static void UpdatePlayerStatus(UdpClient client, uint pid, PlayerStatus status) { NetWerewolfPlayer ap = ConnectedPlayers.Find(p => p.PlayerID == pid); ap.Status = status; UpdatePlayerList.Invoke(pid, status == PlayerStatus.Dead); }
public static void ClientDisconnectedEventHandler(UdpClient client) { NetWerewolfPlayer player = client.GetPlayer(); player.Status = PlayerStatus.Dead; ServerInstance.Send(2, player.PlayerID); // RemoteClientDisconnected(uint) ServerInstance.Send(5, 0u, $"{player.Name} has fallen..."); try { ConnectedPlayers.Remove(player); GameInfo.Players.Remove(player); } catch { } try { NetWerewolfPlayer nextHost = ConnectedPlayers.First(); if (nextHost != null && !nextHost.IsHost) { nextHost.IsHost = true; nextHost.PlayerClient.Send(199, true); ServerInstance.Send(5, 0, $"{nextHost.Name} is now the game master."); } } catch { } // No players left to be host }
public void AddPlayerToList(NetWerewolfPlayer player, bool localPlayer) { InvokerObj.Invoke(() => { LobbyPlayerPanelHelper newPlayer = Instantiate(LobbyPlayerPrefab, PlayerListContent); newPlayer.SetupText(player, localPlayer); playerPanels.Add(newPlayer); }); }
public void SetupText(NetWerewolfPlayer player, bool localPlayer) { PlayerID = player.PlayerID; Player = player; PlayerNameText.text = $"[{PlayerID}] {player.Name}"; if (localPlayer) { PlayerNameText.color = Color.yellow; } }
public static bool InitializeClientInstance(IPAddress ip, int port) { if (udpSv == null) { players = new List <NetWerewolfPlayer>(); } udpCl = new UdpClient(SharedSecret); LocalPlayer = new NetWerewolfPlayer(udpCl, PlayerSettings.Instance.PlayerName); udpCl.AddNetEventsFromAssembly(Assembly.GetExecutingAssembly(), ClientEventGroup); udpCl.ClientDisconnected += ClientNetEvents.ClientDisconnectedEventHandler; return(udpCl.VerifyAndListen(ip, port)); }
static void VerifyRoleHashesAndSendClientList(UdpClient sender, string playerName, string[] roleHashes) { // TODO: verify the role hashes if (roleHashes.Length < LoadedRoleHashes.Count) { NetBase.WriteDebug($"Received role hash list from {sender.EndPoint as IPEndPoint} \"{playerName}\" has less roles than the server, impossible to verify roles."); ConnectedPlayers.Remove(sender.GetPlayer()); sender.Disconnect(); return; } for (int i = 0; i < LoadedRoleHashes.Count; ++i) { string hash = LoadedRoleHashes[i]; if (!roleHashes.Contains(hash)) { NetBase.WriteDebug($"Client {sender.EndPoint as IPEndPoint} \"{playerName}\" missing hash {hash} corresponding to role {LoadedRoleTypes.Values.ElementAt(i).AssemblyQualifiedName}!"); ConnectedPlayers.Remove(sender.GetPlayer()); sender.Disconnect(); return; } else { NetBase.WriteDebug($"{sender.EndPoint as IPEndPoint}: {hash} {LoadedRoleTypes.Values.ElementAt(i).AssemblyQualifiedName} success!"); } } NetWerewolfPlayer playerRef = sender.GetPlayer(); playerRef.Name = playerName; playerRef.RoleListVerified = true; GameInfo.AddPlayerAndAssignId(playerRef); ServerInstance.Send(5, 0u, GenRandomJoinMessage(playerName)); if (GameInfo.Players.Count == 1) { playerRef.IsHost = true; sender.Send(199, true); //SetHost(UdpClient, bool) ServerInstance.Send(5, 0u, $"{playerRef.Name} is now the game master."); } sender.Send(200, playerRef.PlayerID, ConnectedPlayers.Select(p => p.PlayerID).ToArray(), ConnectedPlayers.Select(p => p.Name).ToArray()); // ReceivePlayerList(uint, uint[], string[]); foreach (string hash in ActiveRoleHashes) { sender.Send(190, hash, false); } ServerInstance.Send(1, playerRef.PlayerID, playerRef.Name); // UpdateClientInfo(uint, string) }
public static NetWerewolfPlayer GetPlayer(this UdpClient client) { for (int i = 0; i < ConnectedPlayers.Count; ++i) { NetWerewolfPlayer p = ConnectedPlayers[i]; if (p.PlayerClient != null) { if (p.PlayerClient.EndPoint.Equals(client.EndPoint)) { return(p); } } } return(null); }
static void UpdateClientInfo(UdpClient client, uint pid, string name) { NetWerewolfPlayer player = ConnectedPlayers.FirstOrDefault(p => p.PlayerID == pid); if ((player == null) || (player.PlayerID != LocalPlayer.PlayerID)) { player = new NetWerewolfPlayer(pid, name); if (ServerInstance == null) { ConnectedPlayers.Add(player); } UpdatePlayerList.Invoke(player.PlayerID, false); } else { player.Name = name; } }
static void BroadcastChatMessage(UdpClient sender, string message) { NetWerewolfPlayer p = sender.GetPlayer(); if (p != null) { double secondsSinceLast = (DateTime.Now - p.LastMessageTime).TotalSeconds; if (secondsSinceLast >= 3.5) { ServerInstance.Send(5, p.PlayerID, message); // ReceivedChatMessage(uint, string) p.LastMessageTime = DateTime.Now; } else { sender.Send(5, 0, $"Please wait another {Math.Round(3.5 - secondsSinceLast, 1)} seconds before sending another message."); // ReceivedChatMessage(uint, string) } } }
static void ReceivePlayerList(UdpClient client, uint myPID, uint[] playerIDs, string[] playerNames) { LocalPlayer.PlayerID = myPID; for (int i = 0; i < playerIDs.Length; ++i) { bool isLocalPlayer = LocalPlayer.PlayerID == playerIDs[i]; NetWerewolfPlayer netPlayer = isLocalPlayer ? LocalPlayer : new NetWerewolfPlayer(playerIDs[i], playerNames[i]); if (isLocalPlayer) { LocalPlayer.Name = playerNames[i]; } if (ServerInstance == null) { ConnectedPlayers.Add(netPlayer); } UpdatePlayerList.Invoke(netPlayer.PlayerID, false); } }
public void WriteChatMessage(NetWerewolfPlayer player, string message) { InvokerObj.Invoke(() => { float oldPos = ChatScrollView.normalizedPosition.y; if (player != null) { ChatTextField.text += $"[{player.PlayerID}] {player.Name}: {message}{Environment.NewLine}"; } else { ChatTextField.text += $"SYSTEM: {message}{Environment.NewLine}"; } LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)ChatScrollView.transform); if (oldPos <= 0.0001f) { ChatScrollView.normalizedPosition = Vector2.zero; } }); }
public static async Task NetGameLoop() { CurrentGameState = GameState.Discussion; CurrentDay = 0; StateTime = 25; StateChanged = true; PlayerOnTrial = null; while (true) { if (StateChanged) { foreach (NetWerewolfPlayer p in ConnectedPlayers) { p.TrialTargetPID = 0u; p.TrialVotes = 0; p.VotedForKill = false; } switch (CurrentGameState) { case GameState.Discussion: ServerInstance.Send(5, 0u, "Discussion has begun."); break; case GameState.Night: ServerInstance.Send(5, 0u, "The sun has retreated as the moon rises..."); break; case GameState.Dawn: List <NetWerewolfPlayer> affectedPlayers = GameInfo.ResolveNightEvents().ConvertAll(p => p as NetWerewolfPlayer); affectedPlayers.ForEach(p => { ServerInstance.Send(50, p.PlayerID, p.Status); // UpdatePlayerStatus(UdpClient, uint, PlayerStatus) ServerInstance.Send(5, 0u, $"{p.Name} is {p.Status}!{(p.Status == PlayerStatus.Dead ? $" Their role was {p.Role.Name}" : "")}"); }); break; case GameState.Trial: if (PlayerOnTrial != null) { ServerInstance.Send(5, 0u, $"The town has decided to trial {PlayerOnTrial.Name}! Select their name to vote them guilty."); } else { StateTime = 0; } break; case GameState.End: ServerInstance.Send(5, 0u, $"The following players have won: {string.Join(", ", ConnectedPlayers.Where(p => WinningAlignments.Contains(p.Role.Alignment)).Select(p => p.Name))}"); break; } } StateChanged = false; await Task.Delay(1000); StateTime--; if (StateTime < 0) { switch (CurrentGameState) { case GameState.Discussion: CurrentGameState = GameState.Night; StateTime = 15; break; case GameState.Night: CurrentGameState = GameState.Dawn; StateTime = 10; CurrentDay++; break; case GameState.Dawn: (bool End, IRoleAlignment[] WinList)result = GameInfo.CheckIfWinConditionMet(); if (result.End) { WinningAlignments = result.WinList; CurrentGameState = GameState.End; StateTime = 20; break; } CurrentGameState = GameState.Discussion; StateTime = 120; break; case GameState.Trial: // TODO: Straight to night if voted out if (PlayerOnTrial != null && PlayerOnTrial.Status != PlayerStatus.Dead) { int votes = players.Count(p => p.VotedForKill); int voters = players.Count(p => p.PlayerID != PlayerOnTrial.PlayerID && p.Status == PlayerStatus.Alive); if (votes >= Mathf.CeilToInt(voters / 2.0f)) { PlayerOnTrial.Status = PlayerStatus.Dead; ServerInstance.Send(50, PlayerOnTrial.PlayerID, PlayerOnTrial.Status); // UpdatePlayerStatus(uint, PlayerStatus) ServerInstance.Send(5, 0u, $"The town has decided to execute {PlayerOnTrial.Name}! They were a {PlayerOnTrial.Role.Name}!"); (bool End, IRoleAlignment[] WinList)trialResult = GameInfo.CheckIfWinConditionMet(); if (trialResult.End) { WinningAlignments = trialResult.WinList; CurrentGameState = GameState.End; StateTime = 20; break; } CurrentGameState = GameState.Night; StateTime = 15; break; } } CurrentGameState = GameState.Discussion; StateTime = 50; break; case GameState.End: // TODO: Reset the lobby ConnectedPlayers.ForEach(p => { p.Status = PlayerStatus.Spectating; p.Role = null; }); ActiveRoleHashes = new List <string>(); PlayerOnTrial = null; ServerInstance.Send(192); // InvokeSceneFlip(); return; } StateChanged = true; PlayerOnTrial = null; } ServerInstance.Send(6, StateTime); // SetTimerValue(int); } }
static void RequestActionOnPlayer(UdpClient sender, uint pid) { NetWerewolfPlayer player = sender.GetPlayer(); NetWerewolfPlayer target = ConnectedPlayers.Find(p => p.PlayerID == pid); switch (player.Status) { case PlayerStatus.Dead: sender.Send(5, 0u, $"You are dead and cannot perform any more actions!"); return; case PlayerStatus.Spectating: sender.Send(5, 0u, $"Spectators cannot perform in-game actions."); return; } if (target == null) { sender.Send(5, 0u, $"Targeted player with ID {pid} not found."); return; } if (CurrentDay == 0 && CurrentGameState == GameState.Discussion) { sender.Send(5, 0u, $"No votes for execution will be considered until the first night is over!"); return; } switch (CurrentGameState) { case GameState.Dawn: sender.Send(5, 0u, $"Please wait until dawn is over to begin voting."); break; case GameState.Discussion: // TODO: Vote against player if (target.PlayerID == player.PlayerID) { sender.Send(5, 0u, $"You cannot vote yourself onto trial!"); break; } if (player.TrialTargetPID != target.PlayerID) { player.TrialTargetPID = target.PlayerID; target.TrialVotes++; ServerInstance.Send(5, 0u, $"{player.Name} has voted to trial {target.Name}! ({target.TrialVotes}/2)"); if (target.TrialVotes >= 2 && PlayerOnTrial == null) { PlayerOnTrial = target; CurrentGameState = GameState.Trial; StateChanged = true; StateTime = 20; } } else if (player.TrialTargetPID == target.PlayerID) { player.TrialTargetPID = 0u; target.TrialVotes--; ServerInstance.Send(5, 0u, $"{player.Name} has revoked their vote to trial {target.Name}. ({target.TrialVotes}/2)"); } break; case GameState.Trial: if (PlayerOnTrial != null && PlayerOnTrial.Status != PlayerStatus.Dead) { if (player.PlayerID == PlayerOnTrial.PlayerID) { sender.Send(5, 0u, $"You are on trial and cannot vote to execute yourself!"); break; } player.VotedForKill = !player.VotedForKill; if (player.VotedForKill) { sender.Send(5, 0u, $"You have voted to kill {PlayerOnTrial.Name}."); } else { sender.Send(5, 0u, $"You have decided to revoke your vote to kill {PlayerOnTrial.Name}."); } } else { sender.Send(5, 0u, $"The player who was on trial can no longer be voted against."); } break; case GameState.Night: // TODO: Night abilities if (player.Role.NightEvent == null) { sender.Send(5, 0u, $"The {player.Role.Name} role does not have a night ability!"); break; } if (player.Role.NightEvent.EventTargets == 0) { sender.Send(5, 0u, $"Your night ability is passive and does not require a target."); break; } if (player.Role.NightEvent.TargetPlayers[0] == null || player.Role.NightEvent.TargetPlayers[0].PlayerID != target.PlayerID) { player.Role.NightEvent.TargetPlayers[0] = target; sender.Send(5, 0u, $"You have decided to target {target.Name}."); // TODO: custom action text } else { player.Role.NightEvent.TargetPlayers[0] = null; sender.Send(5, 0u, $"You have instead decided not to perform your night ability."); } break; case GameState.End: sender.Send(5, 0u, $"The game is already over!"); break; } }