diff --git a/MCServer/settings.ini b/MCServer/settings.ini index 1b4155c14..3c24525bf 100644 --- a/MCServer/settings.ini +++ b/MCServer/settings.ini @@ -6,6 +6,7 @@ Port=25565 MaxPlayers=100 Description=MCServer - in C++ +PrimaryServerVersion=39 [Worlds] DefaultWorld=world diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 3dbf4d768..3c1db8d54 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 10/28/12 15:51:24. +** Generated automatically by tolua++-1.0.92 on 10/31/12 20:34:13. */ #ifndef __cplusplus @@ -15211,6 +15211,36 @@ static int tolua_collect_Lua__cPickup (lua_State* tolua_S) } #endif +/* get function: m_PrimaryServerVersion of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_get_cRoot_m_PrimaryServerVersion +static int tolua_get_cRoot_m_PrimaryServerVersion(lua_State* tolua_S) +{ + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PrimaryServerVersion'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PrimaryServerVersion); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PrimaryServerVersion of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_set_cRoot_m_PrimaryServerVersion +static int tolua_set_cRoot_m_PrimaryServerVersion(lua_State* tolua_S) +{ + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PrimaryServerVersion'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PrimaryServerVersion = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + /* method: Get of class cRoot */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_Get00 static int tolua_AllToLua_cRoot_Get00(lua_State* tolua_S) @@ -23156,6 +23186,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cRoot","cRoot","",NULL); tolua_beginmodule(tolua_S,"cRoot"); + tolua_variable(tolua_S,"m_PrimaryServerVersion",tolua_get_cRoot_m_PrimaryServerVersion,tolua_set_cRoot_m_PrimaryServerVersion); tolua_function(tolua_S,"Get",tolua_AllToLua_cRoot_Get00); tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00); tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00); diff --git a/source/Bindings.h b/source/Bindings.h index c681cbcc0..16b1b02a6 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 10/28/12 15:51:25. +** Generated automatically by tolua++-1.0.92 on 10/31/12 20:34:14. */ /* Exported function */ diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp index a607380c8..fcd61d269 100644 --- a/source/Protocol/ProtocolRecognizer.cpp +++ b/source/Protocol/ProtocolRecognizer.cpp @@ -562,7 +562,7 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void) { return false; } - if (ch == 39) + if (ch == PROTO_VERSION_1_3_2) { m_Protocol = new cProtocol132(m_Client); return true; @@ -578,14 +578,58 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void) void cProtocolRecognizer::HandleServerPing(void) { AString Reply; - Printf(Reply, "%s%s%i%s%i", - cRoot::Get()->GetDefaultWorld()->GetDescription().c_str(), - cChatColor::Delimiter.c_str(), - cRoot::Get()->GetDefaultWorld()->GetNumPlayers(), - cChatColor::Delimiter.c_str(), - cRoot::Get()->GetDefaultWorld()->GetMaxPlayers() - ); - m_Client->Kick(Reply.c_str()); + switch (cRoot::Get()->m_PrimaryServerVersion) + { + case PROTO_VERSION_1_2_5: + case PROTO_VERSION_1_3_2: + { + // http://wiki.vg/wiki/index.php?title=Protocol&oldid=3099#Server_List_Ping_.280xFE.29 + Printf(Reply, "%s%s%i%s%i", + cRoot::Get()->GetDefaultWorld()->GetDescription().c_str(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetDefaultWorld()->GetNumPlayers(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetDefaultWorld()->GetMaxPlayers() + ); + break; + } + + case PROTO_VERSION_1_4_2: + { + // The server list ping now has 1 more byte of "magic". Mojang just loves to complicate stuff. + // http://wiki.vg/wiki/index.php?title=Protocol&oldid=3101#Server_List_Ping_.280xFE.29 + // _X 2012_10_31: I know that this needn't eat the byte, since it still may be in transit. + // Who cares? We're disconnecting anyway. + if (m_Buffer.CanReadBytes(1)) + { + byte val; + m_Buffer.ReadByte(val); + ASSERT(val == 0x01); + } + + // http://wiki.vg/wiki/index.php?title=Server_List_Ping&oldid=3100 + AString NumPlayers; + Printf(NumPlayers, "%d", cRoot::Get()->GetDefaultWorld()->GetNumPlayers()); + AString MaxPlayers; + Printf(MaxPlayers, "%d", cRoot::Get()->GetDefaultWorld()->GetMaxPlayers()); + + // Cannot use Printf() because of in-string NUL bytes. + Reply = cChatColor::Delimiter; + Reply.append("1"); + Reply.push_back(0); + Reply.append("47"); + Reply.push_back(0); + Reply.append("1.4.2"); + Reply.push_back(0); + Reply.append(cRoot::Get()->GetDefaultWorld()->GetDescription()); + Reply.push_back(0); + Reply.append(NumPlayers); + Reply.push_back(0); + Reply.append(MaxPlayers); + break; + } + } // switch (m_PrimaryServerVersion) + m_Client->Kick(Reply); } diff --git a/source/Protocol/ProtocolRecognizer.h b/source/Protocol/ProtocolRecognizer.h index 21dd8f84b..451f7fa4d 100644 --- a/source/Protocol/ProtocolRecognizer.h +++ b/source/Protocol/ProtocolRecognizer.h @@ -31,6 +31,13 @@ class cProtocolRecognizer : typedef cProtocol super; public: + enum + { + PROTO_VERSION_1_2_5 = 29, + PROTO_VERSION_1_3_2 = 39, + PROTO_VERSION_1_4_2 = 47, + } ; + cProtocolRecognizer(cClientHandle * a_Client); virtual ~cProtocolRecognizer(); diff --git a/source/Root.cpp b/source/Root.cpp index 750478c10..d8b929102 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -14,6 +14,7 @@ #include "Blocks/BlockHandler.h" #include "Items/ItemHandler.h" #include "Chunk.h" +#include "Protocol/ProtocolRecognizer.h" // for protocol version constants #ifdef USE_SQUIRREL #include "squirrelbindings/SquirrelFunctions.h" @@ -98,8 +99,10 @@ void cRoot::Start() LOG("Starting server..."); cIniFile IniFile("settings.ini"); IniFile.ReadFile(); + m_PrimaryServerVersion = IniFile.GetValueSetI("Server", "PrimaryServerVersion", cProtocolRecognizer::PROTO_VERSION_1_4_2); + int Port = IniFile.GetValueSetI("Server", "Port", 25565 ); - if(!m_Server->InitServer( Port )) + if (!m_Server->InitServer(Port)) { LOG("Failed to start server, shutting down."); return; diff --git a/source/Root.h b/source/Root.h index 5a2238332..3c7dfc19b 100644 --- a/source/Root.h +++ b/source/Root.h @@ -30,6 +30,9 @@ typedef cItemCallback cWorldListCallback; class cRoot //tolua_export { //tolua_export public: + /// The version of the protocol that is primary for the server (reported in the server list). All versions are still supported. + int m_PrimaryServerVersion; // tolua_export + static cRoot* Get() { return s_Root; } //tolua_export cRoot(void);