public void parsePacket(NetworkMessage nmsg)
        {
            int packetType = nmsg.ReadByte();

            if (PacketParsers.ContainsKey(packetType))
            {
                PacketParser pp = PacketParsers[packetType];
                Packet p = pp.parser(nmsg);
                ProtocolEvent handler = PacketHandlers[packetType];
                if (handler != null && p != null)
                    handler.Invoke(p);
                /*
                string m = "Parsing packet 0x" + packetType.ToString("X2") + " '" + ph.name + "'";
                if (p != null)
                    m += "<pre>" + p.ToString() + "</pre>";
                Log.Debug(m);
                 */
                if (!nmsg.ReadAllData())
                    parsePacket(nmsg);
            }
            else
            {
                Log.Warning("Unknown packet type parsed 0x" + packetType.ToString("X2"), this);
            }
        }
        private ClientThing ReadThing(NetworkMessage nmsg)
        {
            UInt16 clientID = nmsg.ReadU16();
            if (clientID == 0x62)
            {
                // Known creature
                //Packet props = new Packet("KnownCreature");
                UInt32 creatureID = nmsg.ReadU32();
                //props["Creature"] = KnownCreatures[creatureID];

                return ReadCreature(nmsg, creatureID);
            }
            else if (clientID == 0x61)
            {
                // New creature
                //Packet props = new Packet("NewCreature");

                // Creature ID to kill
                UInt32 ForgetID = nmsg.ReadU32();
                UInt32 creatureID = nmsg.ReadU32();
                if (ForgetID != 0)
                    KnownCreatures.Remove(ForgetID);

                //props["ForgetCreatureID"] = ForgetID;
                String name = nmsg.ReadString();

                ClientCreature creature = ReadCreature(nmsg, creatureID);
                //props["Creature"] = creature;
                creature.Name = name;

                return creature;
            }
            else if (clientID == 0x63)
            {
                throw new CreatureTurn2Exception();
            }
            else
            {
                return ReadItem(nmsg, clientID);
            }
        }
        private ClientTile ReadTileDescription(NetworkMessage nmsg, MapPosition pos)
        {
            ClientTile Tile = new ClientTile(pos);
            int nStuff = 0;
            while (nStuff < 10)
            {
                if (nmsg.PeekU16() >= 0xFF00)
                {
                    return Tile;
                }
                else
                {
                    Tile.Add(ReadThing(nmsg));
                }
                ++nStuff;
            }

            return Tile;
        }
        /// <summary>
        /// Reads a map description (ie. a list of tiles) from the message.
        /// </summary>
        /// <param name="nmsg">The message to read from.</param>
        /// <param name="startX"></param>
        /// <param name="startY"></param>
        /// <param name="z"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        private object ReadMapDescription(NetworkMessage nmsg, int startX, int startY, int z, int width, int height)
        {
            int startZ = z, endZ = 0, stepZ = 0;
            if (startZ > 7)
            {
                startZ = z - 2;
                endZ = Math.Min(16, z + 2);
                stepZ = 1;
            }
            else
            {
                startZ = 7;
                endZ = 0;
                stepZ = -1;
            }

            int skipTiles = 0;
            List<ClientTile> tiles = new List<ClientTile>();
            for (int curZ = startZ; curZ != endZ + stepZ; curZ += stepZ)
                tiles.AddRange(ReadFloorDescription(nmsg, ref skipTiles, startX, startY, curZ, width, height, z - curZ));

            return tiles;
        }
 /// <summary>
 /// Reads a position (x, y, z) from the message
 /// </summary>
 /// <param name="nmsg">The message to read from</param>
 /// <returns></returns>
 private MapPosition ReadMapPosition(NetworkMessage nmsg)
 {
     int x = nmsg.ReadU16();
     int y = nmsg.ReadU16();
     int z = nmsg.ReadByte();
     return new MapPosition(x, y, z);
 }
        /// <summary>
        /// Read an Item and returns it.
        /// </summary>
        /// <param name="nmsg">Packet to read from.</param>
        /// <param name="clientID">If not 0, the function will not read client ID from the packet but use this one instead.</param>
        /// <returns></returns>
        private ClientItem ReadItem(NetworkMessage nmsg, UInt16 clientID = 0)
        {
            if (clientID == 0)
                clientID = nmsg.ReadU16();
            int subtype = -1;
            ItemType it = GameData.GetItemType(clientID);
            if (it == null)
            {
                Log.Warning("Item packet contains unrecognizabe item (" + clientID + ")");
                it = ItemType.NullType;
            }

            if (it.IsStackable || it.IsFluidContainer || it.IsSplash)
                subtype = nmsg.ReadByte();

            return new ClientItem(it, subtype);
        }
        private List<ClientTile> ReadFloorDescription(NetworkMessage nmsg, ref int skipTiles, int startX, int startY, int Z, int width, int height, int offset)
        {
            List<ClientTile> tiles = new List<ClientTile>();
            for (int x = 0; x < width; ++x)
            {
                for (int y = 0; y < height; ++y)
                {
                    if (skipTiles > 0)
                        skipTiles--;
                    else
                    {
                        MapPosition pos = new MapPosition(startX + x + offset, startY + y + offset, Z);
                        ClientTile Tile = ReadTileDescription(nmsg, pos);
                        skipTiles = nmsg.ReadByte();
                        if (nmsg.ReadByte() != 0xFF)
                            Log.Warning("Server did not follow Tile skip by 0xFF");
                        tiles.Add(Tile);
                    }
                }
            }

            return tiles;
        }
        /// <summary>
        /// Reads a Creature and returns it. This includes Outfit & Light etc.
        /// </summary>
        /// <param name="nmsg">Message to read from.</param>
        /// <param name="props">The read properties will be inserted into this property object.</param>
        /// <returns></returns>
        private ClientCreature ReadCreature(NetworkMessage nmsg, UInt32 CreatureID)
        {
            ClientCreature Creature = null;
            if (CreatureID == Player.ID)
                Creature = Player;
            else if (!KnownCreatures.TryGetValue(CreatureID, out Creature))
            {
                Creature = new ClientCreature(CreatureID);
                KnownCreatures.Add(CreatureID, Creature);
            }
            else
            {
                ;
            }

            Creature.Health = nmsg.ReadByte();
            Creature.Direction = (Direction)nmsg.ReadByte();

            // TODO: This is U16 for later versions
            Creature.Outfit.LookType = (int)nmsg.ReadByte();
            if (Creature.Outfit.LookType == 0)
            {
                // looktypeEx
                Creature.Outfit.LookItem = nmsg.ReadU16();
            }
            else
            {
                Creature.Outfit.LookHead = nmsg.ReadByte();
                Creature.Outfit.LookBody = nmsg.ReadByte();
                Creature.Outfit.LookLegs = nmsg.ReadByte();
                Creature.Outfit.LookFeet = nmsg.ReadByte();
            }

            Creature.Light.Level = nmsg.ReadByte();
            Creature.Light.Color = nmsg.ReadByte();

            Creature.Speed = nmsg.ReadU16();

            Creature.Skull = (CreatureSkull)nmsg.ReadByte();
            Creature.Shield = (PartyShield)nmsg.ReadByte();

            return Creature;
        }
 public void Write(NetworkMessage nmsg)
 {
     // do nothing
 }
예제 #10
0
        public NetworkMessage Read(GameTime Time)
        {
            if (PendingPackets.Count > 0)
                return PendingPackets.Dequeue();

            while (true)
            {
                int chunkType = File.ReadByte();

                if (chunkType == 1)
                {
                    // Marker, skip
                    continue;
                }
                else
                {
                    // Read delay
                    byte[] bytesDelay = new byte[4];
                    File.Read(bytesDelay, 0, 4);
                    int delay = System.BitConverter.ToInt32(bytesDelay, 0);
                    Elapsed = new TimeSpan(Elapsed.Ticks + delay * TimeSpan.TicksPerMillisecond);

                    byte[] bytesChunkLength = new byte[2];
                    File.Read(bytesChunkLength, 0, 2);
                    int chunkLength = System.BitConverter.ToUInt16(bytesChunkLength, 0);

                    int bytesRead = 0;
                    while (bytesRead < chunkLength)
                    {
                        // Data chunk
                        byte[] bytesPacketLength = new byte[2];
                        File.Read(bytesPacketLength, 0, 2);
                        int packetLength = BitConverter.ToUInt16(bytesPacketLength, 0);
                        bytesRead += 2;

                        NetworkMessage msg = new NetworkMessage(true);
                        for (int i = 0; i < packetLength; ++i)
                            msg.AddByte(File.ReadByte());
                        bytesRead += packetLength;

                        PendingPackets.Enqueue(msg);
                    }

                    // Schedule next
                    if (Time != null)
                        NextTime = Time.TotalGameTime +
                            new TimeSpan((int)(delay * TimeSpan.TicksPerMillisecond / PlaybackSpeed));

                    if (PendingPackets.Count == 0)
                        return null;
                    return PendingPackets.Dequeue();
                }
            }
        }