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;
}
Esempio n. 2
0
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;
}