private void OnClientDisconnected(object sender, PBEServerClient client) { // Need to spawn a new thread so "WaitOne()" doesn't block the thread that receives client packets new Thread(() => { lock (this) { // Wait for the server to be in a state where no events will be sent _resetEvent.WaitOne(); if (_readyPlayers.ContainsKey(client)) { Player player = _readyPlayers[client]; _readyPlayers.Remove(client); player.Dispose(); Console.WriteLine($"Client disconnected ({player.BattleId} {player.TrainerName})"); if (player.BattleId < 2) { if (_state != ServerState.WaitingForPlayers) { CancelMatch(); } } else { // Temporarily ignore spectators } } } }) { Name = "Client Disconnected Thread" }.Start(); }
public Player(BattleServer server, PBEServerClient client, byte battleId, string name) { BattleId = battleId; TrainerName = name; Server = server; Client = client; Client.PacketReceived += OnPacketReceived; }
private void OnClientConnected(object sender, PBEServerClient client) { // Need to spawn a new thread so "WaitOne()" doesn't block the thread that receives client packets new Thread(() => { lock (this) { // Wait for the server to be in a state where no events will be sent _resetEvent.WaitOne(); var player = new Player(this, client); // Set new player's info for (int i = 0; i < int.MaxValue; i++) { if (!_readyPlayers.Any(p => p.Value.BattleId == i)) { player.BattleId = i; break; } } player.TrainerName = Utils.RandomElement(new string[] { "Sasha", "Nikki", "Lara", "Violet", "Naomi", "Rose", "Sabrina", "Nicole" }); _readyPlayers.Add(client, player); Console.WriteLine($"Client connected ({client.IP} {player.BattleId} {player.TrainerName})"); foreach (Player rp in _readyPlayers.Values.ToArray()) // Copy so a disconnect doesn't cause an exception { // Alert new player of all other players that have already joined if (rp != player) { player.Send(new PBEPlayerJoinedPacket(false, rp.BattleId, rp.TrainerName)); if (!player.WaitForResponse()) { return; } } // Alert all players that this new player joined (including him/herself) bool isMe = rp == player; rp.Send(new PBEPlayerJoinedPacket(isMe, player.BattleId, player.TrainerName)); if (!rp.WaitForResponse() && (isMe || rp.BattleId < 2)) { return; } } if (player.BattleId >= 2) // Catch up spectator { foreach (IPBEPacket packet in _spectatorPackets) { player.Send(packet); if (!player.WaitForResponse()) { return; } } } else if (_readyPlayers.Count == 2) // Try to start the battle { _state = ServerState.WaitingForParties; Console.WriteLine("Two players connected! Waiting for parties..."); _battlers = _readyPlayers.Values.ToArray(); SendTo(_battlers, new PBEPartyRequestPacket()); } } }) { Name = "Client Connected Thread" }.Start(); }
public Player(BattleServer server, PBEServerClient client) { Server = server; Client = client; Client.PacketReceived += OnPacketReceived; }
private void OnClientConnected(object sender, PBEServerClient client) { // Need to spawn a new thread so "WaitOne()" doesn't block the thread that receives client packets new Thread(() => { lock (this) { // Wait for the server to be in a state where no events will be sent _resetEvent.WaitOne(); string name = PBEDataProvider.GlobalRandom.RandomElement(new string[] { "Sasha", "Nikki", "Lara", "Violet", "Naomi", "Rose", "Sabrina", "Nicole" }); if (_battlerCounter < NumBattlers) { byte i = _battlerCounter; Console.WriteLine($"Client connected ({client.IP} {i} {name})"); var newPlayer = new Player(this, client, i, name); IPBEPokemonCollection party = newPlayer.AskForParty(RequireLegalParties); if (party == null) { newPlayer.Dispose(); return; } _incomingTrainers[i / NumTrainersPerTeam][i % NumTrainersPerTeam] = new PBETrainerInfo(party, name); _battlers[i] = newPlayer; _readyPlayers.Add(client, newPlayer); // Start battle if (++_battlerCounter == NumBattlers) { Console.WriteLine("All players connected!"); _battle = new PBEBattle(BattleFormat, Settings, _incomingTrainers[0], _incomingTrainers[1]); _incomingTrainers = null; _battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler; _battle.OnNewEvent += BattleEventHandler; _battle.OnStateChanged += BattleStateHandler; _server.Battle = _battle; BattleStateHandler(_battle); // Call RunTurn, which sends battle packet } } else { Console.WriteLine($"Client connected ({client.IP} {byte.MaxValue} {name})"); var newPlayer = new Player(this, client, byte.MaxValue, name); var chakoPackay = new PBEPlayerJoinedPacket(name); foreach (Player p in _readyPlayers.Values.ToArray()) { p.Send(chakoPackay); if (!p.WaitForResponse(typeof(PBEResponsePacket)) && p.BattleId != byte.MaxValue) { newPlayer.Dispose(); return; } } _spectatorPackets.Add(chakoPackay); foreach (IPBEPacket packet in _spectatorPackets) { newPlayer.Send(packet); if (!newPlayer.WaitForResponse(typeof(PBEResponsePacket))) { newPlayer.Dispose(); return; } } _readyPlayers.Add(client, newPlayer); } } }) { Name = "Client Connected Thread" }.Start(); }