SpigotMC / BungeeCord

BungeeCord, the 6th in a generation of server portal suites. Efficiently proxies and maintains connections and transport between multiple Minecraft servers.
https://www.spigotmc.org/go/bungeecord
Other
1.57k stars 1.11k forks source link

Hardcore mode desync after switching servers #2361

Open Fejm opened 6 years ago

Fejm commented 6 years ago

After switching from normal server to hardcore server client don't know about new "mode".

Hardcore flag is set in JoinGame but Bungee cancels this packet and sends Respawn packet instead.

While this is done to make things work it can be changed to support hardcore/normal mode switching.

example of working handle(Login login) method: https://gist.github.com/Fejm/d3dc0cd6892860ff3391f1c5be980e8a

As you can see this allows you to remove scoreboard / bossbar handling as client will drop current data. Client also sends ClientSettings packet after that, so handling of this can be removed too.

Tested under 1.12.2 client.

I was wondering about removing entity rewrite but it seems to not working..

Fejm commented 6 years ago

Correction: works after removing entity rewrite completely (not included in example)

md-5 commented 6 years ago

What about 1.8, 1.9, 1.10, 1.11 etc?

It seems like a bug that the client accepts this, and I would not be surprised to learn that it doesn't work on all versions, or causes obscure bugs you haven't found yet.

Fejm commented 6 years ago

My fork only supports 1.12.X so i didn't test other versions.

I got this after using MCP and looking into client code, JoinGame works like Respawn packet but it also creates new PlayerControllerMP();

No bugs so far, need to make new branch to test other versions.

md-5 commented 6 years ago

Based on your comments, I've come up with a patch like this: https://gist.github.com/8f9716bbb1af3a9744d6c2423099f3b7

But it really needs much more testing, especially across other versions.

A pull request in future is more appropriate than an issue if you are proposing patches yourself.

md-5 commented 6 years ago

How does the mentioned branch work for you? What about older versions?

Fejm commented 6 years ago

Switching works on 1.8 (testing now) but i think in hardcore mode it causes bug with disconnection after dead (GUI as disconnected but you can hear entities) also hardcore flag is not being updated.

md-5 commented 6 years ago

It does a live replace of some objects that really should only be initialised once. I would be quite surprised if you didn’t find similar issues on 1.12 also

Fejm commented 6 years ago

I can say that 1.8 seems to be broken, no scoreboard cleaning (at all) so.. Nice to get this working on 1.12 but for global usage here it's broken.

Fejm commented 6 years ago

After removing all scoreboard methods in DownstreamBridge Scoreboard works so..

If not using hardcore it still can work. This can be changed in JoinGame packet. Entities ID's also working.

Fejm commented 6 years ago

Tested in 1.8.9, 1.9.4, 1.10.2 and 1.12.2. I have no time to check 1.11.2 but i think it will work :)

only hardcore flag is not working on 1.8 and 1.9 (not sure above).

https://github.com/Fejm/BungeeCord/commit/3c6d1bd864c2426269f83c38527da1cff02392e1

This is my fork which i used to test this. It's not perfect, but it works. If someone can test this on production server then we can be 100% sure :)

md-5 commented 6 years ago

You cant remove those scoreboard methods, breaks the scoreboard api

Fejm commented 6 years ago

Ach.. I never was not using bungee scoreboard API so i forgot about this. I did my best to quickly find answers here.

Fork proofs that this work, lets not talk about other issues :D

Fejm commented 6 years ago

More info: Everything looks working, scoreboards, bossbars, entityIDs etc. When client recieves JoinGame packet: 1) Creates new PlayerControllerMP object and new WorldClient object 2) Sets new difficulty 3) Calls loadWorld() method and loads WorldClient (created in first step) 4) Sets dimmension id and sets player entity id 5) Sets reduced debug Info and gamemode 6) Sends ClientSetting packet to server 7) Sends MC|Brand payload

When client recieves Respawn Packet: 1) Checks dimmension id, and if not match: a) Creates new WorldClient object b) copies reference of current Scoreboard to worldclient c) Calls loadWorld() method and loads WorldClient (created in first step) d) Sets dimmension id 2) Calls setDimensionAndSpawnPlayer() method (more info bellow) 3) Sets gamemode

#setDimensionAndSpawnPlayer First it's clears all entities known to client then creates new EntityPlayerSP() object, which one holds reference to current connection etc. It's reusing current RecipeBook and Stats. It also copies some references from old object.

There is no setDimensionAndSpawnPlayer method in JoinGame handler, but when it calls loadWorld() new EntityPlayerSP will be created with new RecipeBook and Stats if EntityPlayerSP not exists otherwise it will reuse object.

MCP comparison between versions All MC version from 1.8 to 1.12.2 are handling JoinGame and Respawn the same.

About 1.8.x hardcore bug: Even if connected without bungee (direct to spigot server) "leave server" button is not working - GUI screen in server list but still connected to server. Server is ignoring PERFORM_RESPAWN status and not kicking player.

I got hardcore flags working too, i dont know why they was not working before, maybe it was misconfiguration.

Mystiflow commented 6 years ago

Might it be worthwhile to only send destroy scoreboard packets in !1.12.2 or other affected versions?

Fejm commented 6 years ago

Works in all versions do far

Mystiflow commented 6 years ago

I mean you mentioned that 1.8 does no scoreboard cleaning but 1.12 does, so I'm suggesting we can only send remove scoreboard packets on 1.12

Fejm commented 6 years ago

I fixed it :) it works under 1.8 now

md-5 commented 6 years ago

You haven’t done a particularly good job of communicating what changes though. I suggest you work off the alt-respawn branch and open a PR against that with the requisite changes to improve compatibility

XakepSDK commented 6 years ago

I actually support alt-respawn branch. @Fejm thank you for research, this fixes so many bugs on my server!

md-5 commented 6 years ago

What bugs are you suggesting it fixes aside from hardcore mode?

XakepSDK commented 6 years ago

There was a bug with arrows(they fall down, but this was visual bug for shooter) Also, there was another issue with nametags. These bugs were introduced by me because i send some packets manually, but with alt-respawn branch they are gone!

XakepSDK commented 6 years ago

Also, i sent this issue to ProtocolSupport author, he want to test alt-respawn branch. Wait for more reviews!

Fejm commented 6 years ago

Even if this fix your ID problems it can cause client instability. We need someone who can actually put this on live server and test this with several players. As i have dying server now i can't do this.

Fejm commented 6 years ago

Okay, it's running on production server for about 5 hours. No bug/flaws so far. 300-400 ppl online.

Shevchik commented 6 years ago

Works at least down to 1.4.7

XakepSDK commented 6 years ago

News?

Fejm commented 6 years ago

It's works fine. Just get my fork and build it.

md-5 commented 6 years ago

You said earlier scoreboards were broken

Fejm commented 6 years ago

@md-5 scoreboard API was not working and kicking players, so i just removed it (I don't need it). After 30d of using it on 1.12.x network i can say: it's fully working.

md-5 commented 6 years ago

“I removed it, therefore its fully working” Thats not quite how things work

Shevchik commented 6 years ago

Some modded client crash when using alt respawn branch.

XakepSDK commented 6 years ago

Bump again @Fejm

Fejm commented 6 years ago

I was using this method about 2 months, it's works but i reverted it because no one else is using it - for reasons? Also as @Shevchik pointed: it may crash modded clients. For example LabyMod has some issues with GENERIC_MAX_HEALTH attribute after switching servers.

MrIvanPlays commented 4 years ago

Yes, sorry for bumping this. In IvanCord I have completely removed entity rewriting and the scoreboard api and I get much faster server switch speeds. The scoreboard api and the scoreboard packets aren't a necessary thing to have in bungee, as far as I know the only plugin using the scoreboard is BungeeTabListPlus and it is to modify the tablist. I even don't know why the entity rewriting exists in first place, it isn't necessary at all.