void OnConfirmation(int playerID, GameConfirmation confirmation) { if (confirmation.LockstepTurn < lockstepTurn) // Discard { return; } if (confirmation.LockstepTurn > lockstepTurn + 2) { Debug.LogError("Lockstep : Confirmation from player " + playerID + " on impossible turn (> 2)"); return; } uint turn = confirmation.LockstepTurn - lockstepTurn; NetworkUI.Log("Receive confirmation from player " + playerID + " for turn " + turn); if (confirmation.Wait) { NetworkUI.Log("Player " + playerID + " want me to wait, i'm too overhead !"); wait[turn][playerID] = WaitingTime; return; } if (!playerHaveConfirmedMyAction[turn][playerID]) { playerHaveConfirmedMyAction[turn][playerID] = true; ++numberOfPlayerWhoConfirmedMyAction[turn]; } else { NetworkUI.Log("Confirmation allready received for LockstepTurn " + confirmation.LockstepTurn); } }
// // Did we receive every client’s action for the next turn ? // Did every client confirm that they received our action ? // bool LockStepTurn() { bool allActionsReceived = numberOfPlayerWhoSendAction[0] == numberOfPlayers; bool allActionsConfirmed = numberOfPlayerWhoConfirmedMyAction[0] == numberOfPlayers; bool readyForTurn = (allActionsReceived && allActionsConfirmed) || lockstepTurn < firstLockstepTurn + 2; if (readyForTurn) { NetworkUI.Log("Ready for turn " + lockstepTurn); SetAction(); // set wantedActions[1] if (lockstepTurn >= firstLockstepTurn + 3) { ProcessActions(); } } else { if (!allActionsReceived) { NetworkUI.Log("Waiting of " + (numberOfPlayers - numberOfPlayerWhoSendAction[0]) + " actions..."); } if (!allActionsConfirmed) { NetworkUI.Log("Waiting of " + (numberOfPlayers - numberOfPlayerWhoConfirmedMyAction[0]) + " confirmations..."); } } SendActionToAll(); // send action to all who haven't confirmed return(readyForTurn); }
void GameFrameTurn() { NetworkUI.ClearLog(); // TEST network ui clear log on game frame turn NetworkUI.Log("LockstepTurn : " + lockstepTurn + " ; gameFrame : " + gameFrame); if (gameFrame == 0) { if (LockStepTurn()) { ++gameFrame; } } else { UpdateGame(); ++gameFrame; if (gameFrame == gameFramesPerLockstepTurn) { gameFrame = 0; NextTurn(); } } // SendActionToAll(); // send action to all who haven't confirmed }
void Update() { eventType = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, buffer, bufferSize, out dataSize, out error); if (error != (byte)NetworkError.Ok) { Debug.LogError("[ERROR] NetworkAPI :: Update :: Receive : " + error); if (dataSize > bufferSize) { Debug.LogError("[ERROR] NetworkAPI :: Update : Message too big for be handled by buffer..."); } return; } if (channelId == channelSetupId) { switch (eventType) { case NetworkEventType.ConnectEvent: NetworkUI.Log("Connection on socket " + recHostId + ", connection : " + connectionId + ", channelId : " + channelId); if (PlayerId == 0) { OnConnection(); } break; // case NetworkEventType.DataEvent: break; case NetworkEventType.DisconnectEvent: Application.Quit(); // TEST quit on disconnect break; } } else if (eventType == NetworkEventType.DataEvent) { if (channelId == channelActionId && OnAction != null) { OnAction(PlayerId == 0 ? 1 : 0, GameActionFactory.Get(buffer)); } else if (channelId == channelConfirmationId && OnConfirmation != null) { OnConfirmation(PlayerId == 0 ? 1 : 0, GameConfirmation.FromBytes(buffer)); } } }
void OnAction(int playerID, GameAction action) { if (action.LockstepTurn > lockstepTurn) { uint turn = action.LockstepTurn - lockstepTurn; NetworkUI.Log("Receive action from player " + playerID + " for turn " + turn); if (turn <= 2 && actions[turn][playerID] == null) { actions[turn][playerID] = action; ++numberOfPlayerWhoSendAction[turn]; } } // Send wait message for stop overloaded network bool wait = action.LockstepTurn > lockstepTurn + 2; NetworkAPI.SendConfirmation(new GameConfirmation(action.LockstepTurn, wait)); }
void SetAction() { if (actionQueue.Count > 0) { GameAction action = actionQueue.Dequeue(); action.LockstepTurn = lockstepTurn + 2; actions[2][NetworkAPI.PlayerId] = action; } else { actions[2][NetworkAPI.PlayerId] = new NoAction(lockstepTurn + 2); } NetworkUI.Log("SetAction " + actions[2][NetworkAPI.PlayerId]); ++numberOfPlayerWhoSendAction[2]; playerHaveConfirmedMyAction[2][NetworkAPI.PlayerId] = true; ++numberOfPlayerWhoConfirmedMyAction[2]; }
void NextTurn() { ++lockstepTurn; // Shift left actions for (int i = 0; i < actions.Length - 1; ++i) { actions[i] = actions[i + 1]; NetworkUI.Log("actions[" + i + "][NetworkAPI.PlayerId] = " + actions[i][NetworkAPI.PlayerId]); NetworkUI.Log("actions[" + (i + 1) + "][NetworkAPI.PlayerId] = " + actions[i + 1][NetworkAPI.PlayerId]); } // Last reset actions[actions.Length - 1] = new GameAction[numberOfPlayers]; // allready set to null // Shift left numberOfPlayerWhoSendAction for (int i = 0; i < numberOfPlayerWhoSendAction.Length - 1; ++i) { numberOfPlayerWhoSendAction[i] = numberOfPlayerWhoSendAction[i + 1]; } // Last reset numberOfPlayerWhoSendAction[numberOfPlayerWhoSendAction.Length - 1] = 0; // Shift left playerHaveConfirmedMyAction for (int i = 0; i < playerHaveConfirmedMyAction.Length - 1; ++i) { playerHaveConfirmedMyAction[i] = playerHaveConfirmedMyAction[i + 1]; } // Last reset playerHaveConfirmedMyAction[playerHaveConfirmedMyAction.Length - 1] = new bool[numberOfPlayers]; // allready set to false // Shift left numberOfPlayerWhoConfirmedMyAction for (int i = 0; i < numberOfPlayerWhoConfirmedMyAction.Length - 1; ++i) { numberOfPlayerWhoConfirmedMyAction[i] = numberOfPlayerWhoConfirmedMyAction[i + 1]; } // Last reset numberOfPlayerWhoConfirmedMyAction[numberOfPlayerWhoConfirmedMyAction.Length - 1] = 0; }
void SendActionToAll() { for (int i = 0; i < actions.Length; ++i) { GameAction action = actions[i][NetworkAPI.PlayerId]; if (action == null) { NetworkUI.Log("action null for turn " + i); continue; } for (int j = 0; j < playerHaveConfirmedMyAction[i].Length; ++j) { if (wait[i][j] > 0) { --wait[i][j]; continue; } if (!playerHaveConfirmedMyAction[i][j]) { if (j == NetworkAPI.PlayerId) { Debug.LogError("Player can't have not confirmed it's action..."); } else { NetworkUI.Log("Send action for turn " + i + " to all..."); NetworkAPI.SendAction(action); // TODO send to a specific player } } else { NetworkUI.Log("Player " + j + " have confirmed my action for turn " + i); } } } }