void GameClient::ExecuteNWF()
{
    // Geschickte Network Commands der Spieler ausführen und ggf. im Replay aufzeichnen

    AsyncChecksum checksum = AsyncChecksum::create(*game);
    const unsigned curGF = GetGFNumber();

    for(const NWFPlayerInfo& player : nwfInfo->getPlayerInfos())
    {
        const PlayerGameCommands& currentGCs = player.commands.front();

        // Command im Replay aufzeichnen (wenn nicht gerade eins schon läuft xD)
        // Nur Commands reinschreiben, KEINE PLATZHALTER (nc_count = 0)
        if(!currentGCs.gcs.empty() && replayinfo && replayinfo->replay.IsRecording())
        {
            // Set the current checksum as the GF checksum. The checksum from the command is from the last NWF!
            PlayerGameCommands replayCmds(checksum, currentGCs.gcs);
            replayinfo->replay.AddGameCommand(curGF, player.id, replayCmds);
        }

        // Das ganze Zeug soll die andere Funktion ausführen
        ExecuteAllGCs(player.id, currentGCs);
    }

    // Send GC message for this NWF
    // First for all potential AIs as we need to combine the AI cmds of the local player with our own ones
    for(AIPlayer& ai : game->aiPlayers_)
    {
        const std::vector<gc::GameCommandPtr> aiGCs = ai.FetchGameCommands();
        /// Cmds from own AI get added to our gcs
        if(ai.GetPlayerId() == GetPlayerId())
            gameCommands_.insert(gameCommands_.end(), aiGCs.begin(), aiGCs.end());
        else
            mainPlayer.sendMsgAsync(new GameMessage_GameCommand(ai.GetPlayerId(), checksum, aiGCs));
    }
    mainPlayer.sendMsgAsync(new GameMessage_GameCommand(0xFF, checksum, gameCommands_));
    gameCommands_.clear();
}
Ejemplo n.º 2
0
void GameClient::ExecuteGameFrame_Replay()
{
    randcheckinfo.rand = RANDOM.GetCurrentRandomValue();
    AsyncChecksum checksum(randcheckinfo.rand);

    const unsigned curGF = GetGFNumber();
    RTTR_Assert(replayinfo.next_gf >= curGF || curGF > replayinfo.replay.lastGF_);

    // Execute all commands from the replay for the current GF
    while(replayinfo.next_gf == curGF)
    {
        // What type of command follows?
        Replay::ReplayCommand rc = replayinfo.replay.ReadRCType();

        if(rc == Replay::RC_CHAT)
        {
            unsigned char player, dest;
            std::string message;
            replayinfo.replay.ReadChatCommand(&player, &dest, message);

            if(ci)
                ci->CI_Chat(player, ChatDestination(dest), message);
        } else if(rc == Replay::RC_GAME)
        {
            std::vector<unsigned char> gcData = replayinfo.replay.ReadGameCommand();
            Serializer ser(&gcData.front(), gcData.size());
            GameMessage_GameCommand msg;
            msg.Deserialize(ser);

            // Execute them
            ExecuteAllGCs(msg);

            // Check for async if checksum data is valid
            if(msg.checksum.randState != 0 &&  msg.checksum != checksum)
            {
                // Show message if this is the first async GF
                if(replayinfo.async == 0)
                {
                    char text[256];
                    sprintf(text, _("Warning: The played replay is not in sync with the original match. (GF: %u)"), curGF);

                    if(ci)
                        ci->CI_ReplayAsync(text);

                    LOG.write("Async at GF %u: Checksum %i:%i ObjCt %u:%u ObjIdCt %u:%u\n") % curGF
                        % msg.checksum.randState % checksum.randState
                        % msg.checksum.objCt % checksum.objCt
                        % msg.checksum.objIdCt % checksum.objIdCt;

                    // and pause the game for further investigation
                    framesinfo.isPaused = true;
                }

                replayinfo.async++;
            }
        }
        // Read GF of next command
        replayinfo.replay.ReadGF(&replayinfo.next_gf);
    }

    // Run game simulation
    NextGF();

    // Check for game end
    if(curGF == replayinfo.replay.lastGF_)
    {
        char text[256];
        sprintf(text, _("Notice: The played replay has ended. (GF: %u, %dh %dmin %ds, TF: %u, AVG_FPS: %u)"), curGF, GAMEMANAGER.GetRuntime() / 3600, ((GAMEMANAGER.GetRuntime()) % 3600) / 60, (GameManager::inst().GetRuntime()) % 3600 % 60, GameManager::inst().GetFrameCount(), GameManager::inst().GetAverageFPS());

        if(ci)
            ci->CI_ReplayEndReached(text);

        if(replayinfo.async != 0)
        {
            char text[256];
            sprintf(text, _("Notice: Overall asynchronous frame count: %u"), replayinfo.async);
            // Messenger im Game
            if(ci)
                ci->CI_ReplayEndReached(text);
        }

        replayinfo.end = true;
        framesinfo.isPaused = true;
    }
}