Currently when a client connects that is already there,
the old socket is closed, and the code tries to reuse the existing client object by exchanging its socket.
Reusing the same client object and just changing its socket does cause issues though with copies of the client in other threads.
In the situations that I could reproduce, it always disconnected both sockets, the old one and then the new one.
Instead I make a copy of the client object, use the new socket, remove the old object and add the new object to the collection.
(cherry picked from commit 9e6c312c8e)
Otherwise clients might connect to the server before everything is ready for them.
E.g. when restarting the server, the clients will immediately try to reconnect.
Clients might connect before the `PacketHandler` is initialized, which results in some packets not being processed by the server correctly.
Same goes for the commands: Discord might send in commands before all commands were added to the `CommandHandler`.
Without the `ClientJoined` action, clients might even be allowed to connect if they are on the banlist.
(Though without this initialization they or regular clients might be broken in some ways?)
(cherry picked from commit 92e540aaa6)
currently it always outputs `Failed to get log channel \"{Config.CommandChannel}\"` regardless if the error was with the command channel or the log channel.
await Run(); doesn't need to be in a try-catch block, because it has a try-catch block itself in it.
Otherwise port scans, banned players or clients failing to initialize correctly,
will cause the server to send unnecessary packets to all connected clients.
They currently are informed about a disconnect for a client that hasn't even connected correctly.
(cherry picked from commit 4b04a3d5be)
Behavior: No DM'ing commands under any circumstance
if Config.LogChannel == null, commands can be in any non-private channel
if Config.LogChannel != null, commands can only be in the log channel