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