-
-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a very basic support for multi-server handling. #42
base: master
Are you sure you want to change the base?
Conversation
* Added a new cli param `bind` ("127.0.0.1:25565" by default) for lazymc global binding * Routing now directs all traffic to status service rather than proxying it if server has stared as it is server dependent * Removed all ban checking from routing as it is server dependent * Status server now chooses config/server based on the handshake * Status server is now responsible for strating to proxy if server is started * BUG: After server has started the server status is not shown somewhy
Thank you very much for taking a shot at this! That is very much appreciated. I do have limited time right now to dive into this, but I'll try to leave a proper review. Some comments may be nit-picky. |
src/action/start.rs
Outdated
|
||
// Start server service | ||
let config = Arc::new(config); | ||
service::server::service(config) | ||
let configs_arc = configs.into_iter().map(Arc::new).collect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think Arc<HashMap<_, Arc<Config>>>
is desirable, as this is a very complex type.
I used Arc<Config>
to make it easily sharable across async contexts with message passing.
I'll have to think about something that would be better here. I'm not sure right now. Maybe we need to create a custom type to manage these configurations for us rather than working with a hashmap directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a new type Router
in src/router.rs
to deal with this, what do you think?
src/service/server.rs
Outdated
|
||
if config.lockout.enabled { | ||
warn!( | ||
for config in configs.iter() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably extract this (the logic for doing something for many configuration files) into a separate function we can invoke for each configuration.
This is now a bit messy (and I admit my code already was).
src/service/server.rs
Outdated
// Load server state | ||
let server = Arc::new(Server::default()); | ||
|
||
pub async fn service(bind_addr: SocketAddr, configs: Vec<Arc<Config>>) -> Result<(), ()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't inspected this in-depth right now. I'll try to do that later when the other changes have been made.
Well done thus far, especially since you're new to Rust! Please see my review comments above. I think that [public]
address = "0.0.0.0:25565"
[server]
route = "example.com"
address = "internal_address"
# ... Remember that Please note that I pushed some commits on your branch. Please make sure to pull again to prevent conflicts: |
This comment was marked as outdated.
This comment was marked as outdated.
* Moved Config under Server * Reverted `[public] address` removal * Removed cli `bind` argument
Pushed initial implementation of the proposal, it involved:
Mostly seems to work, the only problem remaining is some trouble with ping packets, after a server it's started it's MOTD is shown as "Can't connect to server..." and status packets do not get through either, but joining the server works Would also still like to support multiple |
I've made the new implementation work similar to original implementation by moving handshake packet parsing to the |
Closed by mistake |
Fantastic work so far! You've hidden your main outline, but I think that represents a very nice goal.
Yes, this sounds very solid. Such an implementation would be great. It would also be surprisingly compatible with how the project currently works. Eventually the
I don't think it should randomly pick one. I think better would be to always pick the first one. The configurations should then be ordered by: the order in which they're provided to I like the ability to have multiple (possible) bind addresses, and the ability to share them across servers.
👍
If I'm right you've already done this. Great!
Yes! If you're still wanting to do this. The two insights I have is accepting an optional list of names and binds, and keeping the configurations in order. But we can do that later.
Did this also fix the ping/status packets? Please keep working on this if you'd like. I'm not available every day to look at this, but I'll try to properly review, test, tweak and merge eventually. |
Thanks again for the support! FIY: I've hidden the outline as it has been implemented already. (except the multiple server names and public addresses). I'll keep working on enabling multiple server namees and public addresses and deterministic choosing of the config. What do you think about choosing the last server config instead of the first when multiple servers compete for the same server name? |
Based on a static code analysis, this looks great! I still have to actually test this on my machine, but I'll do that later. It may be nicer to create a single router somehow, so we don't have to share Thanks for your work! |
I've been testing this for a bit on my home server, and I have noticed there is some bug, not sure on how exactly to reproduce it, but sometimes it seems it has some trouble with the initial connection. One scenario that has happened more than once:
Will look into reproducing this more |
Weird!
The Minecraft client or server? |
Sorry for taking a bit to respond, it's the minecraft client |
That's super weird! I don't think a server should ever able to cause this, meaning it would be a client bug. |
Will this amazing pull request be accepted? |
I have tried fixing #40 myself as a bit of a challenge to learn Rust. This is my first time touching Rust so the code quality is probably terrible, I am having tons of trouble understanding references, Arc, Mutex and RwLocks, and the borrow checker in general.
However, I have manage to create a very rough proof-of-concept that seems to work somewhat.
What has changed:
--bind
(127.0.0.1:25565
by default) that outlines the global bind for TCPListener--config
now can point to either a single config file (lazymc.toml
by default) or a whole directory including multiple config files[public] address
in server config is no longer the address TCPListener binds to, now it describes theserver_address
part of the handshake pattern, by which a server is selectedHere's an example of how to make it work
Allows users to join either serverA or serverB via the same port depending on how it is described in their settings.
TODO: