Пример #1
0
        /// <summary>
        /// Write out a handshake response. Mutate this writer to represent the position after the write.
        /// </summary>
        /// <returns>A copy of this writer (after the write has been applied)</returns>
        public PacketWriter WriteHandshakeResponse <TPeer>(uint session, ushort clientId, [NotNull] ClientIdCollection idMap, [NotNull] Dictionary <string, List <ClientInfo <TPeer> > > peersByRoom)
        {
            if (idMap == null)
            {
                throw new ArgumentNullException("idMap");
            }
            if (peersByRoom == null)
            {
                throw new ArgumentNullException("peersByRoom");
            }

            WriteMagic();
            Write((byte)MessageTypes.HandshakeResponse);
            Write(session);

            //Assigned ID for this client
            Write(clientId);

            //Write ID map for all clients
            idMap.Serialize(ref this);

            //Room names list
            Write((ushort)peersByRoom.Count);
            foreach (var item in peersByRoom)
            {
                Write(item.Key);
            }

            //Channel count
            Write((ushort)peersByRoom.Count);

            //Write out list of peers in each channel (ugly enumerator instead of foreach because this doesn't box)
            using (var enumerator = peersByRoom.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    var channel = enumerator.Current.Key.ToRoomId();
                    var peers   = enumerator.Current.Value;

                    Write((ushort)channel);

                    //Write length prefixed list of peer IDs
                    Write((byte)peers.Count);
                    for (var i = 0; i < peers.Count; i++)
                    {
                        Write(peers[i].PlayerId);
                    }
                }
            }

            return(this);
        }
Пример #2
0
        /// <summary>
        /// Read the handshake response. Will totally overwrite the contents of outputRoomsToPeerId with a new state
        /// </summary>
        /// <param name="idMap"></param>
        /// <param name="outputRoomsToPeerId"></param>
        public void ReadHandshakeResponseBody([NotNull] ClientIdCollection idMap, [NotNull] Dictionary <string, List <ushort> > outputRoomsToPeerId)
        {
            if (idMap == null)
            {
                throw new ArgumentNullException("idMap");
            }
            if (outputRoomsToPeerId == null)
            {
                throw new ArgumentNullException("outputRoomsToPeerId");
            }

            //Read ID map for all clients
            idMap.Deserialize(ref this);

            // Read room name list, later in the packet we'll refer to rooms by their ID and we can look up their name in this list.
            // Only the name is in the packet, we can work out the ID locally.
            var roomNamesById = new Dictionary <ushort, string>();
            var roomNameCount = ReadUInt16();

            for (var i = 0; i < roomNameCount; i++)
            {
                var name = ReadString();
                if (!Log.AssertAndLogWarn(name != null, "Read a null room name in handshake packet (potentially corrupt packet)"))
                {
                    roomNamesById[name.ToRoomId()] = name;
                }
            }

            //Clear all the lists
            using (var enumerator = outputRoomsToPeerId.GetEnumerator())
                while (enumerator.MoveNext())
                {
                    enumerator.Current.Value.Clear();
                }

            //Read out lists per channel
            var channelCount = ReadUInt16();

            for (var i = 0; i < channelCount; i++)
            {
                var channel   = ReadUInt16();
                var peerCount = ReadByte();

                //Find room name
                string room;
                Log.AssertAndThrowPossibleBug(roomNamesById.TryGetValue(channel, out room), "C8E9EBED-2A46-4207-A050-0ABFE00BA9E8", "Could not find room name in handshake for ID:{0}", channel);

                //Get or create a list for this channel
                List <ushort> peers;
                if (!outputRoomsToPeerId.TryGetValue(room, out peers))
                {
                    peers = new List <ushort>();
                    outputRoomsToPeerId[room] = peers;
                }

                //Read out all the peers for this chanel
                for (var j = 0; j < peerCount; j++)
                {
                    peers.Add(ReadUInt16());
                }
            }
        }