void CMasterGameServer::Start(int port, int in_serverId) { SetConsoleTitle("WO::Master"); masterServerId_ = in_serverId; r3d_assert(masterServerId_ > 0 && masterServerId_ < 255); #if 1 // PAX_BUILD DoFirstItemsDbUpdate(); #endif DoFirstUpdateCGK(); serverNet.Initialize(this, "serverNet"); if(!serverNet.CreateHost(port, MAX_PEERS_COUNT)) { r3dError("CreateHost failed\n"); } r3dOutToLog("MasterGameServer started at port %d\n", port); nextLogTime_ = r3dGetTime(); #if 0 // register local temp supervisor { r3dOutToLog("@@@ registering local temp supervisor\n"); SBPKT_S2M_RegisterMachine_s n; n.maxGames = 32; n.maxPlayers = n.maxGames * 32; n.serverGroup = 0; r3dscpy(n.serverName, "arktos01"); n.portStart = SBNET_GAME_PORT; DWORD id = curSuperId_++; CServerS* super = new CServerS(id, 0x1, 0); super->Init(n); supers_.insert(TSupersList::value_type(0x12345, super)); } #endif //@ShellExecute(NULL, "open", "SupervisorServer.exe", "", "", SW_SHOW); return; }
void CMasterGameServer::OnNetData(DWORD peerId, const r3dNetPacketHeader* PacketData, int PacketSize) { if(PacketSize < sizeof(r3dNetPacketHeader)) { DisconnectCheatPeer(peerId, "too small packet"); return; } // wait for validating packet if(!DoValidatePeer(peerId, PacketData, PacketSize)) return; peer_s& peer = peers_[peerId]; r3d_assert(peer.status >= PEER_Validated); switch(PacketData->EventID) { default: r3dOutToLog("CMasterGameServer: invalid packetId %d", PacketData->EventID); DisconnectCheatPeer(peerId, "wrong packet id"); return; case SBPKT_S2M_RegisterMachine: { const SBPKT_S2M_RegisterMachine_s& n = *(SBPKT_S2M_RegisterMachine_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); r3d_assert(supers_.find(peerId) == supers_.end()); DWORD ip = net_->GetPeerIp(peerId); DWORD id = curSuperId_++; // check if that super is already connected or wasn't disconnected yet for(TSupersList::iterator it = supers_.begin(); it != supers_.end(); ++it) { CServerS* super = it->second; if((super->ip_ == ip || super->ip_ == n.externalIpAddr) && strcmp(super->GetName(), n.serverName) == 0) { r3dOutToLog("master: DUPLICATE super registered '%s' ip:%s\n", n.serverName, inet_ntoa(*(in_addr*)&ip)); net_->DisconnectPeer(peerId); return; } } CServerS* super = new CServerS(id, ip, peerId); super->Init(n); supers_.insert(TSupersList::value_type(peerId, super)); r3d_assert(peer.status == PEER_Validated); peer.status = PEER_SuperServer; // send registration answer { SBPKT_M2S_RegisterAns_s n; n.id = id; net_->SendToPeer(&n, sizeof(n), peerId); } /*if (n.region == GBNET_REGION_US_West) { r3dOutToLog("super private zone registered Create RentServer now...\n"); //gServerConfig->LoadRentConfig(); }*/ break; } case SBPKT_M2G_SendPlayerListEnd: { const SBPKT_M2G_SendPlayerListEnd_s& n = *(SBPKT_M2G_SendPlayerListEnd_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); //r3dOutToLog("SBPKT_M2G_SendPlayerListEnd\n"); gMasterUserServer.SendPlayerListEnd(n.ClientPeerId); break; } case SBPKT_M2G_SendPlayerList: { const SBPKT_M2G_SendPlayerList_s& n = *(SBPKT_M2G_SendPlayerList_s*)PacketData; //r3dOutToLog("SBPKT_M2G_SendPlayerList\n"); //r3d_assert(sizeof(n) == PacketSize); gMasterUserServer.SendPlayerList(n.ClientPeerId,n.alive,n.gamertag,n.rep,n.xp); break; } case SBPKT_G2M_SendScreenShot: { break; } case SBPKT_G2M_ScreenShotData: { const SBPKT_G2M_ScreenShotData_s& n = *(SBPKT_G2M_ScreenShotData_s*)PacketData; //r3dOutToLog("Received SS %s\n",n.fname); extern bool isEnabledSS; if (!isEnabledSS) break; _mkdir("SSAH"); FILE* f = fopen(n.fname, "wb"); if(f == NULL) { r3dOutToLog( "SaveScreenshot unable to save fname:%s", n.fname); return; } fwrite((char*)PacketData + sizeof(n), 1, n.size, f); fclose(f); break; } case SBPKT_G2M_SendNoticeMsg: { const SBPKT_G2M_SendNoticeMsg_s& n = *(SBPKT_G2M_SendNoticeMsg_s*)PacketData; r3dOutToLog("Received notice message from peer%d '%s'\n",peerId,n.msg); //r3dOutToLog("Brostcast to all servers.\n"); // scans servers. int numgames = 0; for(CMasterGameServer::TSupersList::const_iterator it = gMasterGameServer.supers_.begin(); it != gMasterGameServer.supers_.end(); ++it) { const CServerS* super = it->second; numgames += super->GetExpectedGames(); for(int i=0; i<super->maxGames_; i++) { const CServerG* game = super->games_[i].game; if(!game) continue; // resend this packet to all servers. net_->SendToPeer(&n, sizeof(n), game->peer_, true); } } r3dOutToLog("Send notice packet to %d servers\n",numgames); break; } case SBPKT_G2M_RegisterGame: { const SBPKT_G2M_RegisterGame_s& n = *(SBPKT_G2M_RegisterGame_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); r3d_assert(peer.status == PEER_Validated); r3dOutToLog("game 0x%x connected\n", n.gameId); // register this game in supervisor CServerS* super = GetServerByGameId(n.gameId); if(super == NULL) { // this might happen when supervisor crashed between game start & registration r3dOutToLog("game 0x%x without supervisor\n", n.gameId); SBPKT_M2G_KillGame_s n1; net_->SendToPeer(&n1, sizeof(n1), peerId); net_->DisconnectPeer(peerId); break; } CServerG* game = super->CreateGame(n.gameId, peerId); r3d_assert(game); games_.insert(TGamesList::value_type(peerId, game)); r3d_assert(peer.status == PEER_Validated); peer.status = PEER_GameServer; #if ENABLED_SERVER_WEAPONARMORY SendArmoryInfoToGame(game); #endif break; } case SBPKT_G2M_AddPlayer: { const SBPKT_G2M_AddPlayer_s& n = *(SBPKT_G2M_AddPlayer_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); TGamesList::iterator it = games_.find(peerId); r3d_assert(it != games_.end()); CServerG* game = it->second; game->AddPlayer(n.CustomerID); break; } case SBPKT_G2M_RemovePlayer: { const SBPKT_G2M_RemovePlayer_s& n = *(SBPKT_G2M_RemovePlayer_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); TGamesList::iterator it = games_.find(peerId); r3d_assert(it != games_.end()); CServerG* game = it->second; game->RemovePlayer(n.CustomerID); break; } case SBPKT_G2M_FinishGame: { const SBPKT_G2M_FinishGame_s& n = *(SBPKT_G2M_FinishGame_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); TGamesList::iterator it = games_.find(peerId); r3d_assert(it != games_.end()); CServerG* game = it->second; r3dOutToLog("game %s finished\n", game->GetName()); game->finished_ = true; break; } case SBPKT_G2M_CloseGame: { const SBPKT_G2M_CloseGame_s& n = *(SBPKT_G2M_CloseGame_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); TGamesList::iterator it = games_.find(peerId); r3d_assert(it != games_.end()); CServerG* game = it->second; r3dOutToLog("game %s closed\n", game->GetName()); DeleteGame(game); games_.erase(it); break; } case SBPKT_G2M_DataUpdateReq: { const SBPKT_G2M_DataUpdateReq_s& n = *(SBPKT_G2M_DataUpdateReq_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); r3dOutToLog("got SBPKT_G2M_DataUpdateReq\n"); #if ENABLED_SERVER_WEAPONARMORY StartItemsDbUpdate(true); #endif break; } } return; }
void CMasterGameServer::OnNetData(DWORD peerId, const r3dNetPacketHeader* PacketData, int PacketSize) { if(PacketSize < sizeof(r3dNetPacketHeader)) { DisconnectCheatPeer(peerId, "too small packet"); return; } // wait for validating packet if(!DoValidatePeer(peerId, PacketData, PacketSize)) return; peer_s& peer = peers_[peerId]; r3d_assert(peer.status >= PEER_Validated); switch(PacketData->EventID) { default: r3dOutToLog("CMasterGameServer: invalid packetId %d", PacketData->EventID); DisconnectCheatPeer(peerId, "wrong packet id"); return; case SBPKT_S2M_RegisterMachine: { const SBPKT_S2M_RegisterMachine_s& n = *(SBPKT_S2M_RegisterMachine_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); r3d_assert(supers_.find(peerId) == supers_.end()); DWORD ip = net_->GetPeerIp(peerId); DWORD id = curSuperId_++; CServerS* super = new CServerS(id, ip, peerId); super->Init(n); supers_.insert(TSupersList::value_type(peerId, super)); r3d_assert(peer.status == PEER_Validated); peer.status = PEER_SuperServer; // send registration answer { SBPKT_M2S_RegisterAns_s n; n.id = id; net_->SendToPeer(&n, sizeof(n), peerId); } break; } case SBPKT_G2M_RegisterGame: { const SBPKT_G2M_RegisterGame_s& n = *(SBPKT_G2M_RegisterGame_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); r3d_assert(peer.status == PEER_Validated); r3dOutToLog("game 0x%x connected\n", n.gameId); // register this game in supervisor CServerS* super = GetServerByGameId(n.gameId); if(super == NULL) { // this might happen when supervisor crashed between game start & registration r3dOutToLog("game 0x%x without supervisor\n", n.gameId); SBPKT_M2G_KillGame_s n1; net_->SendToPeer(&n1, sizeof(n1), peerId); net_->DisconnectPeer(peerId); break; } CServerG* game = super->CreateGame(n.gameId, peerId); r3d_assert(game); games_.insert(TGamesList::value_type(peerId, game)); r3d_assert(peer.status == PEER_Validated); peer.status = PEER_GameServer; #if 1 // PAX_BUILD SendArmoryInfoToGame(game); #endif break; } case SBPKT_G2M_UpdateGame: { const SBPKT_G2M_UpdateGame_s& n = *(SBPKT_G2M_UpdateGame_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); TGamesList::iterator it = games_.find(peerId); r3d_assert(it != games_.end()); CServerG* game = it->second; game->SetCurrentData(n.timeLeft, n.curPlayers, n.uinfo); break; } case SBPKT_G2M_FinishGame: { const SBPKT_G2M_FinishGame_s& n = *(SBPKT_G2M_FinishGame_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); TGamesList::iterator it = games_.find(peerId); r3d_assert(it != games_.end()); CServerG* game = it->second; r3dOutToLog("game %s finished\n", game->GetName()); game->finished_ = true; break; } case SBPKT_G2M_CloseGame: { const SBPKT_G2M_CloseGame_s& n = *(SBPKT_G2M_CloseGame_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); TGamesList::iterator it = games_.find(peerId); r3d_assert(it != games_.end()); CServerG* game = it->second; r3dOutToLog("game %s closed\n", game->GetName()); DeleteGame(game); games_.erase(it); break; } case SBPKT_G2M_DataUpdateReq: { const SBPKT_G2M_DataUpdateReq_s& n = *(SBPKT_G2M_DataUpdateReq_s*)PacketData; r3d_assert(sizeof(n) == PacketSize); r3dOutToLog("got SBPKT_G2M_DataUpdateReq\n"); StartItemsDbUpdate(true); break; } } return; }