예제 #1
0
        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);
            }
        }
예제 #2
0
        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); }
                }
            }
        }
예제 #3
0
        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); }
                }
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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));
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        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));
            }
        }