BungeeCord protocol support
Some kind of protocol support for BungeeCord in node-minecraft-protocol might be interesting.
It sends additional information in the set_protocol packet host field, in the same way as Forge (which instead appends \0FML\0 https://github.com/PrismarineJS/node-minecraft-protocol/issues/114, called this tagHost in https://github.com/PrismarineJS/node-minecraft-protocol/pull/326)
Stumbled across this in Cuberite:
// BungeeCord handling:
// If BC is setup with ip_forward == true, it sends additional data in the login packet's ServerAddress field:
// hostname\00ip-address\00uuid\00profile-properties-as-json
AStringVector Params;
if (cRoot::Get()->GetServer()->ShouldAllowBungeeCord() && SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4))
{
LOGD("Player at %s connected via BungeeCord", Params[1].c_str());
m_ServerAddress = Params[0];
m_Client->SetIPString(Params[1]);
m_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2]));
m_Client->SetProperties(Params[3]);
}
https://github.com/PrismarineJS/node-minecraft-protocol/issues/145 BungeeCord : Fails to parse - closed, not known if still applicable https://github.com/PrismarineJS/node-minecraft-protocol/issues/302 - a potential use case
Again, I'd like to see this as a separate module, outside from NMP. NMP should follow the open/closed principle : it should offer the normal "IDK this thing" support for extensions (effectively behaving as the normal minecraft client), but be extensible enough so having a better support of those things can easily live outside.
The problem with #145 was due to the protocol hack iirc.
Yeah the tagHost client option will allow client plugins to send this BungeeCord proxy information (and perhaps also Lilypad), but some other change may be needed to let server plugins read it. Haven't investigated much but the relevant field is in src/createServer.js:
function onHandshake(packet) {
client.serverHost = packet.serverHost;
Known formats of packet.serverHost field:
- hostname - vanilla
- hostname\00ip-address\00uuid\00profile-properties-as-json - BungeeCord
- hostname\0FML\0 - Forge (open question: what is sent for Forge + BungeeCord?)
- {"h":"localhost","rIp":"127.0.0.1",...} JSON - Lilypad
What kind of mechanism for plugins to handle these fields did you have in mind? My first thought was a callback, but its not clear how multiple plugins each handling this field would interact.
Forge is probably hostname\0FML\0 - Forge\00ip-address\00uuid\00profile-properties-as-json, given the packet should first be sent forge-style by the client, and then bungeecord appends its stuff, before reaching the server.
Anyway, the plugin system for servers is a tiny bit more complicated. If we want the same middleware system discussed in #333 , we'll need some help from the Server. I'm thinking a connect-style API would be good.
(Ignore the pythonic syntax in there, that's me being lazy)
function handleForge(opts) {
return function(client, next) {
var splitHostname = this.serverName.split('\0');
if (splitHostname.length > 2 && splitHostname[1] == "FML" && splitHostname[2] == " - Forge") {
this.serverName = splitHostname[0];
}
return next();
};
}
function handleBungee(opts) { return function(client, next) {
var splitHostname = client.serverName.split('\0');
if (splitHostname.length > 3) {
var realIP = splitHostname[-3];
client.uuid = splitHostname[-2];
client.profile = splitHostname[-1]; // I think that's the name ?
this.serverName = splitHostname[0:-4];
}
return next();
};}
var server = new Server();
server.use(handleBungee(opts));
server.use(handleForge(opts));
It's relatively pretty, and powerful enough for our purposes I think. Obviously, order is important, but there's no way to get around this fact.
https://www.npmjs.com/package/ware is a ready-to-use middleware system.