* rename command: `ban ...` => `ban player ...`
To enable adding other subcommands starting with `ban`.
Moving ban list and crash related code into its own class to tidy the Program class up.
Change Id values of the crash cmds, to fit into the 16 byte max length imposed by ChangeStagePacket.IdSize.
* add command: `ban ip <ipv4-address>`
To add an IPv4 address to the ban list.
* add command: `ban profile <profile-id>`
To add a profile ID to the ban list.
* add command: `unban ip <ipv4-address>`
To remove a banned IPv4 address from the ban list.
* add command: `unban profile <profile-id>`
To remove a banned profile ID from the ban list.
* add commands: `ban enable` and `ban disable`
To set the value of `BanList.Enabled` to `true` or `false` without editing the `settings.json` file.
* add command: `ban list`
To show the current ban list settings.
* fix: actually working ban functionality
Changes:
- ignore new sockets from banned IP addresses way earlier.
- ignore all packets by banned profiles.
Intentionally keeping the connection open instead of d/c banned clients.
This is to prevent endless server logs due to automatically reconnecting clients.
Before:
Reconnecting clients aren't entering `ClientJoined` and therefore the d/c is only working on first connections.
Effectively banned clients got a d/c and then automatically reconnected again without getting a d/c again.
Therefore allowing them to play normally.
* use SortedSet instead of List for settings
To enforce unique entries and maintain a stable order inside of the `settings.json`.
* add commands: `ban stage <stage-name>` and `unban stage <stage-name>`
To kick players from the server when they enter a banned stage.
<stage-name> can also be a kingdom alias, which bans/unbans all stages in that kingdom.
Because we aren't banning the player, d/c them would be no good, because of the client auto reconnect.
Instead send them the crash and ignore all packets by them until they d/c on their own.
This is an alternative solution for issue #43.
* Update Server.cs
---------
Co-authored-by: Sanae <32604996+Sanae6@users.noreply.github.com>
- Send empty `TagPacket` and `CapturePacket` on new connections, to reset old data back that other players might still have in their puppet from an
earlier connection.
- Cache and send `CostumePacket`, `CapturePacket`, `TagPacket`, `GamePacket` and `PlayerPacket` to (re-)connecting players.
- Clear Metadata cache for existing clients that connect fresh (after a game restart).
Changes:
- Moved alias mapping from Constants.cs to Stages.cs.
- Added `odyssey` as an alias.
- Hardcoded all known stage values.
- Verfify that the stage input is either a alias or a known stage name.
- Added an option to append `!` to a stage name to force sending even if the stage is not known (e.g. for custom kingdoms).
Before it only checked that it was a known alias or that it contained `Stage` or `Zone`.
That made it impossible to send players to`MoonWorldShopRoom` and `MoonWorldSphinxRoom`.
And a typo would have resulted in a game crash.
The breaks make the function return true, which causes the shine packets to be broadcasted to all connected clients.
Returning false will prevent the broadcast of the current shine packet.
Note: If shines are enabled, the clients will receive every shine twice.
Once from the `SyncShineBag();` and then a second time from the default broadcast caused by the remaining breaks.
We should probably replace every `break;` with `return false;` here?
Make and use a copy of the RemoteEndPoint at the start of the HandleSocket method.
Because in some cases when the socket is disposed, the RemoteEndPoint inside of it is cleared and isn't available for the following disconnect log entries.
Also: port scanners on the internet don't introduce themselves with a name and ID.
(cherry picked from commit 2f4cd0509a)
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