diff --git a/src/miners/classic/connection.d b/src/miners/classic/connection.d index 5b26ba4..7639ffb 100644 --- a/src/miners/classic/connection.d +++ b/src/miners/classic/connection.d @@ -48,6 +48,9 @@ private: /// Verification recieved from mc.net string verificationKey; + /// Are we still negotiating the extensions. + bool negotiating; + /// Stored data when receiving the level ubyte[] inData; @@ -77,6 +80,7 @@ public: this.username = csi.username; this.verificationKey = csi.verificationKey; + this.negotiating = true; this.packetLength = size_t.max; } @@ -145,7 +149,7 @@ public: ci.username[name.length .. $] = ' '; ci.verificationKey[0 .. key.length] = key[0 .. $]; ci.verificationKey[key.length .. $] = ' '; - ci.pad = 0; + ci.pad = 0x42; sendPacket!(ci)(s); } @@ -220,6 +224,7 @@ protected: ubyte type = si.playerType; setPlayerType(type); + negotiating = false; cl.indentification(ver, name, motd, type); } @@ -440,6 +445,52 @@ protected: cl.playerType(type); } + /** + * 0x10 + */ + void extInfo(ExtInfo *ei_) + { + if (!negotiating) + throw new Exception("ExtInfo packet not expected"); + + string name = removeTrailingSpaces(ei_.name); + int num = ntoh(ei_.numExts); + + l.info("Server: \"%s\" num: %s", name, num); + + ExtInfo ei; + ExtEntry ee; + + string clientName = "Charged Miners"; + ei.packetId = ExtInfo.constId; + ei.name[0 .. clientName.length] = clientName[]; + ei.name[clientName.length .. $] = ' '; + ei.numExts = 1; + + string extName = "EmoteFix"; + ee.packetId = ExtEntry.constId; + ee.name[0 .. extName.length] = extName[]; + ee.name[extName.length .. $] = ' '; + ee.ver = 1; + + sendPacket!(ei)(s); + sendPacket!(ee)(s); + } + + /** + * 0x11 + */ + void extEntry(ExtEntry *ee) + { + if (!negotiating) + throw new Exception("ExtEntry packet not expected"); + + string name = removeTrailingSpaces(ee.name); + int ver = ntoh(ee.ver); + + l.info("Ext: \"%s\" ver: %s", name, ver); + } + void packet(ubyte *pkg) { switch(*pkg) { @@ -492,6 +543,12 @@ protected: case ServerUpdateType.constId: updateType(&packets.updateType); break; + case ExtInfo.constId: + extInfo(&packets.extInfo); + break; + case ExtEntry.constId: + extEntry(&packets.extEntry); + break; default: // Error assert(false); } diff --git a/src/miners/classic/proto.d b/src/miners/classic/proto.d index 7602560..e59a0bb 100644 --- a/src/miners/classic/proto.d +++ b/src/miners/classic/proto.d @@ -3,7 +3,7 @@ module miners.classic.proto; -uint clientPacketSizes[16] = [ +uint clientPacketSizes[16+16+2] = [ ClientIdentification.sizeof, // 0x00 0, // 0x01 0, // 0x02 @@ -18,10 +18,17 @@ uint clientPacketSizes[16] = [ 0, // 0x0b 0, // 0x0c ClientMessage.sizeof, // 0x0d + 0, // 0x0e 0, // 0x0f + + 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x17 + 0, 0, 0, 0, 0, 0, 0, 0, // 0x17 - 0x1f + + ExtInfo.sizeof, // 0x20 + ExtEntry.sizeof // 0x21 ]; -uint serverPacketSizes[16] = [ +uint serverPacketSizes[16+16+2] = [ ServerIdentification.sizeof, // 0x00 ServerPing.sizeof, // 0x01 ServerLevelInitialize.sizeof, // 0x02 @@ -38,6 +45,12 @@ uint serverPacketSizes[16] = [ ServerMessage.sizeof, // 0x0d ServerDisconnect.sizeof, // 0x0e ServerUpdateType.sizeof, // 0x0f + + 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x17 + 0, 0, 0, 0, 0, 0, 0, 0, // 0x17 - 0x1f + + ExtInfo.sizeof, // 0x20 + ExtEntry.sizeof // 0x21 ]; @@ -64,6 +77,8 @@ union ServerPacketUnion { ServerMessage message; // 0x0d ServerDisconnect disconnect; // 0x0e ServerUpdateType updateType; // 0x0f + ExtInfo extInfo; // 0x10 + ExtEntry extEntry; // 0x11 ubyte[ServerLevelDataChunk.sizeof] data; } @@ -280,3 +295,21 @@ struct ServerUpdateType ubyte packetId; ubyte type; } + +struct ExtInfo +{ + const constId = 0x20; + + ubyte packetId; + char[64] name; + int numExts; +} + +struct ExtEntry +{ + const constId = 0x21; + + ubyte packetId; + char[64] name; + int ver; +}