private void OnDataReceived(byte[] data) { CCC_Packet response = data; if (response.Flag == CCC_Packet.Type.PLAYER_MOVE) { byte[] posbytes = response.Data.Skip(0).Take(12).ToArray(); byte[] rotbytes = response.Data.Skip(12).Take(12).ToArray(); byte[] velbytes = response.Data.Skip(24).Take(12).ToArray(); byte[] sclbytes = response.Data.Skip(36).Take(12).ToArray(); Position = posbytes; Rotation = rotbytes; Velocity = velbytes; Scale = sclbytes; TransformChanged(this); } else if (response.Flag == CCC_Packet.Type.PLAYER_CROUCH) { Crouching = BitConverter.ToBoolean(response.Data, 0); Crouch(this); } else if (response.Flag == CCC_Packet.Type.PLAYER_SHOOT) { bool hitplayer = BitConverter.ToBoolean(response.Data, 0); Vector3 position = new Vector3(); position.X = BitConverter.ToSingle(response.Data, 1); position.Y = BitConverter.ToSingle(response.Data, 5); position.Z = BitConverter.ToSingle(response.Data, 9); if (hitplayer) { byte amount = response.Data[13]; byte id = response.Data[14]; Shoot(this, position, id, amount); } else { Shoot(this, position); } } else if (response.Flag == CCC_Packet.Type.LOGOUT) { Logout(this); } }
private void Player_Shoot(CCC_Player player, CCC_Player.Vector3 position, int?playerid = null, int?amount = null) { List <byte> shootpacket = new List <byte>(); shootpacket.AddRange(BitConverter.GetBytes(playerid.HasValue)); byte[] pos = position; shootpacket.AddRange(pos); // Check if a player was hit. if (playerid.HasValue) { for (int i = 0; i < players.Count; i++) { // Find player that was hit. if (players[i].ID == playerid) { // Get damage amount. int damage = 0; if (amount.HasValue) { damage = amount.Value; } // Set health and send update players[i].TakeDamage((byte)damage); shootpacket.Add((byte)damage); shootpacket.Add(players[i].ID); SendPlayerUpdate(players[i]); } } } // Send shoot packet CCC_Packet packet = new CCC_Packet(CCC_Packet.Type.PLAYER_SHOOT); packet.Data = shootpacket.ToArray(); for (int i = 0; i < players.Count; i++) { if (players[i] != player) { try { players[i].Client.Send(packet); } catch (Exception) { players.RemoveAt(i); } } } }
private void SendPlayerUpdate(CCC_Player player) { CCC_Packet packet = new CCC_Packet(CCC_Packet.Type.PLAYER_UPDATE); packet.Data = player.Serialize(); for (int i = 0; i < players.Count; i++) { if (players[i] == player) { players[i] = player; } else { try { players[i].Client.Send(packet); } catch (Exception) { players.RemoveAt(i); } } } }
private void Player_Logout(CCC_Player player) { CCC_Packet packet = new CCC_Packet(CCC_Packet.Type.LOGOUT); packet.Data = new byte[1]; packet.Data[0] = player.ID; for (int i = 0; i < players.Count; i++) { if (players[i] == player) { players.RemoveAt(i); } else { players[i].Client.Send(packet); } } PlayerDisconnected(player); }
private void Player_Timeout(CCC_Player player) { Debug.WriteLine("TIMEOUT"); CCC_Packet packet = new CCC_Packet(CCC_Packet.Type.TIMEOUT); packet.Data = new byte[1]; packet.Data[0] = player.ID; for (int i = 0; i < players.Count; i++) { if (players[i] == player) { players.RemoveAt(i); } else { players[i].Client.Send(packet); } } PlayerDisconnected(player); }
private void OnClient(ServerClient client) { Debug.WriteLine("--Client"); CCC_Packet response = client.Read(); if (response.Flag == CCC_Packet.Type.HANDSHAKE) { Debug.WriteLine("HANDSHAKE"); if (response.Data.Length < 1 || response.Data[0] != CCC_Packet.Version) { client.Send(new CCC_Packet(CCC_Packet.Type.PROTOCOL_NOT_SUPPORTED, CCC_Packet.Version)); } else { client.Send(new CCC_Packet(CCC_Packet.Type.HANDSHAKE_OK)); } } else if (response.Flag == CCC_Packet.Type.INFO) { // THIS IS ONLY TEMP // Will be replaced by proper encoding later Debug.WriteLine("INFO"); StringBuilder builder = new StringBuilder(); builder.AppendFormat("{0};{1};{2};", Name, GameRunning, MaxPlayers); foreach (CCC_Player player in Clients) { builder.AppendFormat("{0},", player.Username); } byte[] encodedInfo = Encoding.UTF8.GetBytes(builder.ToString()); client.Send(new CCC_Packet(CCC_Packet.Type.INFO_RESPONSE, encodedInfo)); } else { Debug.WriteLine("UNKNOWN"); // Unknown Packet Flag. client.Send(new CCC_Packet(CCC_Packet.Type.PROTOCOL_NOT_SUPPORTED, CCC_Packet.Version)); } }
private void SendSync(object sender = null, ElapsedEventArgs e = null) { // Get sync table. CCC_Packet packet = new CCC_Packet(CCC_Packet.Type.SYNC); List <byte> table = new List <byte>(); for (int i = 0; i < players.Count; i++) { byte[] serialize = players[i].Serialize(); UInt16 length = (UInt16)serialize.Length; table.AddRange(BitConverter.GetBytes(length)); table.AddRange(serialize); } packet.Data = table.ToArray(); // Send to all players. for (int i = 0; i < players.Count; i++) { players[i].Client.Send(packet); } Sync(DateTime.Now); }
private void OnClient(ServerClient client) { CCC_Packet response = client.Read(); if (response.Flag == CCC_Packet.Type.HANDSHAKE) { /// Will check if client and server are using /// the same protocol version. if (response.Data.Length < 1 || response.Data[0] != CCC_Packet.Version) { client.Send(new CCC_Packet(CCC_Packet.Type.PROTOCOL_NOT_SUPPORTED, CCC_Packet.Version)); } else { client.Send(new CCC_Packet(CCC_Packet.Type.HANDSHAKE_OK)); } } else if (response.Flag == CCC_Packet.Type.INFO) { /// Will return information about the server. /// Clients can request this to prevent unnecessary requests. /// StringBuilder builder = new StringBuilder(); builder.AppendFormat("{0};{1};{2};", Name, GameRunning, MaxPlayers); foreach (CCC_Player player in players) { builder.AppendFormat("{0},", player.Username); } byte[] encodedInfo = Encoding.Unicode.GetBytes(builder.ToString()); client.Send(new CCC_Packet(CCC_Packet.Type.INFO_RESPONSE, encodedInfo)); } else if (response.Flag == CCC_Packet.Type.LOGIN) { /// Will check for: /// - Game is full /// - Username is taken by another player /// - Username is valid /// (Filter out inappropriate keywords/symbols/...) /// - Whitelist /// - Blacklist /// /// If successfull, will add user to the player list. /// #region Check if game is full. if (players.Count == MaxPlayers) { client.Send(new CCC_Packet(CCC_Packet.Type.GAME_FULL)); return; } #endregion string username = Encoding.Unicode.GetString(response.Data); #region Check if username is taken. foreach (CCC_Player p in players) { if (p.Username == username) { client.Send(new CCC_Packet(CCC_Packet.Type.USERNAME_TAKEN)); return; } } #endregion #region Check if username is valid. // TODO // Maybe some file or smth if (String.IsNullOrWhiteSpace(username) || username.Contains("hacker")) { client.Send(new CCC_Packet(CCC_Packet.Type.USERNAME_INVALID)); return; } #endregion #region Check Whitelist. #endregion #region Check Blacklist. #endregion #region Send Login Response CCC_Player player = new CCC_Player(client, players.Count + 1, username); List <byte> loginresponse = new List <byte>(); loginresponse.Add(player.ID); loginresponse.AddRange(Encoding.Unicode.GetBytes(player.Username)); client.Send(new CCC_Packet(CCC_Packet.Type.LOGIN_OK, loginresponse.ToArray())); #endregion #region Notify other Players CCC_Packet joinPacket = new CCC_Packet(CCC_Packet.Type.PLAYER_JOIN); List <byte> temp = new List <byte>(); temp.Add((byte)player.ID); temp.AddRange(Encoding.Unicode.GetBytes(player.Username)); joinPacket.Data = temp.ToArray(); // Notify other players. foreach (CCC_Player p in players) { p.Client.Send(joinPacket); } #endregion // Add player. players.Add(player); PlayerConnected(player); // Add all eventhandlers player.Logout += Player_Logout; player.TransformChanged += Player_TransformChanged; player.Crouch += Player_Crouch; player.Timeout += Player_Timeout; player.Shoot += Player_Shoot; // Sync SendSync(); } else { /// Will return PROTOCOL_NOT_SUPPORTED error. /// client.Send(new CCC_Packet(CCC_Packet.Type.PROTOCOL_NOT_SUPPORTED, CCC_Packet.Version)); } }