WIP: MISC/mcl_engine_workarounds: Fix malformed client ready packet crashing server #278
No reviewers
Labels
No Label
blocker
bug
code quality
confirmed
critical
discussion
high priority
incompatibility
incomplete feature
invalid
low priority
missing feauture
needs testing
packet spam
performance
project
regression
translations
unconfirmed
in review
ready for review
No Milestone
No project
No Assignees
2 Participants
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Mineclonia/Mineclonia#278
Loading…
Reference in New Issue
No description provided.
Delete Branch "fix-malformed-clientready"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
This PR fixes #269
A malformed clientready packet can leave a connecting player indefinietly in a state where they're not fully connected but the player is returned by get_connected_players leading to all kinds of problems.
Solution
This PR sets a meta field in on_joinplayer and overwrites get_connected_players to check for that.
Testing Steps
1.Start a game in mcla master with host game
2. run the crash script on localhost:30000
3. Observe the game crash
4. Start a game on this pr
5. run the crash script on localhost:30000
6. Observe the game not crash
To do
Another way to do this would of course be just @erlehmann's original solution: cache all players in on_joinplayer and just return that table(nothing else needed in theory). I don't know if the references stay good throughout the entire connection though so I thought this way might be smarter.
The method of detection is that the "fake" clients do not cause on_joinplayer to be run in any case.
It seems it doesn't work.
What you fix - only players connected. But they still appear as dummy objects like this:
They take part in all interactions and crash the servers successfully because many places in the code aren't ready for that.
Well thats the least intrusive way i could think of that doesnt crash the game. If you don't want them you can easily compare original mgcp with the cool new one and kick them when theyre not in the latter ^^
Maybe you're right. I'm not sure where else the player object might come from though if not from mgcp or on_joinplayer.
But i suppose it's possible.
Did it actually crash for you though ?
I can't disconnect/cick them and they crashed the server on interactions, last stuff I tried to fix has been logged when they magneted xp orbs
I added some info to the minetest issue but still think we should better consider them in main loops, it looks simpler
Oh yeah i see. I'll try to figure it out.
To be honest, my problem is - I can't run the crashing script and go to sleep, though it could help to locate and fix many places of code. Locally, I can but almost nothing is happening locally, so I think, wow, everything is fixed, run crash.py for real server, it works 5-10 minutes and wow - we've got something new
No I think if they actually cause widespread weirdness we can't let them connect.
Also i'm dumb ... yeah portals would also make it crash possibly cause they search for objects in the area right?
I think it might be good to detect and rewrite the is_player method of the fake player. That should take care of the rest. They aren't a problem bc theyre objects but bc they're players right ?
The only problem, I think, we didn't initialize them because they didn't go through the callback where we used to initialize player stuff. Some oldschool practice says, deal only player names, don't deal player objects, but when you need player meta, or inventory, or texture, entities, effects - it is not enough to process just names. So yes, we have to create player object somehow (which is more likely impossible for Lua) or ignore them in all loops.
mcl_util.is_player in testing branch of mcl5 right now:
I just replace
if dropper:is_player()
toif mcl_util and mcl_util.is_player(dropper)
, etc.Why
mcl_util and
- because we have wrong dependencies currently which is another issueWell i meant make it just return false. If we detect one of these. Then we can probably even let them stay because i suppose if theyre not seen as players by mcl they won't be a problem.
I haven't figured out a great method to detect them though other than running mgcp in a globalstep and checking that.
Another method i thought about is having a timer start in prejoinplayer and if joinplayer doesnt happen within say 2 seconds we rewrite the is_player function.
Are you sure they can't be kicked though? kick takes a name as arg right ?
yea, have no idea why, tried lot of times, my latest attempt to make it work is a mess but you will see what i tried to do from it
mmmh i wonder .. can we get the object through get_player_by_name ?
mmmh this seems to work for me (p similar to yours ig)
The problem is that media dl might well take longer i suppose
Well, on auth they are NIL:
after 2 seconds of being idle - still
nil
This doesn't work too, predictably
the thing that seems to work is that they do not trigger on_joinplayer.