Sanae6 / SmoOnlineServer

Official server for Super Mario Odyssey: Online
https://discord.gg/jYCueK2BqD
103 stars 24 forks source link

Feature Request: Be able to restrict access to server if not connecting with a brand new save file. #43

Open Clutz450 opened 1 year ago

Clutz450 commented 1 year ago

The short summary is I would like it if I could have an option in the settings to make it so that only people with 0 power moon will be able to connect.

Long story is I am planning on doing a stream on Twitch where I try to collect all 999 power moons and would like it if random people could join me and help me in my quest. What I don't want is for people to connect to my server with a save file that is later in the game than I am currently at and have them sync power moon to me in areas that i shouldn't have access to yet. My idea for this is to have the server check how many power moons a person has and if it's a number greater than 0 then it will refuse the connection. This way when random people join me, once they connect with their brand new save file, all power moons will be synced to them. The only thing a new person has to do to quickly catch up to where I am at is to enter each kingdom and throw cappy on the odyssey.

I know nothing about coding or how any of this works so this is just an idea on how I think it could work. If anyone else has any better ideas or the knowhow to make it happen, I would really appreciate it. Thanks.

Istador commented 1 year ago

What I don't want is for people to connect to my server with a save file that is later in the game than I am currently at and have them sync power moon to me in areas that i shouldn't have access to yet.

Is that how it works? Have you tested this? AFAIK the client software only sends moons to the server that were collected while being connected to the server, so someone that has a 100% save already should not be triggering moon collect packets for you. So when you host your own fresh server, it should have and keep an empty moon list, even when someone with a 100% file connects. (I'm not sure about this and haven't tested this.)

Though someone with a non-100% savefile could collect moons in later kingdoms while connected to your server. Preventing this is likely very difficult, because the client or server would need to know which moons are collectible under which conditions and you would need to tell the server somehow to limit it on your specific players progress and not that of other players.


Limiting connections based on existing moon count seems impossible, without changing the SMOO communication protocol between client and server, because the server afaik doesn't get to know the total moon count of the players, but only what they collect on it (and what the server sends to them from others).

Even if it would keep track of it, you'd also need to persist it somehow, otherwise a server crash/restart would prevent even you from rejoining the server again once you collected a single moon.

Another approach could be to require all clients to start in Cap Kingdom with a brand new save (starting with the first scenario). This is something that is already detected by the server and kept in the metadata for each player, to prevent sending them moons before reaching Cascade Kingdom. But the metadata doesn't survive server restarts currently, so you shouldn't make block decisions based on it (same reason as in the last paragraph).


Maybe a kingdom block feature could be feasible for your use case. Before your stream you block all kingdoms but Cap Kingdom. When someone sends a game packet for another kingdom (tries to load into it), they get kicked of the server (with a game crash). Before YOU enter the next kingdom, you can manually execute a server command to unlock the next kingdom for everyone.

Clutz450 commented 1 year ago

Maybe a kingdom block feature could be feasible for your use case. Before your stream you block all kingdoms but Cap Kingdom. When someone sends a game packet for another kingdom (tries to load into it), they get kicked of the server (with a game crash). Before YOU enter the next kingdom, you can manually execute a server command to unlock the next kingdom for everyone.

Sorry for the very late reply as I kinda fell out of SMOO but am looking to get back in and revisit my stream idea. That Kingdom Block feature sounds like something I could use. Is this something that I can already do or were you just suggesting it as a feature request that would satisfy my needs? Thank you.

Clutz450 commented 1 year ago

Sorry, I fat fingered the close issue button on my phone. Lol.

Istador commented 1 year ago

Is this something that I can already do or were you just suggesting it as a feature request that would satisfy my needs? Thank you.

That was a suggestion for a simpler/smaller feature request that would be easier to implement:

If we want to add this feature to the server permanently and not just for a one-time event, I'd suggest changing/extending the ban command for this:

Crazalu commented 1 year ago

Would stage name be its alias, and how would it work if someone connected to the server with the reconnect button(if the reconnect button miraculously)were in a subarea of a kingdom? (ex. CapWorldHomeStage is banned, but they connect inside CapWorldTowerStage)

Istador commented 1 year ago

The saved stage name should be the exact name of the stage and not an alias. But the server commands should support both forms like the send and sendall commands.

Blocking only based on the overworld stages should be enough to block most possible abuses. Because loading into the game, traveling with the odyssey or using a picture teleport will all load you into an overworld stage. https://github.com/Sanae6/SmoOnlineServer/blob/d8c59f7a237cae65cd9062b08540b775d7df8d30/Shared/Stages.cs#L33-L50

But as you mentioned only-connecting when already in a sub-area of a blocked kingdom could be a way around it (but they can't get out without disconnecting first). Though we could also block/unblock all sub-areas when blocking a kingdom based on an alias. The data which stage is part of which kingdom is already there (in my PR): https://github.com/Sanae6/SmoOnlineServer/blob/d8c59f7a237cae65cd9062b08540b775d7df8d30/Shared/Stages.cs#L75-L249

Istador commented 1 year ago

I've implemented a solution for this in PR #48.

A new release w/ docker image and binary files based on master including all my other unmerged changes: https://github.com/Istador/SmoOnlineServer/releases/tag/1.0.4-rcl.6

Clutz450 commented 1 year ago

I've implemented a solution for this in PR #48.

A new release w/ docker image and binary files based on master including all my other unmerged changes: https://github.com/Istador/SmoOnlineServer/releases/tag/1.0.4-rcl.6

This is so amazing of you to do. Thank you. I'll try and test it out here soon. What do you think the likelihood is that your changes will be put into the main server?

Istador commented 1 year ago

What do you think the likelihood is that your changes will be put into the main server?

IDK.

Except for the ban stage command I think my changes and bugfixes are reasonable enough on their own to include in this repo. Regarding the bug that I fix with 11c291c105cc108c4bf12b15a2914e6afdd2d857 I briefly messaged with Sanae on Discord about it.

The ban stage command is a bit of a special use case, which I can understand not wanting to merge (which is why I added the commit bf0bfae10b34852eaa13d8bf064c161c9e6320d4 at last, to easily not merge it).

I'm not even sure if there ever will be an official 1.0.4 release that will contain this, even if merged. Version 1.0.3 was released more than a half year ago despite 5 of my pull requests being merged since then.

The sporadic development focus currently seems to be on SMOO 2.0, which will likely make this repository obsolete. (But because from my perspective there's no time plan for it and it's not an open development, I find it still important to maintain the current public SMOO software stack.)

Istador commented 10 months ago

It was merged and is part of the new 1.0.4 release from today.

ktmitton commented 6 months ago

I've been thinking about this for a couple weeks, and wanted to throw out an idea. It's not complete yet, but I think it's far enough along to give the general idea if you check out my fork at https://github.com/ktmitton/SmoOnlineServer

In this, I set up the TCP server to work within the asp.net lifecycle as a HostedService, and I split the work into three different projects:

Using this approach, I think it gives us the following benefits:

  1. It puts a separation between the code that sends/receives packets and the code that decides what to do with them, which allows us to implement newer versions and stay backwards compatible
  2. It allows us to create different update strategies for players, so for instance if somebody has a lot of latency, we can opt to send them updates on further away players at longer intervals, and save them some bandwidth
  3. It allows people to extend what we've done by creating new game modes by, bare-minimum, implementing their own kind of ILobby

Number 3 in particular addresses this issue because we could implement an ILobby, or update the current Coop lobby, so it could auto-track the "leader", unlocking zones as the leader unlocks it. So auto-manage the banned stages list, but without needed to adjust how the basic connection code works, dependency injection handles the magic of getting the received data where it needs to go.

What do you think?

ktmitton commented 6 months ago

Oh, running in the asp.net lifecycle, it can also make docker images smaller because we should be able to just leverage the basic microsoft alpine images, and they'll automatically start up the webserver.