Пример #1
0
        public void UpdateRoom(RoomUpdateType type, Packet packet)
        {
            if (!IsHosting)
            {
                return;
            }

            if (type == RoomUpdateType.Additive)
            {
                foreach (string key in packet.Keys)
                {
                    _serverRoom.Set(key, packet.Get(key));
                }
            }
            else
            {
                _serverRoom = packet;
            }

            // Send update to Master
            NetOutgoingMessage outMessageM = _peer.CreateMessage();

            outMessageM.Write((byte)DataType.Room);
            outMessageM.Write((byte)RoomCommand.Update);
            outMessageM.Write((byte)type);
            packet.Serialize(outMessageM);
            _master.NetConnection.SendMessage(outMessageM, NetDeliveryMethod.ReliableOrdered, 0);

            // Send update to connected Clients
            NetOutgoingMessage outMessageC = _peer.CreateMessage();

            outMessageC.Write((byte)DataType.Room);
            outMessageC.Write((byte)RoomCommand.Update);
            _serverRoom.Serialize(outMessageC);

            NetConnection[] clientConns =
                _clientsCache.
                Where(x => x.Status == ConnectionStatus.Connected).
                Select(x => x.NetConnection).ToArray();

            if (clientConns.Length > 0)
            {
                _peer.SendMessage(outMessageC, clientConns, NetDeliveryMethod.ReliableOrdered, 0);
            }
        }
Пример #2
0
        private void _Room(Connection connection, NetIncomingMessage inMessage)
        {
            RoomCommand command = RoomCommand.Unknown;

            try
            {
                command = (RoomCommand)inMessage.ReadByte();
            }
            catch
            {
            }

            switch (command)
            {
            default:
            case RoomCommand.Unknown:
                break;

            case RoomCommand.Create:
            {
                Packet packet = new Packet(inMessage);
                Room   room   = new Room(connection.IPEndPoint.ToString().MD5String(), connection, packet);
                connection.Room = room;

                lock (_rooms)
                {
                    if (!_rooms.Contains(room))
                    {
                        _rooms.Add(room);
                        _roomsCache = _rooms.ToArray();
                    }
                }

                _handler.RoomOperation(RoomOperation.Create, room);
            }
            break;

            case RoomCommand.Update:
            {
                if (connection.Room == null)
                {
                    break;
                }

                RoomUpdateType type = RoomUpdateType.Unknown;

                try
                {
                    type = (RoomUpdateType)inMessage.ReadByte();
                }
                catch
                {
                }

                Packet packet = new Packet(inMessage);
                switch (type)
                {
                default:
                case RoomUpdateType.Unknown:
                    break;

                case RoomUpdateType.Change:
                    connection.Room.Packet = packet;
                    break;

                case RoomUpdateType.Additive:
                    foreach (string key in packet.Keys)
                    {
                        connection.Room.Packet.Set(key, packet.Get(key));
                    }
                    break;
                }

                _handler.RoomOperation(RoomOperation.Update, connection.Room);
            }
            break;

            case RoomCommand.Destroy:
            {
                lock (_rooms)
                {
                    if (_rooms.Remove(connection.Room))
                    {
                        _roomsCache = _rooms.ToArray();
                    }
                }

                _handler.RoomOperation(RoomOperation.Destroy, connection.Room);

                connection.Room = null;
            }
            break;

            case RoomCommand.GetRoom:
            {
                string id = null;
                try
                {
                    id = inMessage.ReadString();
                }
                catch
                {
                }
                if (string.IsNullOrEmpty(id))
                {
                    return;
                }

                Room room = _roomsCache.FirstOrDefault(x => x.Id == id);
                if (room == null)
                {
                    return;
                }

                NetOutgoingMessage outMessage = _peer.CreateMessage();
                outMessage.Write((byte)DataType.Room);
                outMessage.Write((byte)RoomCommand.GetRoom);
                outMessage.Write(room.Id);
                room.Packet.Serialize(outMessage);
                connection.NetConnection.SendMessage(outMessage, NetDeliveryMethod.ReliableOrdered, 0);
            }
            break;

            case RoomCommand.GetRoomsPage:
            {
                byte     reqId  = 0;
                byte     page   = 0;
                PageSize size   = PageSize.Unknown;
                Packet   packet = null;

                try
                {
                    reqId = inMessage.ReadByte();
                    page  = inMessage.ReadByte();
                    size  = (PageSize)inMessage.ReadByte();
                }
                catch
                {
                }

                if (reqId == 0 ||
                    page == 0 ||
                    size == PageSize.Unknown ||
                    !Enum.IsDefined(typeof(PageSize), size))
                {
                    return;
                }

                packet = new Packet(inMessage);

                Room[] filteredRooms =
                    _roomsCache.Where(
                        x =>
                    {
                        foreach (string key in packet.Keys)
                        {
                            Pair <Packet.DataType, object> entry = x.Packet.Get(key);
                            if (entry == null ||
                                !entry.Right.Equals(packet.Get(key).Right))
                            {
                                return(false);
                            }
                        }

                        return(true);
                    }).ToArray();

                if (filteredRooms.Length == 0)
                {
                    return;
                }

                int pages = (int)Math.Ceiling(filteredRooms.Length / (double)size);
                if (page > pages)
                {
                    page = (byte)pages;
                }

                NetOutgoingMessage outMessage = _peer.CreateMessage();
                outMessage.Write((byte)DataType.Room);
                outMessage.Write((byte)RoomCommand.GetRoomsPage);
                outMessage.Write(reqId);
                outMessage.Write(page);
                outMessage.Write((byte)pages);

                Room[] roomsToSend = filteredRooms.Skip((page - 1) * (byte)size).Take((byte)size).ToArray();
                outMessage.Write((byte)roomsToSend.Length);

                foreach (Room room in roomsToSend)
                {
                    outMessage.Write(room.Id);
                }

                connection.NetConnection.SendMessage(outMessage, NetDeliveryMethod.ReliableSequenced, 1);
            }
            break;

            case RoomCommand.Join:     // Client to Master
            {
                string id = null;
                try
                {
                    id = inMessage.ReadString();
                }
                catch
                {
                }
                if (string.IsNullOrEmpty(id))
                {
                    return;
                }

                Room room = _roomsCache.FirstOrDefault(x => x.Id == id);
                if (room == null)
                {
                    return;
                }

                // Send 'Auth' request to target room server
                NetOutgoingMessage outMessage = _peer.CreateMessage();
                outMessage.Write((byte)DataType.Room);
                outMessage.Write((byte)RoomCommand.Auth);
                outMessage.Write(connection.IPEndPoint);
                room.Connection.NetConnection.SendMessage(outMessage, NetDeliveryMethod.ReliableOrdered, 0);

                // Console.WriteLine("Join room received from <{0}> targeting room #{1} which is hosted by <{2}>",
                // connection.IPEndPoint, room.Id, room.Connection.IPEndPoint);
            }
            break;

            case RoomCommand.Accept:     // Server to Master
            {
                if (connection.Room == null)
                {
                    return;
                }

                IPEndPoint ipEndPoint = null;
                string     token      = null;

                try
                {
                    ipEndPoint = inMessage.ReadIPEndPoint();
                    token      = inMessage.ReadString();
                }
                catch
                {
                }

                if (ipEndPoint == null || token == null)
                {
                    return;
                }

                Connection clientConnection = _connectionsCache.FirstOrDefault(x => x.IPEndPoint.Equals(ipEndPoint));
                if (clientConnection == null)
                {
                    return;
                }

                // Send 'Connect' to Client
                NetOutgoingMessage outMessage = _peer.CreateMessage();
                outMessage.Write((byte)DataType.Room);
                outMessage.Write((byte)RoomCommand.Connect);
                outMessage.Write(connection.Room.Id);
                outMessage.Write(connection.IPEndPoint);
                outMessage.Write(token);
                clientConnection.NetConnection.SendMessage(outMessage, NetDeliveryMethod.ReliableOrdered, 0);

                // Console.WriteLine("Accept connection received from <{0}> for <{1}>", connection.IPEndPoint, clientConnection.IPEndPoint);
            }
            break;
            }
        }