mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
refactored mastersrv, working for 0.7 only currently
This commit is contained in:
parent
e49e67e2f4
commit
1c591793b0
|
@ -60,7 +60,7 @@ enum
|
|||
|
||||
NET_SEEDTIME = 10,
|
||||
NET_MAX_PACKETSIZE = 1400,
|
||||
NET_MAX_PAYLOAD = NET_MAX_PACKETSIZE-6,
|
||||
NET_MAX_PAYLOAD = NET_MAX_PACKETSIZE-15,
|
||||
NET_MAX_CHUNKHEADERSIZE = 3,
|
||||
NET_PACKETHEADERSIZE = 11,
|
||||
NET_PACKETHEADERSIZE_LEGACY = 3,
|
||||
|
|
|
@ -13,8 +13,623 @@
|
|||
|
||||
#include "mastersrv.h"
|
||||
|
||||
int main(int argc, const char **argv) // ignore_convention
|
||||
{
|
||||
dbg_logger_stdout();
|
||||
net_init();
|
||||
|
||||
enum {
|
||||
IKernel *pKernel = IKernel::Create();
|
||||
IStorage *pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv);
|
||||
IConfig *pConfig = CreateConfig();
|
||||
IConsole *pConsole = CreateConsole(CFGFLAG_MASTER);
|
||||
IMastersrv *pMastersrv = CreateMastersrv();
|
||||
|
||||
bool RegisterFail = !pKernel->RegisterInterface(pStorage);
|
||||
RegisterFail |= !pKernel->RegisterInterface(pConsole);
|
||||
RegisterFail |= !pKernel->RegisterInterface(pConfig);
|
||||
RegisterFail |= !pKernel->RegisterInterface(pMastersrv);
|
||||
|
||||
if(RegisterFail)
|
||||
return -1;
|
||||
|
||||
pConfig->Init();
|
||||
if(argc > 1) // ignore_convention
|
||||
pConsole->ParseArguments(argc-1, &argv[1]); // ignore_convention
|
||||
|
||||
int Result;
|
||||
|
||||
if((Result = pMastersrv->Init()) != 0)
|
||||
{
|
||||
dbg_msg("mastersrv", "initialisation failed (%d)", Result);
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result = pMastersrv->Run();
|
||||
|
||||
delete pMastersrv;
|
||||
delete pConsole;
|
||||
delete pConfig;
|
||||
delete pStorage;
|
||||
delete pKernel;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void IMastersrvSlave::NetaddrToMastersrv(CMastersrvAddr *pOut, const NETADDR *pIn)
|
||||
{
|
||||
dbg_assert(pIn->type == NETTYPE_IPV6 || pIn->type == NETTYPE_IPV4, "nettype not supported");
|
||||
|
||||
if(pIn->type == NETTYPE_IPV6)
|
||||
{
|
||||
mem_copy(pOut->m_aIp, pIn->ip, sizeof(pOut->m_aIp));
|
||||
}
|
||||
else if(pIn->type == NETTYPE_IPV4)
|
||||
{
|
||||
static const char aIPV4Mapping[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
|
||||
mem_copy(pOut->m_aIp, aIPV4Mapping, sizeof(aIPV4Mapping));
|
||||
mem_copy(pOut->m_aIp + 12, pIn->ip, 4);
|
||||
}
|
||||
|
||||
pOut->m_aPort[0] = (pIn->port>>8)&0xff;
|
||||
pOut->m_aPort[1] = (pIn->port>>0)&0xff;
|
||||
}
|
||||
|
||||
class CMastersrv : public IMastersrv
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_SERVERS=1200,
|
||||
MAX_CHECKSERVERS=MAX_SERVERS,
|
||||
MAX_PACKETS=16,
|
||||
|
||||
EXPIRE_TIME=90,
|
||||
BAN_REFRESH_TIME=300,
|
||||
PACKET_REFRESH_TIME=5,
|
||||
};
|
||||
CMastersrv();
|
||||
~CMastersrv();
|
||||
|
||||
virtual int Init();
|
||||
virtual int Run();
|
||||
|
||||
virtual void AddServer(const NETADDR *pAddr, void *pUserData, int Version);
|
||||
virtual void AddCheckserver(const NETADDR *pAddr, const NETADDR *pAltAddr, void *pUserData, int Version);
|
||||
virtual void SendList(const NETADDR *pAddr, void *pUserData, int Version);
|
||||
virtual int GetCount() const;
|
||||
|
||||
virtual int Send(int Socket, const CNetChunk *pPacket, TOKEN PacketToken, int PacketVersion);
|
||||
|
||||
void PurgeServers();
|
||||
void UpdateServers();
|
||||
void BuildPackets();
|
||||
|
||||
void ReloadBans();
|
||||
|
||||
private:
|
||||
IConsole *m_pConsole;
|
||||
|
||||
CNetBan m_NetBan;
|
||||
CNetClient m_NetOp;
|
||||
CNetClient m_NetChecker;
|
||||
|
||||
int64 m_BanRefreshTime;
|
||||
int64 m_PacketRefreshTime;
|
||||
|
||||
struct CServerEntry
|
||||
{
|
||||
NETADDR m_Address;
|
||||
void *m_pSlaveUserData;
|
||||
|
||||
int m_Version;
|
||||
int64 m_Expire;
|
||||
};
|
||||
|
||||
struct CCheckServer
|
||||
{
|
||||
NETADDR m_Address;
|
||||
NETADDR m_AltAddress;
|
||||
void *m_pSlaveUserData;
|
||||
|
||||
int m_TryCount;
|
||||
int64 m_TryTime;
|
||||
|
||||
int m_Version;
|
||||
};
|
||||
|
||||
CServerEntry m_aServers[MAX_SERVERS];
|
||||
int m_NumServers;
|
||||
CCheckServer m_aCheckServers[MAX_CHECKSERVERS];
|
||||
int m_NumCheckServers;
|
||||
|
||||
struct CMastersrvSlave
|
||||
{
|
||||
struct CPacket
|
||||
{
|
||||
char m_aData[NET_MAX_PAYLOAD];
|
||||
int m_Size;
|
||||
} m_aPackets[MAX_PACKETS];
|
||||
int m_NumPackets;
|
||||
|
||||
IMastersrvSlave *m_pSlave;
|
||||
};
|
||||
|
||||
CMastersrvSlave m_aSlaves[NUM_MASTERSRV];
|
||||
};
|
||||
|
||||
IMastersrv *CreateMastersrv()
|
||||
{
|
||||
return new CMastersrv();
|
||||
}
|
||||
|
||||
CMastersrv::CMastersrv()
|
||||
{
|
||||
for(int s = 0; s < NUM_MASTERSRV; s++)
|
||||
m_aSlaves[s].m_pSlave = 0;
|
||||
}
|
||||
|
||||
CMastersrv::~CMastersrv()
|
||||
{
|
||||
for(int s = 0; s < NUM_MASTERSRV; s++)
|
||||
if(m_aSlaves[s].m_pSlave)
|
||||
delete m_aSlaves[s].m_pSlave;
|
||||
}
|
||||
|
||||
int CMastersrv::Init()
|
||||
{
|
||||
m_pConsole = Kernel()->RequestInterface<IConsole>();
|
||||
|
||||
m_NetBan.Init(m_pConsole, Kernel()->RequestInterface<IStorage>());
|
||||
|
||||
NETADDR BindAddr;
|
||||
if(g_Config.m_Bindaddr[0] && net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0)
|
||||
{
|
||||
// got bindaddr
|
||||
BindAddr.type = NETTYPE_ALL;
|
||||
BindAddr.port = MASTERSERVER_PORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_zero(&BindAddr, sizeof(BindAddr));
|
||||
BindAddr.type = NETTYPE_ALL;
|
||||
BindAddr.port = MASTERSERVER_PORT;
|
||||
}
|
||||
|
||||
if(!m_NetOp.Open(BindAddr, NETFLAG_ALLOWSTATELESS))
|
||||
{
|
||||
dbg_msg("mastersrv", "couldn't start network (op)");
|
||||
return -1;
|
||||
}
|
||||
BindAddr.port = MASTERSERVER_PORT+1;
|
||||
if(!m_NetChecker.Open(BindAddr, NETFLAG_ALLOWSTATELESS))
|
||||
{
|
||||
dbg_msg("mastersrv", "couldn't start network (checker)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// process pending commands
|
||||
m_pConsole->StoreCommands(false);
|
||||
|
||||
for(int s = 0; s < NUM_MASTERSRV; s++)
|
||||
m_aSlaves[s].m_NumPackets = 0;
|
||||
|
||||
m_aSlaves[MASTERSRV_0_5].m_pSlave = CreateSlave_0_5(this);
|
||||
m_aSlaves[MASTERSRV_0_6].m_pSlave = CreateSlave_0_6(this);
|
||||
m_aSlaves[MASTERSRV_0_7].m_pSlave = CreateSlave_0_7(this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CMastersrv::Run()
|
||||
{
|
||||
dbg_msg("mastersrv", "started");
|
||||
|
||||
while(1)
|
||||
{
|
||||
m_NetOp.Update();
|
||||
m_NetChecker.Update();
|
||||
|
||||
// process packets
|
||||
CNetChunk Packet;
|
||||
TOKEN Token;
|
||||
int Version;
|
||||
while(m_NetOp.Recv(&Packet, &Token, &Version))
|
||||
{
|
||||
// check if the server is banned
|
||||
if(m_NetBan.IsBanned(&Packet.m_Address, 0, 0))
|
||||
continue;
|
||||
|
||||
for(int s = 0; s < NUM_MASTERSRV; s++)
|
||||
if(m_aSlaves[s].m_pSlave)
|
||||
{
|
||||
if(m_aSlaves[s].m_pSlave->ProcessMessage(SOCKET_OP, &Packet, Token, Version) != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// process packets
|
||||
while(m_NetChecker.Recv(&Packet, &Token, &Version))
|
||||
{
|
||||
// check if the server is banned
|
||||
if(m_NetBan.IsBanned(&Packet.m_Address, 0, 0))
|
||||
continue;
|
||||
|
||||
for(int s = 0; s < NUM_MASTERSRV; s++)
|
||||
if(m_aSlaves[s].m_pSlave)
|
||||
if(m_aSlaves[s].m_pSlave->ProcessMessage(SOCKET_CHECKER, &Packet, Token, Version) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
int64 Now = time_get();
|
||||
int64 Freq = time_freq();
|
||||
if(m_BanRefreshTime < Now)
|
||||
{
|
||||
m_BanRefreshTime = Now + Freq * BAN_REFRESH_TIME;
|
||||
ReloadBans();
|
||||
}
|
||||
|
||||
if(m_PacketRefreshTime < Now)
|
||||
{
|
||||
m_PacketRefreshTime = Now + Freq * PACKET_REFRESH_TIME;
|
||||
|
||||
PurgeServers();
|
||||
UpdateServers();
|
||||
BuildPackets();
|
||||
}
|
||||
|
||||
// be nice to the CPU
|
||||
thread_sleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CMastersrv::UpdateServers()
|
||||
{
|
||||
int64 Now = time_get();
|
||||
int64 Freq = time_freq();
|
||||
for(int i = 0; i < m_NumCheckServers; i++)
|
||||
{
|
||||
CCheckServer *pCheck = &m_aCheckServers[i];
|
||||
|
||||
if(pCheck->m_TryTime + Freq < Now)
|
||||
{
|
||||
IMastersrvSlave *pSlave = m_aSlaves[pCheck->m_Version].m_pSlave;
|
||||
dbg_assert(pSlave != 0, "attempting to access uninitalised slave");
|
||||
|
||||
if(pCheck->m_TryCount == 10)
|
||||
{
|
||||
char aAddrStr[NETADDR_MAXSTRSIZE];
|
||||
net_addr_str(&pCheck->m_Address, aAddrStr, sizeof(aAddrStr), true);
|
||||
char aAltAddrStr[NETADDR_MAXSTRSIZE];
|
||||
net_addr_str(&pCheck->m_AltAddress, aAltAddrStr, sizeof(aAltAddrStr), true);
|
||||
dbg_msg("mastersrv", "check failed: %s (%s)", aAddrStr, aAltAddrStr);
|
||||
|
||||
// FAIL!!
|
||||
pSlave->SendError(&pCheck->m_Address, pCheck->m_pSlaveUserData);
|
||||
*pCheck = m_aCheckServers[m_NumCheckServers-1];
|
||||
m_NumCheckServers--;
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCheck->m_TryCount++;
|
||||
pCheck->m_TryTime = Now;
|
||||
|
||||
if(pCheck->m_TryCount&1)
|
||||
pSlave->SendCheck(&pCheck->m_Address, pCheck->m_pSlaveUserData);
|
||||
else
|
||||
pSlave->SendCheck(&pCheck->m_AltAddress, pCheck->m_pSlaveUserData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMastersrv::BuildPackets()
|
||||
{
|
||||
bool aPreparePacket[NUM_MASTERSRV];
|
||||
for(int s = 0; s < NUM_MASTERSRV; s++)
|
||||
{
|
||||
m_aSlaves[s].m_NumPackets = 0;
|
||||
aPreparePacket[s] = true;
|
||||
for(int i = 0; i < MAX_PACKETS; i++)
|
||||
m_aSlaves[s].m_aPackets[i].m_Size = 0;
|
||||
}
|
||||
|
||||
for(int i = 0; i < m_NumServers; i++)
|
||||
{
|
||||
CServerEntry *pServer = &m_aServers[i];
|
||||
CMastersrvSlave *pSlaveData = &m_aSlaves[pServer->m_Version];
|
||||
IMastersrvSlave *pSlave = pSlaveData->m_pSlave;
|
||||
CMastersrvSlave::CPacket *pPacket = &pSlaveData->m_aPackets[pSlaveData->m_NumPackets - 1];
|
||||
dbg_assert(pSlave != 0, "attempting to access uninitalised slave");
|
||||
|
||||
int BytesWritten;
|
||||
|
||||
if(aPreparePacket[pServer->m_Version])
|
||||
{
|
||||
if(pSlaveData->m_NumPackets != 0)
|
||||
{
|
||||
BytesWritten = pSlave->BuildPacketFinalize(&pPacket->m_aData[pPacket->m_Size], NET_MAX_PAYLOAD - pPacket->m_Size);
|
||||
dbg_assert(BytesWritten >= 0, "build packet finalisation failed");
|
||||
}
|
||||
|
||||
pPacket = &pSlaveData->m_aPackets[pSlaveData->m_NumPackets];
|
||||
pSlaveData->m_NumPackets++;
|
||||
|
||||
BytesWritten = pSlave->BuildPacketStart(&pPacket->m_aData[0], NET_MAX_PAYLOAD);
|
||||
|
||||
dbg_assert(BytesWritten >= 0, "build packet initialisation failed");
|
||||
pPacket->m_Size += BytesWritten;
|
||||
|
||||
pSlaveData->m_NumPackets++;
|
||||
|
||||
aPreparePacket[pServer->m_Version] = false;
|
||||
}
|
||||
|
||||
BytesWritten = pSlave->BuildPacketAdd(&pPacket->m_aData[pPacket->m_Size], NET_MAX_PAYLOAD - pPacket->m_Size,
|
||||
&pServer->m_Address, pServer->m_pSlaveUserData);
|
||||
if(BytesWritten < 0)
|
||||
{
|
||||
aPreparePacket[pServer->m_Version] = true;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
pPacket->m_Size += BytesWritten;
|
||||
}
|
||||
|
||||
for(int s = 0; s < NUM_MASTERSRV; s++)
|
||||
{
|
||||
CMastersrvSlave *pSlaveData = &m_aSlaves[s];
|
||||
IMastersrvSlave *pSlave = pSlaveData->m_pSlave;
|
||||
if(m_aSlaves[s].m_NumPackets > 0)
|
||||
{
|
||||
dbg_assert(pSlave != 0, "attempting to finalise packet for non-existant slave");
|
||||
|
||||
CMastersrvSlave::CPacket *pPacket = &pSlaveData->m_aPackets[pSlaveData->m_NumPackets - 1];
|
||||
dbg_assert(pSlave->BuildPacketFinalize(&pPacket->m_aData[pPacket->m_Size], NET_MAX_PAYLOAD - pPacket->m_Size) >= 0, "final build packet finalisation failed");
|
||||
}
|
||||
}
|
||||
|
||||
/* CServerEntry *pCurrent = &m_aServers[0];
|
||||
int ServersLeft = m_NumServers;
|
||||
m_NumPackets = 0;
|
||||
m_NumPacketsLegacy = 0;
|
||||
int PacketIndex = 0;
|
||||
int PacketIndexLegacy = 0;
|
||||
while(ServersLeft-- && (m_NumPackets + m_NumPacketsLegacy) < MAX_PACKETS)
|
||||
{
|
||||
if(pCurrent->m_Type == SERVERTYPE_NORMAL)
|
||||
{
|
||||
if(PacketIndex % MAX_SERVERS_PER_PACKET == 0)
|
||||
{
|
||||
PacketIndex = 0;
|
||||
m_NumPackets++;
|
||||
}
|
||||
|
||||
// copy header
|
||||
mem_copy(m_aPackets[m_NumPackets-1].m_Data.m_aHeader, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST));
|
||||
|
||||
// copy server addresses
|
||||
if(pCurrent->m_Address.type == NETTYPE_IPV6)
|
||||
{
|
||||
mem_copy(m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aIp, pCurrent->m_Address.ip,
|
||||
sizeof(m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aIp));
|
||||
}
|
||||
else
|
||||
{
|
||||
static char IPV4Mapping[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
|
||||
|
||||
mem_copy(m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aIp, IPV4Mapping, sizeof(IPV4Mapping));
|
||||
m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aIp[12] = pCurrent->m_Address.ip[0];
|
||||
m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aIp[13] = pCurrent->m_Address.ip[1];
|
||||
m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aIp[14] = pCurrent->m_Address.ip[2];
|
||||
m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aIp[15] = pCurrent->m_Address.ip[3];
|
||||
}
|
||||
|
||||
m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aPort[0] = (pCurrent->m_Address.port>>8)&0xff;
|
||||
m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aPort[1] = pCurrent->m_Address.port&0xff;
|
||||
|
||||
PacketIndex++;
|
||||
|
||||
m_aPackets[m_NumPackets-1].m_Size = sizeof(SERVERBROWSE_LIST) + sizeof(CMastersrvAddr)*PacketIndex;
|
||||
|
||||
pCurrent++;
|
||||
}
|
||||
else if(pCurrent->m_Type == SERVERTYPE_LEGACY)
|
||||
{
|
||||
if(PacketIndexLegacy % MAX_SERVERS_PER_PACKET == 0)
|
||||
{
|
||||
PacketIndexLegacy = 0;
|
||||
m_NumPacketsLegacy++;
|
||||
}
|
||||
|
||||
// copy header
|
||||
mem_copy(m_aPacketsLegacy[m_NumPacketsLegacy-1].m_Data.m_aHeader, SERVERBROWSE_LIST_LEGACY, sizeof(SERVERBROWSE_LIST_LEGACY));
|
||||
|
||||
// copy server addresses
|
||||
mem_copy(m_aPacketsLegacy[m_NumPacketsLegacy-1].m_Data.m_aServers[PacketIndexLegacy].m_aIp, pCurrent->m_Address.ip,
|
||||
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;
|
||||
|
||||
PacketIndexLegacy++;
|
||||
|
||||
m_aPacketsLegacy[m_NumPacketsLegacy-1].m_Size = sizeof(SERVERBROWSE_LIST_LEGACY) + sizeof(CMastersrvAddrLegacy)*PacketIndexLegacy;
|
||||
|
||||
pCurrent++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pCurrent = m_aServers[m_NumServers-1];
|
||||
m_NumServers--;
|
||||
dbg_msg("mastersrv", "error: server of invalid type, dropping it");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int CMastersrv::Send(int Socket, const CNetChunk *pPacket, TOKEN PacketToken, int PacketVersion)
|
||||
{
|
||||
dbg_assert(Socket >= 0 && Socket < NUM_SOCKETS, "attempting to send via non-existant socket");
|
||||
|
||||
CNetClient *pNet = 0;
|
||||
if(Socket == SOCKET_OP)
|
||||
pNet = &m_NetOp;
|
||||
else if(Socket == SOCKET_CHECKER)
|
||||
pNet = &m_NetChecker;
|
||||
|
||||
pNet->Send((CNetChunk *)pPacket, PacketToken, PacketVersion);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CMastersrv::AddServer(const NETADDR *pAddr, void *pUserData, int Version)
|
||||
{
|
||||
dbg_assert(Version >= 0 && Version < NUM_MASTERSRV, "version out of range");
|
||||
|
||||
bool Found = false;
|
||||
for(int i = 0; i < m_NumCheckServers && !Found; i++)
|
||||
{
|
||||
if((net_addr_comp(&m_aCheckServers[i].m_Address, pAddr) == 0
|
||||
|| net_addr_comp(&m_aCheckServers[i].m_AltAddress, pAddr) == 0)
|
||||
&& m_aCheckServers[i].m_Version == Version)
|
||||
|
||||
{
|
||||
m_NumCheckServers--;
|
||||
m_aCheckServers[i] = m_aCheckServers[m_NumCheckServers];
|
||||
Found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!Found) // only allow this for servers which are actually being checked
|
||||
return;
|
||||
|
||||
char aAddrStr[NETADDR_MAXSTRSIZE];
|
||||
net_addr_str(pAddr, aAddrStr, sizeof(aAddrStr), true);
|
||||
|
||||
// see if server already exists in list
|
||||
for(int i = 0; i < m_NumServers; i++)
|
||||
{
|
||||
if(net_addr_comp(&m_aServers[i].m_Address, pAddr) == 0 && m_aServers[i].m_Version == Version)
|
||||
{
|
||||
dbg_msg("mastersrv", "updated: %s", aAddrStr);
|
||||
m_aServers[i].m_pSlaveUserData = pUserData;
|
||||
m_aServers[i].m_Expire = time_get() + time_freq() * EXPIRE_TIME;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// add server
|
||||
if(m_NumServers == MAX_SERVERS)
|
||||
{
|
||||
dbg_msg("mastersrv", "error: mastersrv is full: %s", aAddrStr);
|
||||
return;
|
||||
}
|
||||
|
||||
dbg_msg("mastersrv", "added: %s", aAddrStr);
|
||||
m_aServers[m_NumServers].m_Address = *pAddr;
|
||||
m_aServers[m_NumServers].m_pSlaveUserData = pUserData;
|
||||
m_aServers[m_NumServers].m_Expire = time_get() + time_freq() * EXPIRE_TIME;
|
||||
m_aServers[m_NumServers].m_Version = Version;
|
||||
m_NumServers++;
|
||||
|
||||
IMastersrvSlave *pSlave = m_aSlaves[Version].m_pSlave;
|
||||
dbg_assert(pSlave != 0, "attempting to access uninitalised slave");
|
||||
pSlave->SendOk(pAddr, pUserData);
|
||||
}
|
||||
|
||||
void CMastersrv::AddCheckserver(const NETADDR *pAddr, const NETADDR *pAltAddr, void *pUserData, int Version)
|
||||
{
|
||||
dbg_assert(Version >= 0 && Version < NUM_MASTERSRV, "version out of range");
|
||||
|
||||
char aAddrStr[2 * NETADDR_MAXSTRSIZE + 3]; // 3 == sizeof(' ()')
|
||||
char aTmp1[NETADDR_MAXSTRSIZE], aTmp2[NETADDR_MAXSTRSIZE];
|
||||
|
||||
net_addr_str(pAddr, aTmp1, sizeof(aTmp1), true);
|
||||
net_addr_str(pAltAddr, aTmp2, sizeof(aTmp2), true);
|
||||
|
||||
str_format(aAddrStr, sizeof(aAddrStr), "%s (%s)", aTmp1, aTmp2);
|
||||
|
||||
// see if server already exists in list
|
||||
for(int i = 0; i < m_NumCheckServers; i++)
|
||||
{
|
||||
if(net_addr_comp(&m_aCheckServers[i].m_Address, pAddr) == 0
|
||||
&& m_aCheckServers[i].m_Version == Version)
|
||||
{
|
||||
dbg_msg("mastersrv/check", "warning: updated: %s", aAddrStr);
|
||||
m_aCheckServers[i].m_AltAddress = *pAltAddr;
|
||||
m_aCheckServers[i].m_pSlaveUserData = pUserData;
|
||||
m_aCheckServers[i].m_TryCount = 0;
|
||||
m_aCheckServers[i].m_TryTime = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// add server
|
||||
if(m_NumCheckServers == MAX_CHECKSERVERS)
|
||||
{
|
||||
dbg_msg("mastersrv/check", "error: mastersrv is full: %s", aAddrStr);
|
||||
return;
|
||||
}
|
||||
|
||||
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_pSlaveUserData = pUserData;
|
||||
m_aCheckServers[m_NumCheckServers].m_TryCount = 0;
|
||||
m_aCheckServers[m_NumCheckServers].m_TryTime = 0;
|
||||
m_NumCheckServers++;
|
||||
}
|
||||
|
||||
void CMastersrv::SendList(const NETADDR *pAddr, void *pUserData, int Version)
|
||||
{
|
||||
dbg_assert(Version >= 0 && Version < NUM_MASTERSRV, "version out of range");
|
||||
IMastersrvSlave *pSlave = m_aSlaves[Version].m_pSlave;
|
||||
dbg_assert(pSlave != 0, "attempting to access uninitalised slave");
|
||||
|
||||
for(int i = 0; i < m_aSlaves[Version].m_NumPackets; i++)
|
||||
{
|
||||
CMastersrvSlave::CPacket *pPacket = &m_aSlaves[Version].m_aPackets[i];
|
||||
pSlave->SendList(pAddr, pPacket->m_aData, pPacket->m_Size, pUserData);
|
||||
}
|
||||
}
|
||||
|
||||
int CMastersrv::GetCount() const
|
||||
{
|
||||
dbg_msg("mastersrv", "requesting count, responding with %d", m_NumServers);
|
||||
return m_NumServers;
|
||||
}
|
||||
|
||||
void CMastersrv::PurgeServers()
|
||||
{
|
||||
int64 Now = time_get();
|
||||
int i = 0;
|
||||
while(i < m_NumServers)
|
||||
{
|
||||
if(m_aServers[i].m_Expire < Now)
|
||||
{
|
||||
// remove server
|
||||
char aAddrStr[NETADDR_MAXSTRSIZE];
|
||||
net_addr_str(&m_aServers[i].m_Address, aAddrStr, sizeof(aAddrStr), true);
|
||||
dbg_msg("mastersrv", "expired: %s", aAddrStr);
|
||||
m_aServers[i] = m_aServers[m_NumServers-1];
|
||||
m_NumServers--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void CMastersrv::ReloadBans()
|
||||
{
|
||||
m_NetBan.UnbanAll();
|
||||
m_pConsole->ExecuteFile("master.cfg");
|
||||
}
|
||||
|
||||
/*enum
|
||||
{
|
||||
MTU = 1400,
|
||||
MAX_SERVERS_PER_PACKET=75,
|
||||
MAX_PACKETS=16,
|
||||
|
@ -407,7 +1022,7 @@ int main(int argc, const char **argv) // ignore_convention
|
|||
// add it
|
||||
AddCheckserver(&Packet.m_Address, &Alt, SERVERTYPE_NORMAL, Token);
|
||||
}
|
||||
/*else if(Packet.m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT_LEGACY)+2 &&
|
||||
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT_LEGACY)+2 &&
|
||||
mem_comp(Packet.m_pData, SERVERBROWSE_HEARTBEAT_LEGACY, sizeof(SERVERBROWSE_HEARTBEAT_LEGACY)) == 0)
|
||||
{
|
||||
NETADDR Alt;
|
||||
|
@ -419,7 +1034,7 @@ int main(int argc, const char **argv) // ignore_convention
|
|||
|
||||
// add it
|
||||
AddCheckserver(&Packet.m_Address, &Alt, SERVERTYPE_LEGACY);
|
||||
}*/
|
||||
}
|
||||
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETCOUNT) &&
|
||||
mem_comp(Packet.m_pData, SERVERBROWSE_GETCOUNT, sizeof(SERVERBROWSE_GETCOUNT)) == 0)
|
||||
{
|
||||
|
@ -435,7 +1050,7 @@ int main(int argc, const char **argv) // ignore_convention
|
|||
m_CountData.m_Low = m_NumServers&0xff;
|
||||
m_NetOp.Send(&p, Token);
|
||||
}
|
||||
/*else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETCOUNT_LEGACY) &&
|
||||
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETCOUNT_LEGACY) &&
|
||||
mem_comp(Packet.m_pData, SERVERBROWSE_GETCOUNT_LEGACY, sizeof(SERVERBROWSE_GETCOUNT_LEGACY)) == 0)
|
||||
{
|
||||
dbg_msg("mastersrv", "count requested, responding with %d", m_NumServers);
|
||||
|
@ -449,7 +1064,7 @@ int main(int argc, const char **argv) // ignore_convention
|
|||
m_CountDataLegacy.m_High = (m_NumServers>>8)&0xff;
|
||||
m_CountDataLegacy.m_Low = m_NumServers&0xff;
|
||||
m_NetOp.Send(&p);
|
||||
}*/
|
||||
}
|
||||
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETLIST) &&
|
||||
mem_comp(Packet.m_pData, SERVERBROWSE_GETLIST, sizeof(SERVERBROWSE_GETLIST)) == 0)
|
||||
{
|
||||
|
@ -468,7 +1083,7 @@ int main(int argc, const char **argv) // ignore_convention
|
|||
m_NetOp.Send(&p, Token);
|
||||
}
|
||||
}
|
||||
/*else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETLIST_LEGACY) &&
|
||||
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETLIST_LEGACY) &&
|
||||
mem_comp(Packet.m_pData, SERVERBROWSE_GETLIST_LEGACY, sizeof(SERVERBROWSE_GETLIST_LEGACY)) == 0)
|
||||
{
|
||||
// someone requested the list
|
||||
|
@ -485,7 +1100,7 @@ int main(int argc, const char **argv) // ignore_convention
|
|||
p.m_pData = &m_aPacketsLegacy[i].m_Data;
|
||||
m_NetOp.Send(&p);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
// process m_aPackets
|
||||
|
@ -543,3 +1158,5 @@ int main(int argc, const char **argv) // ignore_convention
|
|||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
#ifndef MASTERSRV_MASTERSRV_H
|
||||
#define MASTERSRV_MASTERSRV_H
|
||||
static const int MASTERSERVER_PORT = 8300;
|
||||
|
||||
#include <engine/kernel.h>
|
||||
#include <engine/shared/network.h>
|
||||
|
||||
/*static const int MASTERSERVER_PORT = 8300;
|
||||
|
||||
enum ServerType
|
||||
{
|
||||
SERVERTYPE_INVALID = -1,
|
||||
SERVERTYPE_NORMAL,
|
||||
SERVERTYPE_LEGACY
|
||||
};
|
||||
};*/
|
||||
|
||||
struct CMastersrvAddr
|
||||
{
|
||||
|
@ -17,6 +21,7 @@ struct CMastersrvAddr
|
|||
unsigned char m_aPort[2];
|
||||
};
|
||||
|
||||
|
||||
static const unsigned char SERVERBROWSE_HEARTBEAT[] = {255, 255, 255, 255, 'b', 'e', 'a', '2'};
|
||||
|
||||
static const unsigned char SERVERBROWSE_GETLIST[] = {255, 255, 255, 255, 'r', 'e', 'q', '2'};
|
||||
|
@ -34,6 +39,7 @@ static const unsigned char SERVERBROWSE_FWOK[] = {255, 255, 255, 255, 'f', 'w',
|
|||
static const unsigned char SERVERBROWSE_FWERROR[] = {255, 255, 255, 255, 'f', 'w', 'e', 'r'};
|
||||
|
||||
|
||||
/*
|
||||
// packet headers for the 0.5 branch
|
||||
|
||||
struct CMastersrvAddrLegacy
|
||||
|
@ -49,4 +55,119 @@ static const unsigned char SERVERBROWSE_LIST_LEGACY[] = {255, 255, 255, 255, 'l'
|
|||
|
||||
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;
|
||||
|
||||
enum
|
||||
{
|
||||
MASTERSERVER_PORT=8300,
|
||||
};
|
||||
|
||||
class IMastersrv : public IInterface
|
||||
{
|
||||
MACRO_INTERFACE("mastersrv", 0)
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MASTERSRV_0_7=0,
|
||||
MASTERSRV_0_6,
|
||||
MASTERSRV_0_5,
|
||||
NUM_MASTERSRV,
|
||||
|
||||
SOCKET_OP=0,
|
||||
SOCKET_CHECKER,
|
||||
NUM_SOCKETS,
|
||||
};
|
||||
|
||||
IMastersrv() {}
|
||||
virtual ~IMastersrv() {}
|
||||
|
||||
virtual int Init() = 0;
|
||||
virtual int Run() = 0;
|
||||
|
||||
virtual void AddServer(const NETADDR *pAddr, void *pUserData, int Version) = 0;
|
||||
virtual void AddCheckserver(const NETADDR *pAddr, const NETADDR *pAltAddr, void *pUserData, int Version) = 0;
|
||||
virtual void SendList(const NETADDR *pAddr, void *pUserData, int Version) = 0;
|
||||
virtual int GetCount() const = 0;
|
||||
|
||||
virtual int Send(int Socket, const CNetChunk *pPacket, TOKEN PacketToken, int PacketVersion) = 0;
|
||||
};
|
||||
|
||||
class IMastersrvSlave
|
||||
{
|
||||
public:
|
||||
IMastersrvSlave(IMastersrv *pOwner, int Version) : m_pOwner(pOwner), m_Version(Version) {}
|
||||
virtual ~IMastersrvSlave() {}
|
||||
|
||||
// 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); }
|
||||
|
||||
// interface for packet building
|
||||
// these functions return number of bytes written
|
||||
// if that number smaller than 0, an error is assumed
|
||||
virtual int BuildPacketStart(void *pData, int MaxLength) { return 0; };
|
||||
virtual int BuildPacketAdd(void *pData, int MaxLength, const NETADDR *pAddr, void *pUserData) = 0;
|
||||
virtual int BuildPacketFinalize(void *pData, int MaxLength) { return 0; };
|
||||
|
||||
// interface for packet receiving
|
||||
// this function shall return 0 if the packet should be furtherly processed
|
||||
virtual int ProcessMessage(int Socket, const CNetChunk *pPacket, TOKEN PacketToken, int PacketVersion) = 0;
|
||||
|
||||
// interface for network
|
||||
virtual void SendCheck(const NETADDR *pAddr, void *pUserData) = 0;
|
||||
virtual void SendOk(const NETADDR *pAddr, void *pUserData) = 0;
|
||||
virtual void SendError(const NETADDR *pAddr, void *pUserData) = 0;
|
||||
virtual void SendList(const NETADDR *pAddr, const void *pData, int DataSize, void *pUserData) = 0;
|
||||
|
||||
static void NetaddrToMastersrv(CMastersrvAddr *pOut, const NETADDR *pIn);
|
||||
|
||||
protected:
|
||||
IMastersrv *m_pOwner;
|
||||
const int m_Version;
|
||||
};
|
||||
|
||||
class IMastersrvSlaveAdv : public IMastersrvSlave
|
||||
{
|
||||
public:
|
||||
IMastersrvSlaveAdv(IMastersrv *pOwner, int Version) : IMastersrvSlave(pOwner, Version) {}
|
||||
virtual ~IMastersrvSlaveAdv() {}
|
||||
|
||||
virtual void SendCount(const NETADDR *pAddr, void *pUserData) { SendPacket(PACKET_COUNT, pAddr, pUserData); }
|
||||
virtual void SendCheck(const NETADDR *pAddr, void *pUserData) { SendPacket(PACKET_CHECK, pAddr, pUserData); }
|
||||
virtual void SendOk(const NETADDR *pAddr, void *pUserData) { SendPacket(PACKET_OK, pAddr, pUserData); }
|
||||
virtual void SendError(const NETADDR *pAddr, void *pUserData) { SendPacket(PACKET_ERROR, pAddr, pUserData); }
|
||||
virtual void SendList(const NETADDR *pAddr, const void *pData, int DataSize, void *pUserData)
|
||||
{
|
||||
m_aPackets[PACKET_LIST].m_DataSize = DataSize;
|
||||
m_aPackets[PACKET_LIST].m_pData = pData;
|
||||
SendPacket(PACKET_LIST, pAddr, pUserData);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void SendPacket(int PacketType, const NETADDR *pAddr, void *pUserData) = 0;
|
||||
|
||||
enum
|
||||
{
|
||||
PACKET_COUNT=0,
|
||||
PACKET_CHECK,
|
||||
PACKET_OK,
|
||||
PACKET_ERROR,
|
||||
PACKET_LIST,
|
||||
NUM_PACKETS,
|
||||
};
|
||||
CNetChunk m_aPackets[NUM_PACKETS];
|
||||
};
|
||||
|
||||
IMastersrv *CreateMastersrv();
|
||||
|
||||
IMastersrvSlave *CreateSlave_0_5(IMastersrv *pOwner);
|
||||
IMastersrvSlave *CreateSlave_0_6(IMastersrv *pOwner);
|
||||
IMastersrvSlave *CreateSlave_0_7(IMastersrv *pOwner);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
10
src/mastersrv/mastersrv5.cpp
Normal file
10
src/mastersrv/mastersrv5.cpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
|
||||
#include "mastersrv.h"
|
||||
|
||||
IMastersrvSlave *CreateSlave_0_5(IMastersrv *pOwner)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
10
src/mastersrv/mastersrv6.cpp
Normal file
10
src/mastersrv/mastersrv6.cpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
|
||||
#include "mastersrv.h"
|
||||
|
||||
IMastersrvSlave *CreateSlave_0_6(IMastersrv *pOwner)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
133
src/mastersrv/mastersrv7.cpp
Normal file
133
src/mastersrv/mastersrv7.cpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
|
||||
#include "mastersrv.h"
|
||||
|
||||
class CMastersrvSlave_0_7 : public IMastersrvSlaveAdv
|
||||
{
|
||||
public:
|
||||
CMastersrvSlave_0_7(IMastersrv *pOwner);
|
||||
virtual ~CMastersrvSlave_0_7() {}
|
||||
|
||||
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_7::CMastersrvSlave_0_7(IMastersrv *pOwner)
|
||||
: IMastersrvSlaveAdv(pOwner, IMastersrv::MASTERSRV_0_7)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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_7::BuildPacketStart(void *pData, int MaxLength)
|
||||
{
|
||||
if(MaxLength < sizeof(SERVERBROWSE_GETLIST))
|
||||
return -1;
|
||||
mem_copy(pData, SERVERBROWSE_GETLIST, sizeof(SERVERBROWSE_GETLIST));
|
||||
return sizeof(SERVERBROWSE_GETLIST);
|
||||
}
|
||||
|
||||
int CMastersrvSlave_0_7::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_7::ProcessMessage(int Socket, const CNetChunk *pPacket, TOKEN PacketToken, int PacketVersion)
|
||||
{
|
||||
if(PacketVersion != NET_PACKETVERSION || !(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)
|
||||
{
|
||||
if(pPacket->m_Flags&NETSENDFLAG_STATELESS)
|
||||
return -1;
|
||||
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, (void *)PacketToken);
|
||||
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, (void *)PacketToken);
|
||||
return 1;
|
||||
}
|
||||
else if(pPacket->m_DataSize == sizeof(SERVERBROWSE_GETLIST) &&
|
||||
mem_comp(pPacket->m_pData, SERVERBROWSE_GETLIST, sizeof(SERVERBROWSE_GETLIST)) == 0)
|
||||
{
|
||||
if(pPacket->m_Flags&NETSENDFLAG_STATELESS)
|
||||
return -1;
|
||||
IMastersrvSlave::SendList(&pPacket->m_Address, (void *)PacketToken);
|
||||
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, (void *)PacketToken);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
dbg_assert(0, "invalid socket type");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CMastersrvSlave_0_7::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], (TOKEN) (long int) pUserData, NET_PACKETVERSION);
|
||||
|
||||
}
|
||||
|
||||
IMastersrvSlave *CreateSlave_0_7(IMastersrv *pOwner)
|
||||
{
|
||||
return new CMastersrvSlave_0_7(pOwner);
|
||||
}
|
||||
|
Loading…
Reference in a new issue