Waterfall icon indicating copy to clipboard operation
Waterfall copied to clipboard

Modern forge support

Open electronicboy opened this issue 5 years ago • 77 comments

Bungee, and by extension, Waterfall; does not support IP forwarding for forge clients, this needs to be investigated, especially as upstream has expressed 0 interest in maintaining forge support

electronicboy avatar Jan 26 '20 01:01 electronicboy

This is highly wanted 😄 Anything you need to get the support to happen or is it just a waiting game ?

Bennyboy1695 avatar Mar 09 '20 21:03 Bennyboy1695

I did quite a bit more digging into this and it's actually might be a bit more simple than I think people are realizing.

The error experienced in #449 is a Disconnect packet caused by the server lacking IP Forwarding support. A 1.14+ modded client can connect to a modded server in Vanilla mode just fine it's when you start involving mods you have trouble.

17:06:42 [INFO] Packet ID: 27
17:06:42 [INFO] Text?: {"translate":"disconnect.genericReason","with":["Internal Exception: io.netty.handler.codec.DecoderException: The received encoded string buffer length is longer than maximum allowed (1105 > 1020)"]}

If you make some changes to Bungee and add the new FML Server List Ping data outlined here here as well as bypass Netty attribute additions for the FML markers and protocol version here the server will start talking.

00:27:47 [INFO] Decoder Packet ID: 4
00:27:47 [INFO] Payload Request CH: fml:loginwrapper

Problem being right now I think due to the lack of all the Netty channel attributes uses throughout the new Forge networking such as this results in the client not responding. I tried adding some of these attributes here in Bungee but they didn't seem to be picked up by the client.

It doesn't seem like Waterfall would have to implement any of the handshake really short of pulling Mod List data to support this newer Forge protocol due to it's reliance on Vanilla LoginPayloadRequest and Response.

PurpleIsEverything avatar Mar 12 '20 07:03 PurpleIsEverything

You don't add those attributes via the proxy, attributes aren't transmitted over the connection, from what I recall, it's basically just a K,V store on the connection, but, that's set here: https://github.com/MinecraftForge/MinecraftForge/blob/1933d05e36245ef7461b29853b4854fa769a807f/src/main/java/net/minecraftforge/fml/network/FMLHandshakeHandler.java#L186

We basically need to ensure that the proxy will handle the handshake process properly, including handling phases in the connection where it's not in play

#449 being the kick message for a string too long makes sense, in forge based setups, you generally need to disable ip_forwarding support or use Sponge in order to support the network changes

electronicboy avatar Mar 12 '20 07:03 electronicboy

In the case of the new FML protocol you won't be worrying about phases or race conditions for the FML Handshake it's all being done over the Vanilla LoginPayloadRequest and Responses they are blocking operations and are forced to happen in order.

Your really only needing to track the vanilla transition between LOGIN and PLAY as these payloads need to ALL complete during LOGIN.

The new FML protocol is outlined here

PurpleIsEverything avatar Mar 12 '20 07:03 PurpleIsEverything

I've yet to get around to looking over the new protocol, still on the mend from my health issues, sloowly getting there, needless to say, stuff like this is on the back burner

The issue is really reimplementing the login stuff, that all has to be handled by the proxy given the nature of how this all works, not really expecting any issues, it just boils down to getting the time/motivation/energy/brain-juice to do it

electronicboy avatar Mar 12 '20 07:03 electronicboy

I fully understand hence why I've be trying to do as much as the leg work as possible and will continue to do so to try and reduce some of the workload.

This issue is a very significant blockade to our innovation and keeping our players a safe and happy with new content is of the utmost priority. Without this we can't provide them the experience they expect.

With everyone moving on we just want to be able to keep up, wish you the best hope to see you find the time, motivation and energy to continue with this until then we will continue to work away at this.

PurpleIsEverything avatar Mar 12 '20 07:03 PurpleIsEverything

I've done quite a bit more digging today and found a few more things.

Currently it seems that PayloadRequest and Response packets are coming in AFTER the Login Success packet has already been sent here unfortunately that means the client has already gone into a Play state.

The server will attempt 20 times to send fml:loginwrapper through PayloadRequest packet to the client unfortunately these never make it out of the proxy to the client as the client has already been forced into a play state then gets stuck joining world. If the client never gets these packets the client will assume a vanilla connection.

FML tokens are still present in the extra data of the handshake it's simply been changed from \0FML\0 to \0FML2\0 so the same detection method can be used.

It also currently ignores all previous forge handshake handling when enabled so no real worries about it incompatible there.

PurpleIsEverything avatar Mar 12 '20 22:03 PurpleIsEverything

Unfortunately after much discussion modern Forge support currently is not possible with the current climate.

There is no packet currently available to reset the client back into a LOGIN state and without that server switching will never be possible.

While initial logins could be done by having Bungee wait for a Login Success or Join Game packet before sending a login success to the client and moving on to Play this will likely cause lots of confusion.

PurpleIsEverything avatar Mar 17 '20 21:03 PurpleIsEverything

sounds like it would just leave us in the exact same state of affairs, but, with some level of "we support 1.14+", unless I'm missing something with the older system, the client was never forced back into login

electronicboy avatar Mar 18 '20 07:03 electronicboy

No it wasn't since the FML handshake happened in Game mode since it was all Plugin Messages.

PurpleIsEverything avatar Mar 18 '20 13:03 PurpleIsEverything

I have the same problem too and it's really annoying

Nothingness-Void avatar May 14 '20 12:05 Nothingness-Void

same here. I wish sponge updated to 1.14.4. hope they fix this soon as its been 8 months since this has been opened

1337-haxxor avatar Aug 04 '20 23:08 1337-haxxor

Screenshot_20200804-095517

I'll include this as a conversation that occurred in the MinecraftForge Discord, make sure to go there and find these messages for the rest of the conversation and context as there is more.

Essentially a reset packet has to be added to Forge that follows this general idea for any support like this work. At this time they are not interested in spending the time to create this however it seems they are willing to entertain a PR.

Hopefully someone like BloodMC who worked on the reset last time or Dualspiral who worked on Forge Bungee support can add this so support can be added proxy side. Otherwise the work proxy side is very simple.

PurpleIsEverything avatar Aug 04 '20 23:08 PurpleIsEverything

I believe that the best route, which I'm pretty sure we talked to lex about, would be to basically have a server switch packet, the only real caveat is making this work in common proxy environments, the /only/ way I could see this working would be to have some way to pass some data to the client to re-forward on join, that way we can send them to the correct server, which ofc, creates its own "we don't want the client to be able to throw arbitrary data at us and do whatever" issues

electronicboy avatar Aug 05 '20 00:08 electronicboy

I noticed here, try

https://github.com/ArclightPowered/lightfall https://github.com/ArclightPowered/lightfall-client

This is what I found when browsing Github recently, the project works in 1.15.x-1.16.x bungee-forge

hanbings avatar Mar 08 '21 10:03 hanbings

Lightfall is a good example attempt but is not a solution as it requires a client side mixin patch to work.

The implementation of that patch is very basic and doesn't clean up any registries so it's bound to cause problems. In that state it can't be added into Forge.

PurpleIsEverything avatar Mar 08 '21 16:03 PurpleIsEverything

@PurpleIsEverything here is how my implementation looks like for now

  1. Server list has a second ping response type to indicate PROXY and mark it with an extra type compatible icon
  2. Upon connection to the proxy, before login plugin messages start a proxy:identify payload is communicated.
  3. Proxy then starts connection to downstream and sends proxy:ready back to the client.
  4. Client connects to the server
  5. Upon switching servers a proxy:reconnect payload is sent from the proxy to the client.
  6. The client gets a random UUID to present for the new connection.
  7. The client disconnects
  8. The client starts connection again
  9. Step 2 reoccurs but the client informs the server of the connection UUID
  10. Proxy now knows what to do and starts from the top

It works. I’m not 100% happy with everything yet but I’m getting closer

Xernium avatar Mar 08 '21 19:03 Xernium

See, personally, am not too sure about the UUID, i guess it works, would just need to be exposed in the API, I was more thinking potentially something which can be signed so that the server doesn't need to deal with storing stuff, but, uuid is more portable 🤷

electronicboy avatar Mar 08 '21 19:03 electronicboy

I’ve tried many things and among long convoluted hacks that try to reset the client state without closing the connection- No. Forge mods can’t be expected to be completely reset if you do that. The only way to be sure is to force a complete disconnect so the client must undergo a full new connection. It’s also the most maintainable way

Xernium avatar Mar 08 '21 19:03 Xernium

a full reconnect is what I was proposing to lex, given that it offers a cleaner state, just there would need to be some form of token passed

electronicboy avatar Mar 08 '21 19:03 electronicboy

or, well, what we where discussion, not too sure who entirely proposed it, that discussion was a little while ago

electronicboy avatar Mar 08 '21 19:03 electronicboy

Whatever implementation is used it's going to require modifications to Forge on the client to handle the reset.

A proper PR into Forge likely involves a more complete reset hook and event to make sure mods are aware of the transition.

PurpleIsEverything avatar Mar 08 '21 19:03 PurpleIsEverything

it's a balance between, do we make mods responsible for it and hope they catch up, or, just have a more blanket system for it which generally works as expected across the entire board

electronicboy avatar Mar 08 '21 19:03 electronicboy

There still should be a transition hook or event to allow for less hacky mod support while working with a blanket system.

With 1.16 still quite early in the dev cycle if the implementation is simple enough it's probably not a huge ask.

PurpleIsEverything avatar Mar 08 '21 19:03 PurpleIsEverything

@PurpleIsEverything Right. I have some family matters to take care off of. If I have the time I’ll get something out to you to test.

Xernium avatar Mar 08 '21 19:03 Xernium

I have a problem with this discussion.

If we can not only detect that the client is FML, but that it is in fact FML protocol 2 during the handshake, why can't we just follow forge's protocol and forward the payloads beyond that point as is expected? All this reconnecting business seems completely unnecessary to me.

ME1312 avatar Jun 23 '21 03:06 ME1312

handshaking is done during the LOGIN protocol, and handshakes are initiated by the server itself, not the client, so we'd have no way of knowing what mods are installed and if they're even an FML client until they join a forge server, which, if the first server which they join is not forge, you're not gonna handshake

and then you've got the data to deal with when actually switching servers, noting that this is all done in login, there is no way to actually do any form of handshake without rejoining the server entirely, in the past this was done in the play phase early on, so you could just jump between servers and have stuff (hopefully) align up, but, that's no longer the case

electronicboy avatar Jun 23 '21 03:06 electronicboy

I see. That is rather unfortunate.

If that's the case, though, then this problem isn't exclusive to networks using ip-forwarding, is it? We seem to be having trouble simply connecting a player to a modded server.

Anyway, I did manage to verify my claim that even if you act like a Vanilla server, you should still be able to read and take note of the FML2 token from the handshake packet. But, yeah, with no way to reset & resend those payloads this isn't exactly useful.

ME1312 avatar Jun 23 '21 03:06 ME1312

Continuing the previous discussion, though, I still don't see why the client should be required to actually disconnect from the proxy.

It seems like all we're missing is a single "plugin message" that, when executed by the client, would: notify all the mods that the player disconnected (despite this not being the case) so that they reset themselves, clean up the forge connection internals (registries & etc.), and restart the LOGIN process from the beginning.

As for where ip-forwarding comes in, It would probably be best at this point if we could move on to using login payloads for that as well, but I digress. You could probably get away with just shoving it in the handshake packet as always.

ME1312 avatar Jun 23 '21 21:06 ME1312

notify all the mods that the player disconnected (despite this not being the case) so that they reset themselves,

The problem, if I understand correctly, is that Forge mods are currently expecting the registries, etc. to remain the same from the time that the player connects to the time that they disconnect. As such, the simplest and most backwards-compatible approach is to always disconnect and reconnect the player when they switch servers. Otherwise, a new event needs to be added to Forge, all mods which deal with registries have to implement support for this event if they want to be compatible with Bungee, and so on.

embeddedt avatar Jun 23 '21 21:06 embeddedt