private async void ShowLoading(object sender, object e) { await playersReadySemaphore.WaitAsync(); if (PlayersReadyLocked) { playersReadySemaphore.Release(); return; } PlayersReadyLocked = true; Game.Log("All players are ready."); // Reset Game.Ready = false; this.Ready = false; for (int i = 0; i < Connections.Count; i++) { if (Connections[i].Ready) { Connections[i].Ready = false; } } // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { LoadMapEvent?.Invoke(null); }); playersReadySemaphore.Release(); }
private void loadSelectMapBtn_Click(object sender, EventArgs e) { if (availableMapsListBox.SelectedItem != null) { LoadMapRecord record = (LoadMapRecord)availableMapsListBox.SelectedItem; // Invoke the event MapLoadedEvent to pass the map object to the parent form. if (LoadMapEvent != null) { LoadMapEvent.Invoke(record.Id); } Close(); } else { MessageBox.Show("Please select a map."); } }
private async void ParsePacket(Packet packet) { if (packet.payload == null) { Game.Log("Packet Received (" + packet.commandType + ")."); } else if (packet.commandType == Packets.PingRequest && packet.commandType == Packets.PingReply && packet.commandType == Packets.PlayerPing && packet.commandType != Packets.Position && packet.commandType != Packets.PlayerPosition) { Game.Log("Packet Received (" + packet.commandType + ") " + ByteArray2String(packet.payload) + "."); } if (packet.commandType == 0 && host) { // <Host> // Ping request from player Game.Log("Ping test request received."); Tuple <short, byte[]> pingReplyPacket = CreatePacket(Packets.PingTestReply, null); await SendPacket(pingReplyPacket); this.Close(); } else if (packet.commandType == 1) { // <Player> // Ping reply from host PingTimer.Stop(); connected = false; // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PingTestReplyReceivedEvent?.Invoke(null, new PingTestReplyArguments( StreamSocket.Information.RemoteAddress.ToString(), Int32.Parse(StreamSocket.Information.RemotePort), PingTimer.ElapsedMilliseconds )); }); } else if (packet.commandType == 2 && host) { // <Host> // Join request from player byte[] playerIdBytes = new byte[packet.payload.Length]; System.Buffer.BlockCopy(packet.payload, 0, playerIdBytes, 0, packet.payload.Length); PlayerId = Encoding.UTF8.GetString(playerIdBytes); Game.Log("Join request from player (" + PlayerId + ")."); // Code ushort code = 0; // Check if player id // is used if (Game.PlayerId == PlayerId) { code = 1; } else { for (int i = 0; i < server.Connections.Count; i++) { Connection connection = server.Connections[i]; if (connection.PlayerId == PlayerId) { code = 1; } } } if (code == 1) { Game.Log("Join request from player (" + PlayerId + ") rejected, player id used."); } // Check if maximum number of players // is exceeded if (server.Connections.Count == 16) { code = 2; Game.Log("Join request from player (" + PlayerId + ") rejected, no slots available."); } // Check if host // left if (Game.State == States.Started) { code = 3; Game.Log("Join request from player (" + PlayerId + ") rejected, match is deleted."); } // Send reply byte[] joinReplyPayload = new byte[19]; byte[] hostPlayerIdPaddedBytes = new byte[15]; byte[] codeBytes = BitConverter.GetBytes(code); byte[] hostPlayerIdBytes = Encoding.ASCII.GetBytes(Game.PlayerId); System.Buffer.BlockCopy(hostPlayerIdBytes, 0, hostPlayerIdPaddedBytes, 0, hostPlayerIdBytes.Length); ushort hostReadyStatus = 0; if (Game.Ready) { hostReadyStatus = 1; } byte[] readyStatusBytes = BitConverter.GetBytes(hostReadyStatus); System.Buffer.BlockCopy(codeBytes, 0, joinReplyPayload, 0, codeBytes.Length); System.Buffer.BlockCopy(hostPlayerIdPaddedBytes, 0, joinReplyPayload, codeBytes.Length, hostPlayerIdPaddedBytes.Length); System.Buffer.BlockCopy(readyStatusBytes, 0, joinReplyPayload, codeBytes.Length + hostPlayerIdPaddedBytes.Length, readyStatusBytes.Length); Tuple <short, byte[]> joinReplyPacket = CreatePacket(Packets.JoinReply, joinReplyPayload); await SendPacket(joinReplyPacket); if (code > 0) { this.Close(); return; } if (Game.State == States.MatchEnded || Game.State == States.CleanupMatchDetails1 || Game.State == States.CleanupMatchDetails2) { CleanupCompleted = true; server.PlayerCleanupCompleted(this); } // Send player list Game.Log("Sending player list to player (" + PlayerId + ")."); server.SendPlayerList(this); // Broadcast to all players byte[] playerJoinedPayload = Encoding.ASCII.GetBytes(PlayerId); Tuple <short, byte[]> playerJoinedPacket = server.CreatePacket(Packets.PlayerJoined, playerJoinedPayload); await server.SendPacket(playerJoinedPacket); // Send match state byte[] statePayload = BitConverter.GetBytes(Game.State); Tuple <short, byte[]> statePacket = CreatePacket(Packets.GameState, statePayload); await SendPacket(statePacket); // Add to connections list server.PlayerJoined(this); // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerJoinedEvent?.Invoke(this, new PlayerJoinedArguments(PlayerId, false, Ready)); }); // Request ping every second PingTimer = new Stopwatch(); pingInterval = new Timer(SendPing, null, 0, 1000); pingReplyReceived = true; Joined = true; } else if (packet.commandType == 3) { // <Player> // Join reply from host byte[] codeBytes = new byte[2]; System.Buffer.BlockCopy(packet.payload, 0, codeBytes, 0, 2); ushort code = BitConverter.ToUInt16(codeBytes, 0); // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { JoinMatchEvent?.Invoke(null, new JoinMatchArguments( code )); }); if (code > 0) { this.Close(); return; } else { byte[] playerIdBytes = new byte[15]; byte[] playerReadyBytes = new byte[2]; System.Buffer.BlockCopy(packet.payload, codeBytes.Length, playerIdBytes, 0, playerIdBytes.Length); System.Buffer.BlockCopy(packet.payload, codeBytes.Length + playerIdBytes.Length, playerReadyBytes, 0, playerReadyBytes.Length); PlayerId = Encoding.UTF8.GetString(playerIdBytes).Replace("\0", String.Empty); Joined = true; ushort playerStatus = BitConverter.ToUInt16(playerReadyBytes, 0); bool playerReady = false; if (playerStatus == 1) { playerReady = true; } // Check ping every second PingTimer = new Stopwatch(); PingTimer.Start(); pingInterval = new Timer(CheckPing, null, 0, 1000); // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerJoinedEvent?.Invoke(this, new PlayerJoinedArguments(PlayerId, true, playerReady)); }); } } else if (packet.commandType == 4) { // <Player> // Game state from host byte[] stateBytes = new byte[2]; System.Buffer.BlockCopy(packet.payload, 0, stateBytes, 0, stateBytes.Length); ushort state = BitConverter.ToUInt16(stateBytes, 0); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { MatchStateEvent?.Invoke(null, new MatchStateArguments( state )); }); } else if (packet.commandType == 5) { // <Host/Player> // Leave request from host/player leaveRequestReceived = true; if (host) { // Broadcast to all players byte[] playerLeftPayload = Encoding.ASCII.GetBytes(PlayerId); Tuple <short, byte[]> playerLeftPacket = server.CreatePacket(Packets.PlayerLeft, playerLeftPayload); await server.SendPacket(playerLeftPacket); } // Stop ping interval if (pingInterval != null) { pingInterval.Dispose(); } // Remove from connections list server.PlayerLeft(this); // Update player list and UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerLeftEvent?.Invoke(this, new PlayerLeftArguments(PlayerId, false)); }); // Disconnect player Tuple <short, byte[]> leaveReplyPacket = CreatePacket(Packets.LeaveReply, null); await SendPacket(leaveReplyPacket); this.Close(); } else if (packet.commandType == 6) { // <Host/Player> // Leave reply from host/player LeaveRequestAccepted = true; if (host) { Game.Log("Player (" + PlayerId + ") accepted the leave request."); } else { Game.Log("Host accepted the leave request."); } // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { LeaveReplyEvent.Invoke(null); }); } else if (packet.commandType == 7) { // <Player> // Ping request from host Tuple <short, byte[]> pingReplyPacket = CreatePacket(Packets.PingReply, null); await SendPacket(pingReplyPacket); if (PingTimer != null) { PingTimer.Restart(); } } else if (packet.commandType == 8 && host) { // <Host> // Ping reply from player PingTimer.Stop(); PingTime = (ulong)PingTimer.ElapsedMilliseconds; pingReplyReceived = true; // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerPingEvent?.Invoke(this, new PlayerPingArguments(PlayerId, PingTime)); }); // Send to all players byte[] playerPingTimePayload = new byte[23]; byte[] playerIdPaddedBytes = new byte[15]; byte[] playerIdBytes = Encoding.ASCII.GetBytes(PlayerId); byte[] playerPingTimeBytes = BitConverter.GetBytes(PingTime); System.Buffer.BlockCopy(playerIdBytes, 0, playerIdPaddedBytes, 0, playerIdBytes.Length); System.Buffer.BlockCopy(playerIdPaddedBytes, 0, playerPingTimePayload, 0, playerIdPaddedBytes.Length); System.Buffer.BlockCopy(playerPingTimeBytes, 0, playerPingTimePayload, playerIdPaddedBytes.Length, playerPingTimeBytes.Length); Tuple <short, byte[]> playerPingTimePacket = server.CreatePacket(Packets.PlayerPing, playerPingTimePayload); await server.SendPacket(playerPingTimePacket); } else if (packet.commandType == 9) { // <Player> // Player from list byte[] playerIdBytes = new byte[15]; System.Buffer.BlockCopy(packet.payload, 0, playerIdBytes, 0, 15); string playerId = Encoding.UTF8.GetString(playerIdBytes).Replace("\0", String.Empty); byte[] playerReadyStatusBytes = new byte[2]; System.Buffer.BlockCopy(packet.payload, 15, playerReadyStatusBytes, 0, 2); ushort playerReadyStatus = BitConverter.ToUInt16(playerReadyStatusBytes, 0); bool playerReady = false; if (playerReadyStatus == 1) { playerReady = true; } await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerJoinedEvent?.Invoke(this, new PlayerJoinedArguments(playerId, false, playerReady)); }); } else if (packet.commandType == 10) { // <Player> // Player joined byte[] playerIdBytes = new byte[packet.payload.Length]; System.Buffer.BlockCopy(packet.payload, 0, playerIdBytes, 0, packet.payload.Length); string playerId = Encoding.UTF8.GetString(playerIdBytes).Replace("\0", String.Empty); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerJoinedEvent?.Invoke(this, new PlayerJoinedArguments(playerId, false, false)); }); } else if (packet.commandType == 11) { // <Player> // Player left byte[] playerIdBytes = new byte[packet.payload.Length]; System.Buffer.BlockCopy(packet.payload, 0, playerIdBytes, 0, packet.payload.Length); string playerId = Encoding.UTF8.GetString(playerIdBytes).Replace("\0", String.Empty); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerLeftEvent?.Invoke(this, new PlayerLeftArguments(playerId, false)); }); } else if (packet.commandType == 12) { // <Player> // Ready time left byte[] readyTimeLeftBytes = new byte[packet.payload.Length]; System.Buffer.BlockCopy(packet.payload, 0, readyTimeLeftBytes, 0, 4); uint readyTimeLeft = BitConverter.ToUInt32(readyTimeLeftBytes, 0); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { ReadyTimeEvent?.Invoke(null, new ReadyTimeLeftArguments(readyTimeLeft)); }); } else if (packet.commandType == 13) { // <Player> // Player ping time byte[] playerIdBytes = new byte[15]; byte[] playerPingTimeBytes = new byte[8]; System.Buffer.BlockCopy(packet.payload, 0, playerIdBytes, 0, 15); System.Buffer.BlockCopy(packet.payload, 15, playerPingTimeBytes, 0, 8); string playerId = Encoding.UTF8.GetString(playerIdBytes).Replace("\0", String.Empty); ulong playerPingTime = BitConverter.ToUInt64(playerPingTimeBytes, 0); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerPingEvent?.Invoke(null, new PlayerPingArguments(playerId, playerPingTime)); }); } else if (packet.commandType == 14 && host) { // <Host> // Player ready byte[] readyStatusBytes = new byte[packet.payload.Length]; System.Buffer.BlockCopy(packet.payload, 0, readyStatusBytes, 0, packet.payload.Length); ushort readyStatus = BitConverter.ToUInt16(readyStatusBytes, 0); if (readyStatus == 0) { Ready = false; } else { Ready = true; } // Broadcast to all players byte[] playerStatusPayload = new byte[17]; byte[] playerIdPaddedBytes = new byte[15]; byte[] playerIdBytes = Encoding.ASCII.GetBytes(PlayerId); byte[] playerReadyStatusBytes = BitConverter.GetBytes(readyStatus); System.Buffer.BlockCopy(playerIdBytes, 0, playerIdPaddedBytes, 0, playerIdBytes.Length); System.Buffer.BlockCopy(playerIdPaddedBytes, 0, playerStatusPayload, 0, playerIdPaddedBytes.Length); System.Buffer.BlockCopy(playerReadyStatusBytes, 0, playerStatusPayload, playerIdPaddedBytes.Length, playerReadyStatusBytes.Length); Tuple <short, byte[]> playeReadyStatusPacket = server.CreatePacket(Packets.PlayerReady, playerStatusPayload); await server.SendPacket(playeReadyStatusPacket); // Update ready state server.PlayerReady(this); // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerReadyEvent?.Invoke(null, new PlayerReadyArguments(PlayerId, Ready)); }); } else if (packet.commandType == 15) { // <Player> // Player ready byte[] playerIdBytes = new byte[15]; byte[] playerReadyStatusBytes = new byte[2]; System.Buffer.BlockCopy(packet.payload, 0, playerIdBytes, 0, 15); System.Buffer.BlockCopy(packet.payload, 15, playerReadyStatusBytes, 0, 2); string playerId = Encoding.UTF8.GetString(playerIdBytes).Replace("\0", String.Empty); ushort playerReadyStatus = BitConverter.ToUInt16(playerReadyStatusBytes, 0); bool ready = false; if (playerReadyStatus == 1) { ready = true; } await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerReadyEvent?.Invoke(null, new PlayerReadyArguments(playerId, ready)); }); } else if (packet.commandType == 16) { // <Player> // Load map await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { LoadMapEvent?.Invoke(null); }); } else if (packet.commandType == 17) { // <Player> // Map objects created await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { MapObjectsCreatedEvent?.Invoke(null); }); } else if (packet.commandType == 18 && host) { // <Host> // Map objects requested await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerMapObjectsRequestedEvent?.Invoke(this); }); } else if (packet.commandType == 19) { // <Player> // Target position byte[] targetXBytes = new byte[4]; byte[] targetYBytes = new byte[4]; System.Buffer.BlockCopy(packet.payload, 0, targetXBytes, 0, 4); System.Buffer.BlockCopy(packet.payload, targetXBytes.Length, targetYBytes, 0, 4); float targetX = BitConverter.ToSingle(targetXBytes, 0); float targetY = BitConverter.ToSingle(targetYBytes, 0); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { TargetPositionEvent?.Invoke(null, new TargetPositionArguments(targetX, targetY)); }); } else if (packet.commandType == 20) { // <Player> // Score byte[] playerIdBytes = new byte[15]; byte[] scoreBytes = new byte[2]; System.Buffer.BlockCopy(packet.payload, 0, playerIdBytes, 0, 15); System.Buffer.BlockCopy(packet.payload, playerIdBytes.Length, scoreBytes, 0, scoreBytes.Length); string playerId = Encoding.UTF8.GetString(playerIdBytes).Replace("\0", String.Empty); ushort score = BitConverter.ToUInt16(scoreBytes, 0); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerScoreEvent?.Invoke(null, new PlayerScoreArguments(playerId, score)); }); } else if (packet.commandType == 21) { // <Player> // Map data end await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { MapDataEndEvent?.Invoke(null); }); } else if (packet.commandType == 22 && host) { // <Host> // Player map loaded if (!MapLoaded) { MapLoaded = true; server.PlayerMapLoaded(this); } } else if (packet.commandType == 23) { // <Player> // Show map await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { ShowMapEvent?.Invoke(this); }); } else if (packet.commandType == 24 && host) { // <Host> // Player map shown if (!MapShown) { MapShown = true; server.PlayerMapShown(this); } } else if (packet.commandType == 25) { // <Player> // Match countdown byte[] countdownBytes = new byte[packet.payload.Length]; System.Buffer.BlockCopy(packet.payload, 0, countdownBytes, 0, 4); uint countdownSeconds = BitConverter.ToUInt32(countdownBytes, 0); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { MatchCountdownEvent?.Invoke(this, new MatchCountdownArguments(countdownSeconds)); }); } else if (packet.commandType == 26) { // <Player> // Match started await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { MatchStartedEvent?.Invoke(this); }); } else if (packet.commandType == 27 && host) { // <Host> // Player position byte[] playerXBytes1 = new byte[4]; byte[] playerYBytes1 = new byte[4]; byte[] playerAngleBytes1 = new byte[4]; System.Buffer.BlockCopy(packet.payload, 0, playerXBytes1, 0, 4); System.Buffer.BlockCopy(packet.payload, playerXBytes1.Length, playerYBytes1, 0, 4); System.Buffer.BlockCopy(packet.payload, playerXBytes1.Length + playerYBytes1.Length, playerAngleBytes1, 0, 4); PlayerX = BitConverter.ToSingle(playerXBytes1, 0); PlayerY = BitConverter.ToSingle(playerYBytes1, 0); PlayerAngle = BitConverter.ToSingle(playerAngleBytes1, 0); // Broadcast to all players byte[] positionPayload = new byte[27]; byte[] playerIdPaddedBytes = new byte[15]; byte[] playerIdBytes = Encoding.ASCII.GetBytes(PlayerId); byte[] playerX = BitConverter.GetBytes(PlayerX); byte[] playerY = BitConverter.GetBytes(PlayerY); byte[] playerAngle = BitConverter.GetBytes(PlayerAngle); System.Buffer.BlockCopy(playerIdBytes, 0, playerIdPaddedBytes, 0, playerIdBytes.Length); System.Buffer.BlockCopy(playerIdPaddedBytes, 0, positionPayload, 0, playerIdPaddedBytes.Length); System.Buffer.BlockCopy(playerX, 0, positionPayload, playerIdPaddedBytes.Length, playerX.Length); System.Buffer.BlockCopy(playerY, 0, positionPayload, playerIdPaddedBytes.Length + playerX.Length, playerY.Length); System.Buffer.BlockCopy(playerAngle, 0, positionPayload, playerIdPaddedBytes.Length + playerX.Length + playerY.Length, playerAngle.Length); Tuple <short, byte[]> playerPositionPacket = server.CreatePacket(Packets.PlayerPosition, positionPayload); await server.SendPacket(playerPositionPacket); // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerPositionEvent?.Invoke(null, new PlayerPositionArguments(PlayerId, PlayerX, PlayerY, PlayerAngle)); }); } else if (packet.commandType == 28) { // <Player> // Player position byte[] playerIdBytes = new byte[15]; byte[] playerXBytes = new byte[4]; byte[] playerYBytes = new byte[4]; byte[] playerAngleBytes = new byte[4]; System.Buffer.BlockCopy(packet.payload, 0, playerIdBytes, 0, 15); System.Buffer.BlockCopy(packet.payload, playerIdBytes.Length, playerXBytes, 0, playerXBytes.Length); System.Buffer.BlockCopy(packet.payload, playerIdBytes.Length + playerXBytes.Length, playerYBytes, 0, playerYBytes.Length); System.Buffer.BlockCopy(packet.payload, playerIdBytes.Length + playerXBytes.Length + playerYBytes.Length, playerAngleBytes, 0, playerAngleBytes.Length); string playerId = Encoding.UTF8.GetString(playerIdBytes).Replace("\0", String.Empty); float playerX = BitConverter.ToSingle(playerXBytes, 0); float playerY = BitConverter.ToSingle(playerYBytes, 0); float playerAngle = BitConverter.ToSingle(playerAngleBytes, 0); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerPositionEvent?.Invoke(null, new PlayerPositionArguments(playerId, playerX, playerY, playerAngle)); }); } else if (packet.commandType == 29) { // <Player> // Match time left byte[] timeLeftBytes = new byte[packet.payload.Length]; System.Buffer.BlockCopy(packet.payload, 0, timeLeftBytes, 0, 4); uint timeLeftSeconds = BitConverter.ToUInt32(timeLeftBytes, 0); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { MatchTimeLeftEvent?.Invoke(null, new MatchTimeLeftArguments(timeLeftSeconds)); }); } else if (packet.commandType == 30 && host) { // <Host> // Target reached TargetIndex++; // Sent to all players byte[] targetReachedPayload = new byte[17]; byte[] playerIdPaddedBytes = new byte[15]; byte[] playerIdBytes = Encoding.ASCII.GetBytes(PlayerId); byte[] targetIndex = BitConverter.GetBytes(TargetIndex); System.Buffer.BlockCopy(playerIdBytes, 0, playerIdPaddedBytes, 0, playerIdBytes.Length); System.Buffer.BlockCopy(playerIdPaddedBytes, 0, targetReachedPayload, 0, playerIdPaddedBytes.Length); System.Buffer.BlockCopy(targetIndex, 0, targetReachedPayload, playerIdPaddedBytes.Length, targetIndex.Length); Tuple <short, byte[]> targetReachedPacket = server.CreatePacket(Packets.PlayerTargetReached, targetReachedPayload); await server.SendPacket(targetReachedPacket); // Update UI await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerTargetReachedEvent?.Invoke(null, new PlayerTargetReachedArguments(PlayerId, TargetIndex)); }); } else if (packet.commandType == 31) { // <Player> // Target reached byte[] playerIdBytes = new byte[15]; byte[] playerTargetIndexBytes = new byte[2]; System.Buffer.BlockCopy(packet.payload, 0, playerIdBytes, 0, playerIdBytes.Length); System.Buffer.BlockCopy(packet.payload, playerIdBytes.Length, playerTargetIndexBytes, 0, playerTargetIndexBytes.Length); string playerId = Encoding.UTF8.GetString(playerIdBytes).Replace("\0", String.Empty); ushort playerTargetIndex = BitConverter.ToUInt16(playerTargetIndexBytes, 0); await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { PlayerTargetReachedEvent?.Invoke(null, new PlayerTargetReachedArguments(playerId, playerTargetIndex)); }); } else if (packet.commandType == 32) { // <Player> // Match ended await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { MatchEndedEvent?.Invoke(this); }); } else if (packet.commandType == 33) { // <Player> // Load match details await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { LoadMatchDetailsEvent?.Invoke(this); }); } else if (packet.commandType == 34 && host) { // <Host> // Cleanup completed if (!CleanupCompleted) { CleanupCompleted = true; server.PlayerCleanupCompleted(this); } } else if (packet.commandType == 35) { // <Player> // Show match details await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { ShowMatchDetailsEvent?.Invoke(this); }); } }