From 64c8fcd74af400e566e5182c253d87b701087642 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Wed, 1 Aug 2012 12:25:19 +0200 Subject: [PATCH] Finished mastersrv, now supports all versions Fixed mastersrv packet building --- src/mastersrv/mastersrv.cpp | 15 ++-- src/mastersrv/mastersrv.h | 31 +------- src/mastersrv/mastersrv5.cpp | 145 ++++++++++++++++++++++++++++++++++- src/mastersrv/mastersrv6.cpp | 120 ++++++++++++++++++++++++++++- src/mastersrv/mastersrv7.cpp | 7 +- 5 files changed, 275 insertions(+), 43 deletions(-) diff --git a/src/mastersrv/mastersrv.cpp b/src/mastersrv/mastersrv.cpp index 78e173c6f..8ed24d5bc 100644 --- a/src/mastersrv/mastersrv.cpp +++ b/src/mastersrv/mastersrv.cpp @@ -70,7 +70,7 @@ void IMastersrvSlave::NetaddrToMastersrv(CMastersrvAddr *pOut, const NETADDR *pI mem_copy(pOut->m_aIp + 12, pIn->ip, 4); } - pOut->m_aPort[0] = (pIn->port>>8)&0xff; + pOut->m_aPort[0] = (pIn->port>>8)&0xff; // big endian pOut->m_aPort[1] = (pIn->port>>0)&0xff; } @@ -195,13 +195,13 @@ int CMastersrv::Init() BindAddr.port = MASTERSERVER_PORT; } - if(!m_NetOp.Open(BindAddr, NETFLAG_ALLOWSTATELESS)) + if(!m_NetOp.Open(BindAddr, NETFLAG_ALLOWSTATELESS|NETFLAG_ALLOWOLDSTYLE)) { dbg_msg("mastersrv", "couldn't start network (op)"); return -1; } BindAddr.port = MASTERSERVER_PORT+1; - if(!m_NetChecker.Open(BindAddr, NETFLAG_ALLOWSTATELESS)) + if(!m_NetChecker.Open(BindAddr, NETFLAG_ALLOWSTATELESS|NETFLAG_ALLOWOLDSTYLE)) { dbg_msg("mastersrv", "couldn't start network (checker)"); return -1; @@ -362,8 +362,6 @@ void CMastersrv::BuildPackets() dbg_assert(BytesWritten >= 0, "build packet initialisation failed"); pPacket->m_Size += BytesWritten; - pSlaveData->m_NumPackets++; - aPreparePacket[pServer->m_Version] = false; } @@ -452,8 +450,7 @@ void CMastersrv::BuildPackets() sizeof(m_aPacketsLegacy[m_NumPacketsLegacy-1].m_Data.m_aServers[PacketIndexLegacy].m_aIp)); // 0.5 has the port in little endian on the network m_aPacketsLegacy[m_NumPacketsLegacy-1].m_Data.m_aServers[PacketIndexLegacy].m_aPort[0] = pCurrent->m_Address.port&0xff; - m_aPacketsLegacy[m_NumPacketsLegacy-1].m_Data.m_aServers[PacketIndexLegacy].m_aPort[1] = (pCurrent->m_Address.port>>8)&0xff; - + m_aPacketsLegacy[m_NumPacketsLegacy-1].m_Data.m_aServers[PacketIndexLegacy].m_aPort[1] = (pCurrent->m_Address.port>>8)&0xff; PacketIndexLegacy++; m_aPacketsLegacy[m_NumPacketsLegacy-1].m_Size = sizeof(SERVERBROWSE_LIST_LEGACY) + sizeof(CMastersrvAddrLegacy)*PacketIndexLegacy; @@ -560,6 +557,7 @@ void CMastersrv::AddCheckserver(const NETADDR *pAddr, const NETADDR *pAltAddr, v { dbg_msg("mastersrv/check", "warning: updated: %s", aAddrStr); m_aCheckServers[i].m_AltAddress = *pAltAddr; + m_aCheckServers[i].m_Version = Version; m_aCheckServers[i].m_pSlaveUserData = pUserData; m_aCheckServers[i].m_TryCount = 0; m_aCheckServers[i].m_TryTime = 0; @@ -577,6 +575,7 @@ void CMastersrv::AddCheckserver(const NETADDR *pAddr, const NETADDR *pAltAddr, v dbg_msg("mastersrv/check", "added: %s", aAddrStr); m_aCheckServers[m_NumCheckServers].m_Address = *pAddr; m_aCheckServers[m_NumCheckServers].m_AltAddress = *pAltAddr; + m_aCheckServers[m_NumCheckServers].m_Version = Version; m_aCheckServers[m_NumCheckServers].m_pSlaveUserData = pUserData; m_aCheckServers[m_NumCheckServers].m_TryCount = 0; m_aCheckServers[m_NumCheckServers].m_TryTime = 0; @@ -589,6 +588,8 @@ void CMastersrv::SendList(const NETADDR *pAddr, void *pUserData, int Version) IMastersrvSlave *pSlave = m_aSlaves[Version].m_pSlave; dbg_assert(pSlave != 0, "attempting to access uninitalised slave"); + dbg_msg("mastersrv", "requested, responding with %d packets", m_aSlaves[Version].m_NumPackets); + for(int i = 0; i < m_aSlaves[Version].m_NumPackets; i++) { CMastersrvSlave::CPacket *pPacket = &m_aSlaves[Version].m_aPackets[i]; diff --git a/src/mastersrv/mastersrv.h b/src/mastersrv/mastersrv.h index 105543da0..8b63cd2ac 100644 --- a/src/mastersrv/mastersrv.h +++ b/src/mastersrv/mastersrv.h @@ -6,15 +6,6 @@ #include #include -/*static const int MASTERSERVER_PORT = 8300; - -enum ServerType -{ - SERVERTYPE_INVALID = -1, - SERVERTYPE_NORMAL, - SERVERTYPE_LEGACY -};*/ - struct CMastersrvAddr { unsigned char m_aIp[16]; @@ -38,26 +29,6 @@ static const unsigned char SERVERBROWSE_FWRESPONSE[] = {255, 255, 255, 255, 'f', static const unsigned char SERVERBROWSE_FWOK[] = {255, 255, 255, 255, 'f', 'w', 'o', 'k'}; static const unsigned char SERVERBROWSE_FWERROR[] = {255, 255, 255, 255, 'f', 'w', 'e', 'r'}; - -/* -// packet headers for the 0.5 branch - -struct CMastersrvAddrLegacy -{ - unsigned char m_aIp[4]; - unsigned char m_aPort[2]; -}; - -static const unsigned char SERVERBROWSE_HEARTBEAT_LEGACY[] = {255, 255, 255, 255, 'b', 'e', 'a', 't'}; - -static const unsigned char SERVERBROWSE_GETLIST_LEGACY[] = {255, 255, 255, 255, 'r', 'e', 'q', 't'}; -static const unsigned char SERVERBROWSE_LIST_LEGACY[] = {255, 255, 255, 255, 'l', 'i', 's', 't'}; - -static const unsigned char SERVERBROWSE_GETCOUNT_LEGACY[] = {255, 255, 255, 255, 'c', 'o', 'u', 'n'}; -static const unsigned char SERVERBROWSE_COUNT_LEGACY[] = {255, 255, 255, 255, 's', 'i', 'z', 'e'}; - -*/ - class CNetChunk; class IMastersrv; @@ -105,7 +76,7 @@ public: // hooks void AddServer(const NETADDR *pAddr, void *pUserData) { m_pOwner->AddServer(pAddr, pUserData, m_Version); } void AddCheckserver(const NETADDR *pAddr, const NETADDR *pAltAddr, void *pUserData) { m_pOwner->AddCheckserver(pAddr, pAltAddr, pUserData, m_Version); } - void SendList(const NETADDR *pAddr, void *pUserData) { m_pOwner->AddServer(pAddr, pUserData, m_Version); } + void SendList(const NETADDR *pAddr, void *pUserData) { m_pOwner->SendList(pAddr, pUserData, m_Version); } // interface for packet building // these functions return number of bytes written diff --git a/src/mastersrv/mastersrv5.cpp b/src/mastersrv/mastersrv5.cpp index 4a8cc7deb..1f556af13 100644 --- a/src/mastersrv/mastersrv5.cpp +++ b/src/mastersrv/mastersrv5.cpp @@ -3,8 +3,151 @@ #include "mastersrv.h" -IMastersrvSlave *CreateSlave_0_5(IMastersrv *pOwner) +static const unsigned char SERVERBROWSE_HEARTBEAT_LEGACY[] = {255, 255, 255, 255, 'b', 'e', 'a', 't'}; + +static const unsigned char SERVERBROWSE_GETLIST_LEGACY[] = {255, 255, 255, 255, 'r', 'e', 'q', 't'}; +static const unsigned char SERVERBROWSE_LIST_LEGACY[] = {255, 255, 255, 255, 'l', 'i', 's', 't'}; + +static const unsigned char SERVERBROWSE_GETCOUNT_LEGACY[] = {255, 255, 255, 255, 'c', 'o', 'u', 'n'}; +static const unsigned char SERVERBROWSE_COUNT_LEGACY[] = {255, 255, 255, 255, 's', 'i', 'z', 'e'}; + +class CMastersrvSlave_0_5 : public IMastersrvSlaveAdv { +public: + CMastersrvSlave_0_5(IMastersrv *pOwner); + virtual ~CMastersrvSlave_0_5() {} + + virtual int BuildPacketStart(void *pData, int MaxLength); + virtual int BuildPacketAdd(void *pData, int MaxLength, const NETADDR *pAddr, void *pUserData); + virtual int ProcessMessage(int Socket, const CNetChunk *pPacket, TOKEN PacketToken, int PacketVersion); + + virtual void SendPacket(int PacketType, const NETADDR *pAddr, void *pUserData); + + struct CCountPacketData + { + unsigned char m_Header[sizeof(SERVERBROWSE_COUNT_LEGACY)]; + unsigned char m_High; + unsigned char m_Low; + } m_CountData; + + struct CMastersrvAddrLegacy + { + unsigned char m_aIp[4]; + unsigned char m_aPort[2]; + }; + + static void NetaddrToMastersrv(CMastersrvAddrLegacy *pOut, const NETADDR *pIn); +}; + +CMastersrvSlave_0_5::CMastersrvSlave_0_5(IMastersrv *pOwner) + : IMastersrvSlaveAdv(pOwner, IMastersrv::MASTERSRV_0_5) +{ + mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT_LEGACY, sizeof(m_CountData.m_Header)); + + for(int i = 0; i < NUM_PACKETS; i++) + { + m_aPackets[i].m_ClientID = -1; + m_aPackets[i].m_Flags = NETSENDFLAG_CONNLESS|NETSENDFLAG_STATELESS; + } + + m_aPackets[PACKET_COUNT].m_DataSize = sizeof(m_CountData); + m_aPackets[PACKET_COUNT].m_pData = &m_CountData; + + m_aPackets[PACKET_CHECK].m_DataSize = sizeof(SERVERBROWSE_FWCHECK); + m_aPackets[PACKET_CHECK].m_pData = SERVERBROWSE_FWCHECK; + + m_aPackets[PACKET_OK].m_DataSize = sizeof(SERVERBROWSE_FWOK); + m_aPackets[PACKET_OK].m_pData = SERVERBROWSE_FWOK; + + m_aPackets[PACKET_ERROR].m_DataSize = sizeof(SERVERBROWSE_FWERROR); + m_aPackets[PACKET_ERROR].m_pData = SERVERBROWSE_FWERROR; +} + +int CMastersrvSlave_0_5::BuildPacketStart(void *pData, int MaxLength) +{ + if(MaxLength < sizeof(SERVERBROWSE_LIST_LEGACY)) + return -1; + mem_copy(pData, SERVERBROWSE_LIST_LEGACY, sizeof(SERVERBROWSE_LIST_LEGACY)); + return sizeof(SERVERBROWSE_LIST_LEGACY); +} + +int CMastersrvSlave_0_5::BuildPacketAdd(void *pData, int MaxLength, const NETADDR *pAddr, void *pUserData) +{ + if(MaxLength < sizeof(CMastersrvAddrLegacy)) + return -1; + NetaddrToMastersrv((CMastersrvAddrLegacy *)pData, pAddr); + return sizeof(CMastersrvAddrLegacy); +} + +int CMastersrvSlave_0_5::ProcessMessage(int Socket, const CNetChunk *pPacket, TOKEN PacketToken, int PacketVersion) +{ + if(PacketVersion != NET_PACKETVERSION_LEGACY || !(pPacket->m_Flags&NETSENDFLAG_CONNLESS)) + return 0; + + if(Socket == IMastersrv::SOCKET_OP) + { + if(pPacket->m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT_LEGACY)+2 && + mem_comp(pPacket->m_pData, SERVERBROWSE_HEARTBEAT_LEGACY, sizeof(SERVERBROWSE_HEARTBEAT_LEGACY)) == 0) + { + NETADDR Alt; + unsigned char *d = (unsigned char *)pPacket->m_pData; + Alt = pPacket->m_Address; + Alt.port = (d[sizeof(SERVERBROWSE_HEARTBEAT_LEGACY)]<<8) + | d[sizeof(SERVERBROWSE_HEARTBEAT_LEGACY)+1]; + AddCheckserver(&pPacket->m_Address, &Alt, 0); + return 1; + } + else if(pPacket->m_DataSize == sizeof(SERVERBROWSE_GETCOUNT_LEGACY) && + mem_comp(pPacket->m_pData, SERVERBROWSE_GETCOUNT_LEGACY, sizeof(SERVERBROWSE_GETCOUNT_LEGACY)) == 0) + { + int Count = m_pOwner->GetCount(); + m_CountData.m_High = (Count>>8)&0xff; + m_CountData.m_Low = Count&0xff; + SendPacket(PACKET_COUNT, &pPacket->m_Address, 0); + return 1; + } + else if(pPacket->m_DataSize == sizeof(SERVERBROWSE_GETLIST_LEGACY) && + mem_comp(pPacket->m_pData, SERVERBROWSE_GETLIST_LEGACY, sizeof(SERVERBROWSE_GETLIST_LEGACY)) == 0) + { + IMastersrvSlave::SendList(&pPacket->m_Address, 0); + return 1; + } + } + else if(Socket == IMastersrv::SOCKET_CHECKER) + { + if(pPacket->m_DataSize == sizeof(SERVERBROWSE_FWRESPONSE) && + mem_comp(pPacket->m_pData, SERVERBROWSE_FWRESPONSE, sizeof(SERVERBROWSE_FWRESPONSE)) == 0) + { + AddServer(&pPacket->m_Address, 0); + return 0; // for 0.6 compatiblity + } + } + else + dbg_assert(0, "invalid socket type"); + return 0; } +void CMastersrvSlave_0_5::SendPacket(int PacketType, const NETADDR *pAddr, void *pUserData) +{ + dbg_assert(PacketType >= 0 && PacketType < NUM_PACKETS, "invalid packet type"); + + m_aPackets[PacketType].m_Address = *pAddr; + m_pOwner->Send((PacketType != PACKET_CHECK) ? IMastersrv::SOCKET_OP : IMastersrv::SOCKET_CHECKER, + &m_aPackets[PacketType], NET_TOKEN_NONE, NET_PACKETVERSION_LEGACY); +} + +void CMastersrvSlave_0_5::NetaddrToMastersrv(CMastersrvAddrLegacy *pOut, const NETADDR *pIn) +{ + dbg_assert(pIn->type == NETTYPE_IPV4, "legacy mastersrv addresses only support ipv4"); + + mem_copy(pOut->m_aIp, pIn->ip, 4); + pOut->m_aPort[0] = (pIn->port>>0)&0xff; // little endian + pOut->m_aPort[1] = (pIn->port>>8)&0xff; +} + +IMastersrvSlave *CreateSlave_0_5(IMastersrv *pOwner) +{ + return new CMastersrvSlave_0_5(pOwner); +} + diff --git a/src/mastersrv/mastersrv6.cpp b/src/mastersrv/mastersrv6.cpp index be2cdbe17..bf4f07c1d 100644 --- a/src/mastersrv/mastersrv6.cpp +++ b/src/mastersrv/mastersrv6.cpp @@ -3,8 +3,126 @@ #include "mastersrv.h" -IMastersrvSlave *CreateSlave_0_6(IMastersrv *pOwner) +class CMastersrvSlave_0_6 : public IMastersrvSlaveAdv { +public: + CMastersrvSlave_0_6(IMastersrv *pOwner); + virtual ~CMastersrvSlave_0_6() {} + + virtual int BuildPacketStart(void *pData, int MaxLength); + virtual int BuildPacketAdd(void *pData, int MaxLength, const NETADDR *pAddr, void *pUserData); + virtual int ProcessMessage(int Socket, const CNetChunk *pPacket, TOKEN PacketToken, int PacketVersion); + + virtual void SendPacket(int PacketType, const NETADDR *pAddr, void *pUserData); + + struct CCountPacketData + { + unsigned char m_Header[sizeof(SERVERBROWSE_COUNT)]; + unsigned char m_High; + unsigned char m_Low; + } m_CountData; +}; + +CMastersrvSlave_0_6::CMastersrvSlave_0_6(IMastersrv *pOwner) + : IMastersrvSlaveAdv(pOwner, IMastersrv::MASTERSRV_0_6) +{ + mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT, sizeof(m_CountData.m_Header)); + + for(int i = 0; i < NUM_PACKETS; i++) + { + m_aPackets[i].m_ClientID = -1; + m_aPackets[i].m_Flags = NETSENDFLAG_CONNLESS|NETSENDFLAG_STATELESS; + } + + m_aPackets[PACKET_COUNT].m_DataSize = sizeof(m_CountData); + m_aPackets[PACKET_COUNT].m_pData = &m_CountData; + + m_aPackets[PACKET_CHECK].m_DataSize = sizeof(SERVERBROWSE_FWCHECK); + m_aPackets[PACKET_CHECK].m_pData = SERVERBROWSE_FWCHECK; + + m_aPackets[PACKET_OK].m_DataSize = sizeof(SERVERBROWSE_FWOK); + m_aPackets[PACKET_OK].m_pData = SERVERBROWSE_FWOK; + + m_aPackets[PACKET_ERROR].m_DataSize = sizeof(SERVERBROWSE_FWERROR); + m_aPackets[PACKET_ERROR].m_pData = SERVERBROWSE_FWERROR; +} + +int CMastersrvSlave_0_6::BuildPacketStart(void *pData, int MaxLength) +{ + if(MaxLength < sizeof(SERVERBROWSE_LIST)) + return -1; + mem_copy(pData, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)); + return sizeof(SERVERBROWSE_LIST); +} + +int CMastersrvSlave_0_6::BuildPacketAdd(void *pData, int MaxLength, const NETADDR *pAddr, void *pUserData) +{ + if(MaxLength < sizeof(CMastersrvAddr)) + return -1; + NetaddrToMastersrv((CMastersrvAddr *)pData, pAddr); + return sizeof(CMastersrvAddr); +} + +int CMastersrvSlave_0_6::ProcessMessage(int Socket, const CNetChunk *pPacket, TOKEN PacketToken, int PacketVersion) +{ + if(PacketVersion != NET_PACKETVERSION_LEGACY || !(pPacket->m_Flags&NETSENDFLAG_CONNLESS)) + return 0; + + if(Socket == IMastersrv::SOCKET_OP) + { + if(pPacket->m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT)+2 && + mem_comp(pPacket->m_pData, SERVERBROWSE_HEARTBEAT, sizeof(SERVERBROWSE_HEARTBEAT)) == 0) + { + NETADDR Alt; + unsigned char *d = (unsigned char *)pPacket->m_pData; + Alt = pPacket->m_Address; + Alt.port = (d[sizeof(SERVERBROWSE_HEARTBEAT)]<<8) + | d[sizeof(SERVERBROWSE_HEARTBEAT)+1]; + AddCheckserver(&pPacket->m_Address, &Alt, 0); + return 1; + } + else if(pPacket->m_DataSize == sizeof(SERVERBROWSE_GETCOUNT) && + mem_comp(pPacket->m_pData, SERVERBROWSE_GETCOUNT, sizeof(SERVERBROWSE_GETCOUNT)) == 0) + { + int Count = m_pOwner->GetCount(); + m_CountData.m_High = (Count>>8)&0xff; + m_CountData.m_Low = Count&0xff; + SendPacket(PACKET_COUNT, &pPacket->m_Address, 0); + return 1; + } + else if(pPacket->m_DataSize == sizeof(SERVERBROWSE_GETLIST) && + mem_comp(pPacket->m_pData, SERVERBROWSE_GETLIST, sizeof(SERVERBROWSE_GETLIST)) == 0) + { + IMastersrvSlave::SendList(&pPacket->m_Address, 0); + return 1; + } + } + else if(Socket == IMastersrv::SOCKET_CHECKER) + { + if(pPacket->m_DataSize == sizeof(SERVERBROWSE_FWRESPONSE) && + mem_comp(pPacket->m_pData, SERVERBROWSE_FWRESPONSE, sizeof(SERVERBROWSE_FWRESPONSE)) == 0) + { + AddServer(&pPacket->m_Address, 0); + return 0; // for 0.5 compatiblity + } + } + else + dbg_assert(0, "invalid socket type"); + return 0; } +void CMastersrvSlave_0_6::SendPacket(int PacketType, const NETADDR *pAddr, void *pUserData) +{ + dbg_assert(PacketType >= 0 && PacketType < NUM_PACKETS, "invalid packet type"); + + m_aPackets[PacketType].m_Address = *pAddr; + m_pOwner->Send((PacketType != PACKET_CHECK) ? IMastersrv::SOCKET_OP : IMastersrv::SOCKET_CHECKER, + &m_aPackets[PacketType], NET_TOKEN_NONE, NET_PACKETVERSION_LEGACY); +} + +IMastersrvSlave *CreateSlave_0_6(IMastersrv *pOwner) +{ + return new CMastersrvSlave_0_6(pOwner); +} + diff --git a/src/mastersrv/mastersrv7.cpp b/src/mastersrv/mastersrv7.cpp index 929f42a46..d749421f2 100644 --- a/src/mastersrv/mastersrv7.cpp +++ b/src/mastersrv/mastersrv7.cpp @@ -49,10 +49,10 @@ CMastersrvSlave_0_7::CMastersrvSlave_0_7(IMastersrv *pOwner) int CMastersrvSlave_0_7::BuildPacketStart(void *pData, int MaxLength) { - if(MaxLength < sizeof(SERVERBROWSE_GETLIST)) + if(MaxLength < sizeof(SERVERBROWSE_LIST)) return -1; - mem_copy(pData, SERVERBROWSE_GETLIST, sizeof(SERVERBROWSE_GETLIST)); - return sizeof(SERVERBROWSE_GETLIST); + mem_copy(pData, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)); + return sizeof(SERVERBROWSE_LIST); } int CMastersrvSlave_0_7::BuildPacketAdd(void *pData, int MaxLength, const NETADDR *pAddr, void *pUserData) @@ -123,7 +123,6 @@ void CMastersrvSlave_0_7::SendPacket(int PacketType, const NETADDR *pAddr, void m_aPackets[PacketType].m_Address = *pAddr; m_pOwner->Send((PacketType != PACKET_CHECK) ? IMastersrv::SOCKET_OP : IMastersrv::SOCKET_CHECKER, &m_aPackets[PacketType], (TOKEN) (long int) pUserData, NET_PACKETVERSION); - } IMastersrvSlave *CreateSlave_0_7(IMastersrv *pOwner)