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); } }
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; } }