void CMasterUserServer::OnGBPKT_C2M_QuickGameReq(DWORD peerId, const GBPKT_C2M_QuickGameReq_s& n) { GBPKT_M2C_JoinGameAns_s ans; CServerG* game = gMasterGameServer.GetQuickJoinGame(n.gameMap, (EGBGameRegion)n.region); // in case some region game wasn't available, repeat search without specifying filter if(game == NULL && n.region != GBNET_REGION_Unknown) { CLOG_INDENT; game = gMasterGameServer.GetQuickJoinGame(n.gameMap, GBNET_REGION_Unknown); } if(!game) { ans.result = GBPKT_M2C_JoinGameAns_s::rGameNotFound; net_->SendToPeer(&ans, sizeof(ans), peerId, true); return; } game->AddJoiningPlayer(n.CustomerID); ans.result = GBPKT_M2C_JoinGameAns_s::rOk; ans.ip = game->ip_; ans.port = game->info_.port; ans.sessionId = game->info_.sessionId; net_->SendToPeer(&ans, sizeof(ans), peerId, true); return; }
void CMasterGameServer::OnNetPeerDisconnected(DWORD peerId) { peer_s& peer = peers_[peerId]; switch(peer.status) { case PEER_Free: break; case PEER_Connected: break; case PEER_Validated: break; case PEER_GameServer: { TGamesList::iterator it = games_.find(peerId); // see if game was already closed successfully if(it == games_.end()) break; CServerG* game = it->second; r3dOutToLog("game %s closed unexpectedly\n", game->GetName()); DeleteGame(game); games_.erase(it); break; } case PEER_SuperServer: { TSupersList::iterator it = supers_.find(peerId); if(it == supers_.end()) { break; } CServerS* super = it->second; r3dOutToLog("master: super disconnected '%s'[%d] \n", super->GetName(), super->id_); //TODO? disconnect all games from there. delete super; supers_.erase(it); // supervisor is disconnected, this might be network problem and other supervisors will be disconnecting as well // so we initiate cooldown time to wait for disconnected games, etc, etc if(r3dGetTime() > supersCooldown_) { r3dOutToLog("starting cooldown timer\n"); supersCooldown_ = r3dGetTime() + 60.0f; } break; } } peer.status = PEER_Free; return; }
void CMasterGameServer::OnNetPeerDisconnected(DWORD peerId) { peer_s& peer = peers_[peerId]; switch(peer.status) { case PEER_Free: break; case PEER_Connected: break; case PEER_Validated: break; case PEER_GameServer: { TGamesList::iterator it = games_.find(peerId); // see if game was already closed successfully if(it == games_.end()) break; CServerG* game = it->second; r3dOutToLog("game %s closed unexpectedly\n", game->GetName()); DeleteGame(game); games_.erase(it); break; } case PEER_SuperServer: { TSupersList::iterator it = supers_.find(peerId); if(it == supers_.end()) { break; } CServerS* super = it->second; r3dOutToLog("master: super '%s' disconnected\n", super->GetName()); //TODO? disconnect all games from there. delete super; supers_.erase(it); break; } } peer.status = PEER_Free; 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; }