void NetworkSendRejoinSync (int nPlayer) { int i, j; gameData.multiplayer.players [nPlayer].connected = 1; // connect the new guy ResetPlayerTimeout (nPlayer, -1); if (gameStates.app.bEndLevelSequence || gameData.reactor.bDestroyed) { // Endlevel started before we finished sending the goods, we'll // have to stop and try again after the level. if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer ( networkData.playerRejoining.player.network.ipx.server, networkData.playerRejoining.player.network.ipx.node, DUMP_ENDLEVEL); networkData.nSyncState = 0; networkData.nSyncExtras = 0; return; } if (networkData.bPlayerAdded) { networkData.playerRejoining.nType = PID_ADDPLAYER; networkData.playerRejoining.player.connected = nPlayer; NetworkNewPlayer (&networkData.playerRejoining); for (i = 0; i < gameData.multiplayer.nPlayers; i++) { if ((i != nPlayer) && (i != gameData.multiplayer.nLocalPlayer) && (gameData.multiplayer.players [i].connected)) if (gameStates.multi.nGameType >= IPX_GAME) { SendSequencePacket ( networkData.playerRejoining, netPlayers.players [i].network.ipx.server, netPlayers.players [i].network.ipx.node, gameData.multiplayer.players [i].netAddress); } } } // Send sync packet to the new guy NetworkUpdateNetGame (); // Fill in the kill list for (j = 0; j < MAX_PLAYERS; j++) { for (i = 0; i < MAX_PLAYERS; i++) netGame.kills [j][i] = gameData.multigame.kills.matrix [j][i]; netGame.killed [j] = gameData.multiplayer.players [j].netKilledTotal; netGame.playerKills [j] = gameData.multiplayer.players [j].netKillsTotal; netGame.player_score [j] = gameData.multiplayer.players [j].score; } netGame.xLevelTime = LOCALPLAYER.timeLevel; netGame.monitor_vector = NetworkCreateMonitorVector (); if (gameStates.multi.nGameType >= IPX_GAME) { SendInternetFullNetGamePacket ( networkData.playerRejoining.player.network.ipx.server, networkData.playerRejoining.player.network.ipx.node); SendNetPlayersPacket ( networkData.playerRejoining.player.network.ipx.server, networkData.playerRejoining.player.network.ipx.node); } return; }
int KickPlayer (int bBan) { int i, name_index = 5 - bBan; const char *pszKick = GT (589 + bBan); if (strlen (gameData.multigame.msg.szMsg) > 5) while (gameData.multigame.msg.szMsg [name_index] == ' ') name_index++; if (!NetworkIAmMaster ()) { HUDInitMessage (TXT_KICK_RIGHTS, gameData.multiplayer.players [NetworkWhoIsMaster ()].callsign, pszKick); MultiSendMsgQuit (); return 1; } if (strlen (gameData.multigame.msg.szMsg) <= (size_t) name_index) { HUDInitMessage (TXT_KICK_NAME, pszKick); MultiSendMsgQuit (); return 1; } if (gameData.multigame.msg.szMsg [name_index] == '#' && ::isdigit (gameData.multigame.msg.szMsg [name_index+1])) { int players [MAX_PLAYERS]; int listpos = gameData.multigame.msg.szMsg [name_index+1] - '0'; if (gameData.multigame.kills.bShowList == 1 || gameData.multigame.kills.bShowList == 2) { if (listpos == 0 || listpos >= gameData.multiplayer.nPlayers) { HUDInitMessage (TXT_KICK_PLR, pszKick); MultiSendMsgQuit (); return 1; } MultiGetKillList (players); i = players [listpos]; if ((i != gameData.multiplayer.nLocalPlayer) && (gameData.multiplayer.players [i].connected)) goto kick_player; } else HUDInitMessage (TXT_KICK_NUMBER, pszKick); MultiSendMsgQuit (); return 1; } for (i = 0; i < gameData.multiplayer.nPlayers; i++) if ((!strnicmp (gameData.multiplayer.players [i].callsign, &gameData.multigame.msg.szMsg [name_index], strlen (gameData.multigame.msg.szMsg)-name_index)) && (i != gameData.multiplayer.nLocalPlayer) && (gameData.multiplayer.players [i].connected)) { kick_player:; if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer ( netPlayers.m_info.players [i].network.ipx.server, netPlayers.m_info.players [i].network.ipx.node, 7); HUDInitMessage (TXT_DUMPING, gameData.multiplayer.players [i].callsign); if (bBan) banList.Add (gameData.multiplayer.players [i].callsign); MultiSendMsgQuit (); return 1; } return 0; }
static tNetworkSyncData *AcceptJoinRequest (tSequencePacket *player) { // Don't accept new players if we're ending this level. Its safe to // ignore since they'll request again later if (gameStates.app.bEndLevelSequence || gameData.reactor.bDestroyed) { #if 1 con_printf (CONDBG, "Ignored request from new tPlayer to join during endgame.\n"); #endif if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer ( player->player.network.ipx.server, player->player.network.ipx.node, DUMP_ENDLEVEL); return NULL; } if (player->player.connected != gameData.missions.nCurrentLevel) { #if 1 con_printf (CONDBG, "Dumping tPlayer due to old level number.\n"); #endif if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer ( player->player.network.ipx.server, player->player.network.ipx.node, DUMP_LEVEL); return NULL; } tNetworkSyncData *syncP; short nConnection = FindJoiningPlayer (player); if (nConnection < 0) { if (networkData.nJoining == MAX_JOIN_REQUESTS) return NULL; syncP = networkData.sync + networkData.nJoining++; } else { //prevent flooding with connection attempts from the same player syncP = networkData.sync + nConnection; if (gameStates.app.nSDLTicks - syncP->tLastJoined < 2100) return NULL; syncP->tLastJoined = gameStates.app.nSDLTicks; } return syncP; }
void NetworkSendRejoinSync (int nPlayer, tNetworkSyncData *syncP) { int i, j; gameData.multiplayer.players [nPlayer].connected = 1; // connect the new guy ResetPlayerTimeout (nPlayer, -1); if (gameStates.app.bEndLevelSequence || gameData.reactor.bDestroyed) { // Endlevel started before we finished sending the goods, we'll // have to stop and try again after the level. if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer ( syncP->player [1].player.network.ipx.server, syncP->player [1].player.network.ipx.node, DUMP_ENDLEVEL); syncP->nState = 0; syncP->nExtras = 0; return; } if (networkData.bPlayerAdded) { syncP->player [1].nType = PID_ADDPLAYER; syncP->player [1].player.connected = nPlayer; NetworkNewPlayer (&syncP->player [1]); for (i = 0; i < gameData.multiplayer.nPlayers; i++) { if ((i != nPlayer) && (i != gameData.multiplayer.nLocalPlayer) && gameData.multiplayer.players [i].connected && (gameStates.multi.nGameType >= IPX_GAME)) { SendSequencePacket ( syncP->player [1], netPlayers.m_info.players [i].network.ipx.server, netPlayers.m_info.players [i].network.ipx.node, gameData.multiplayer.players [i].netAddress); } } } // Send sync packet to the new guy NetworkUpdateNetGame (); // Fill in the kill list for (j = 0; j < MAX_PLAYERS; j++) { for (i = 0; i < MAX_PLAYERS; i++) *netGame.Kills (j, i) = gameData.multigame.kills.matrix [j][i]; *netGame.Killed (j) = gameData.multiplayer.players [j].netKilledTotal; *netGame.PlayerKills (j) = gameData.multiplayer.players [j].netKillsTotal; *netGame.PlayerScore (j) = gameData.multiplayer.players [j].score; } netGame.SetLevelTime (LOCALPLAYER.timeLevel); netGame.SetMonitorVector (NetworkCreateMonitorVector ()); if (gameStates.multi.nGameType >= IPX_GAME) { SendInternetFullNetGamePacket (syncP->player [1].player.network.ipx.server, syncP->player [1].player.network.ipx.node); SendNetPlayersPacket (syncP->player [1].player.network.ipx.server, syncP->player [1].player.network.ipx.node); MultiSendMonsterball (1, 1); } }
static int FindPlayerSlot (tSequencePacket *player) { if (netGame.gameFlags & NETGAME_FLAG_CLOSED) { // Slots are open but game is closed if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer ( player->player.network.ipx.server, player->player.network.ipx.node, DUMP_CLOSED); return -1; } if (gameData.multiplayer.nPlayers < gameData.multiplayer.nMaxPlayers) { // Add tPlayer in an open slot, game not full yet networkData.bPlayerAdded = 1; return gameData.multiplayer.nPlayers; } // Slots are full but game is open, see if anyone is // disconnected and replace the oldest tPlayer with this new one int oldestPlayer = -1; fix oldestTime = TimerGetApproxSeconds (); Assert (gameData.multiplayer.nPlayers == gameData.multiplayer.nMaxPlayers); for (int i = 0; i < gameData.multiplayer.nPlayers; i++) { if (!gameData.multiplayer.players [i].connected && (networkData.nLastPacketTime [i] < oldestTime)) { oldestTime = networkData.nLastPacketTime [i]; oldestPlayer = i; } } if (oldestPlayer == -1) { // Everyone is still connected if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer ( player->player.network.ipx.server, player->player.network.ipx.node, DUMP_FULL); return -1; } networkData.bPlayerAdded = 1; return oldestPlayer; }
void NetworkWaitForRequests (void) { // Wait for other players to load the level before we send the sync int choice, i; tMenuItem m [1]; networkData.nStatus = NETSTAT_WAITING; memset (m, 0, sizeof (m)); m [0].nType= NM_TYPE_TEXT; m [0].text = (char *) TXT_NET_LEAVE; NetworkFlush (); LOCALPLAYER.connected = 1; do_menu: choice = ExecMenu (NULL, TXT_WAIT, 1, m, NetworkRequestPoll, NULL); if (choice == -1) { // User aborted choice = ExecMessageBox (NULL, NULL, 3, TXT_YES, TXT_NO, TXT_START_NOWAIT, TXT_QUITTING_NOW); if (choice == 2) return; if (choice != 0) goto do_menu; // User confirmed abort for (i = 0; i < gameData.multiplayer.nPlayers; i++) { if ((gameData.multiplayer.players [i].connected != 0) && (i != gameData.multiplayer.nLocalPlayer)) { if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer (netPlayers.players [i].network.ipx.server, netPlayers.players [i].network.ipx.node, DUMP_ABORTED); } } longjmp (gameExitPoint, 0); } else if (choice != -2) goto do_menu; }
void DoRefuseStuff (tSequencePacket *their) { int i, nNewPlayer; static tTextIndex joinMsgIndex; static char szJoinMsg [200]; ClipRank ((char *) &their->player.rank); for (i = 0; i < MAX_PLAYERS; i++) if (!strcmp (their->player.callsign, gameData.multiplayer.players [i].callsign)) { NetworkWelcomePlayer (their); return; } if (FindPlayerInBanList (their->player.callsign)) return; if (!networkData.refuse.bWaitForAnswer) { DigiPlaySample (SOUND_HUD_JOIN_REQUEST, F1_0*2); #if 0 if (IsTeamGame) { if (gameOpts->multi.bNoRankings) HUDInitMessage ("%s joining", their->player.callsign); else HUDInitMessage ("%s %s wants to join", pszRankStrings [their->player.rank], their->player.callsign); HUDInitMessage ("Alt-1 assigns to team %s. Alt-2 to team %s", their->player.callsign, netGame.szTeamName [0], netGame.szTeamName [1]); } else HUDInitMessage (TXT_JOIN_ACCEPT, their->player.callsign); #else if (IsTeamGame) { char szRank [20]; if (gameOpts->multi.bNoRankings) *szRank = '\0'; else sprintf (szRank, "%s ", pszRankStrings [their->player.rank]); sprintf (szJoinMsg, " \n %s%s wants to join. \n Alt-1 assigns to team %s. \n Alt-2 to team %s. \n ", szRank, their->player.callsign, netGame.szTeamName [0], netGame.szTeamName [1]); joinMsgIndex.nLines = 5; } else { sprintf (szJoinMsg, " \n %s wants to join. \n Press F6 to accept. \n ", their->player.callsign); joinMsgIndex.nLines = 4; } joinMsgIndex.pszText = szJoinMsg; joinMsgIndex.nId = 1; gameData.messages [1].nMessages = 1; gameData.messages [1].index = gameData.messages [1].currentMsg = &joinMsgIndex; gameData.messages [1].nStartTime = gameStates.app.nSDLTicks; gameData.messages [1].nEndTime = gameStates.app.nSDLTicks + 5000; gameData.messages [1].textBuffer = NULL; gameData.messages [1].bmP = NULL; #endif strcpy (networkData.refuse.szPlayer, their->player.callsign); networkData.refuse.xTimeLimit = TimerGetApproxSeconds (); networkData.refuse.bThisPlayer = 0; networkData.refuse.bWaitForAnswer = 1; } else { if (strcmp (their->player.callsign, networkData.refuse.szPlayer)) return; if (networkData.refuse.bThisPlayer) { networkData.refuse.xTimeLimit = 0; networkData.refuse.bThisPlayer = 0; networkData.refuse.bWaitForAnswer = 0; if (IsTeamGame) { nNewPlayer = GetNewPlayerNumber (their); Assert (networkData.refuse.bTeam == 1 || networkData.refuse.bTeam == 2); if (networkData.refuse.bTeam == 1) netGame.teamVector &= ~(1 << nNewPlayer); else netGame.teamVector |= (1 << nNewPlayer); NetworkWelcomePlayer (their); NetworkSendNetgameUpdate (); } else NetworkWelcomePlayer (their); return; } if ((TimerGetApproxSeconds ()) > networkData.refuse.xTimeLimit + REFUSE_INTERVAL) { networkData.refuse.xTimeLimit = 0; networkData.refuse.bThisPlayer = 0; networkData.refuse.bWaitForAnswer = 0; if (!strcmp (their->player.callsign, networkData.refuse.szPlayer)) { if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer ( their->player.network.ipx.server, their->player.network.ipx.node, DUMP_DORK); } return; } } }
void NetworkWelcomePlayer (tSequencePacket *player) { int nPlayer; ubyte newAddress [6]; tNetworkSyncData *syncP; networkData.refuse.bWaitForAnswer = 0; if (FindArg ("-NoMatrixCheat")) { if ((player->player.versionMinor & 0x0F) < 3) { NetworkDumpPlayer ( player->player.network.ipx.server, player->player.network.ipx.node, DUMP_DORK); return; } } if (HoardEquipped ()) { // If hoard game, and this guy isn't D2 Christmas (v1.2), dump him if ((gameData.app.nGameMode & GM_HOARD) && ((player->player.versionMinor & 0x0F) < 2)) { if (gameStates.multi.nGameType >= IPX_GAME) NetworkDumpPlayer ( player->player.network.ipx.server, player->player.network.ipx.node, DUMP_DORK); return; } } if (!(syncP = AcceptJoinRequest (player))) return; memset (&syncP->player [1], 0, sizeof (tSequencePacket)); networkData.bPlayerAdded = 0; if (gameStates.multi.nGameType >= IPX_GAME) { if ((*(uint *) player->player.network.ipx.server) != 0) IpxGetLocalTarget ( player->player.network.ipx.server, player->player.network.ipx.node, newAddress); else memcpy (newAddress, player->player.network.ipx.node, 6); } if (0 > (nPlayer = FindNetworkPlayer (player, newAddress))) { // Player is new to this game if (0 > (nPlayer = FindPlayerSlot (player))) { DeleteSyncData (syncP - networkData.sync); return; } } else { // Player is reconnecting if (gameData.demo.nState == ND_STATE_RECORDING) NDRecordMultiReconnect (nPlayer); networkData.bPlayerAdded = 0; DigiPlaySample (SOUND_HUD_MESSAGE, F1_0); if (gameOpts->multi.bNoRankings) HUDInitMessage ("'%s' %s", gameData.multiplayer.players [nPlayer].callsign, TXT_REJOIN); else HUDInitMessage ("%s'%s' %s", pszRankStrings [netPlayers.players [nPlayer].rank], gameData.multiplayer.players [nPlayer].callsign, TXT_REJOIN); } if (IsTeamGame) ChoseTeam (nPlayer); gameData.multiplayer.players [nPlayer].nKillGoalCount = 0; gameData.multiplayer.players [nPlayer].connected = 0; // Send updated OBJECTS data to the new/returning tPlayer syncP->player [0] = *player; syncP->player [1] = *player; syncP->player [1].player.connected = nPlayer; syncP->bExtraGameInfo = 0; syncP->nState = 1; syncP->objs.nCurrent = -1; syncP->nExtras = 0; syncP->timeout = 0; syncP->tLastJoined = gameStates.app.nSDLTicks; NetworkDoSyncFrame (); }