Esempio n. 1
0
        /// <summary>
        /// Internal use only, fetches the correct handler for a given handler name. One packet name may map to multiple handler names.
        /// </summary>
        /// <param name="parserName">The packet handler to fetch</param>
        /// <returns></returns>
        private GamePacketParser GetPacketParser(String parserName)
        {
            if (parserName == "ErrorMessage")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["Message"] = nmsg.ReadString();
                           return props;
                       }
            }
            ;
            else if (parserName == "MOTD")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["Message"] = nmsg.ReadString();
                           return props;
                       }
            }
            ;
            else if (parserName == "Ping")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           return new Packet(parserName);
                       }
            }
            ;

            else if (parserName == "PlayerLogin")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           Player                    = new ClientPlayer(nmsg.ReadU32());
                           props["DrawSpeed"]        = nmsg.ReadU16();
                           props["CanReportBugs"]    = nmsg.ReadByte() != 0;
                           props["Player"]           = Player;
                           KnownCreatures[Player.ID] = Player;

                           return props;
                       }
            }
            ;
            else if (parserName == "MapDescription")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           CurrentPosition = ReadMapPosition(nmsg);
                           props["Center"] = CurrentPosition;
                           props["Tiles"]  = ReadMapDescription(nmsg, CurrentPosition.X - 8, CurrentPosition.Y - 6, CurrentPosition.Z, 18, 14);
                           return props;
                       }
            }
            ;

            else if (parserName == "UpdateInventory")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["Slot"]  = (int)nmsg.ReadByte();
                           props["Thing"] = ReadThing(nmsg);
                           return props;
                       }
            }
            ;
            else if (parserName == "ClearInventory")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["Slot"] = (int)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "OpenContainer")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props       = new Packet(parserName);
                           int    ContainerID = (int)nmsg.ReadByte();
                           props["ContainerID"] = ContainerID;
                           int      ClientID = nmsg.ReadU16();
                           ItemType it       = GameData.GetItemType(ClientID);
                           if (it == null)
                           {
                               Log.Warning("OpenContainer contains unrecognized item type (" + ClientID.ToString() + ").", this);
                               it = ItemType.NullType;
                           }
                           props["Thing"]   = new ClientContainer(it, ContainerID);
                           props["Name"]    = nmsg.ReadString();
                           props["Volume"]  = (int)nmsg.ReadByte();
                           props["IsChild"] = nmsg.ReadByte() != 0;
                           int ItemCount = nmsg.ReadByte();
                           props["ItemCount"] = (int)ItemCount;
                           List <ClientItem> contents = new List <ClientItem>();
                           for (int i = 0; i < ItemCount; ++i)
                           {
                               contents.Add((ClientItem)ReadThing(nmsg));
                           }
                           props["Contents"] = contents;
                           return props;
                       }
            }
            ;
            else if (parserName == "CloseContainer")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["ContainerID"] = (int)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "ContainerAddItem")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["ContainerID"] = (int)nmsg.ReadByte();
                           props["Item"]        = ReadItem(nmsg);
                           return props;
                       }
            }
            ;
            else if (parserName == "ContainerTransformItem")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["ContainerID"] = (int)nmsg.ReadByte();
                           props["Slot"]        = (int)nmsg.ReadByte();
                           props["Item"]        = ReadItem(nmsg);
                           return props;
                       }
            }
            ;
            else if (parserName == "ContainerRemoveItem")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["ContainerID"] = (int)nmsg.ReadByte();
                           props["Slot"]        = (int)nmsg.ReadByte();
                           return props;
                       }
            }
            ;

            else if (parserName == "UpdateStats")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["Health"]            = (int)nmsg.ReadU16();
                           props["MaxHealth"]         = (int)nmsg.ReadU16();
                           props["Capacity"]          = (int)nmsg.ReadU16();
                           props["Experience"]        = (int)nmsg.ReadU32();
                           props["Level"]             = (int)nmsg.ReadByte();
                           props["LevelPercent"]      = (int)nmsg.ReadByte();
                           props["Mana"]              = (int)nmsg.ReadU16();
                           props["MaxMana"]           = (int)nmsg.ReadU16();
                           props["MagicLevel"]        = (int)nmsg.ReadByte();
                           props["MagicLevelPercent"] = (int)nmsg.ReadByte();
                           // TODO: Stamina for some versions
                           //int soul = nmsg.ReadByte();
                           //int staminaMinutes = nmsg.ReadU16();

                           return props;
                       }
            }
            ;
            else if (parserName == "UpdateSkills")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["Fist"]          = (int)nmsg.ReadByte();
                           props["FistPercent"]   = (int)nmsg.ReadByte();
                           props["Club"]          = (int)nmsg.ReadByte();
                           props["ClubPercent"]   = (int)nmsg.ReadByte();
                           props["Sword"]         = (int)nmsg.ReadByte();
                           props["SwordPercent"]  = (int)nmsg.ReadByte();
                           props["Axe"]           = (int)nmsg.ReadByte();
                           props["AxePercent"]    = (int)nmsg.ReadByte();
                           props["Dist"]          = (int)nmsg.ReadByte();
                           props["DistPercent"]   = (int)nmsg.ReadByte();
                           props["Shield"]        = (int)nmsg.ReadByte();
                           props["ShieldPercent"] = (int)nmsg.ReadByte();
                           props["Fish"]          = (int)nmsg.ReadByte();
                           props["FishPercent"]   = (int)nmsg.ReadByte();

                           return props;
                       }
            }
            ;
            else if (parserName == "PlayerIcons")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["ConditionState"] = (ConditionState)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "CancelAttack")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           return new Packet(parserName);
                       }
            }
            ;
            else if (parserName == "CancelWalk")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["Direction"] = (Direction)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "Death")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           return new Packet(parserName);
                       }
            }
            ;
            else if (parserName == "CanReport")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           return new Packet(parserName);
                       }
            }
            ;
            else if (parserName == "MoveNorth")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           CurrentPosition.Y--;
                           props["Center"] = CurrentPosition;
                           props["Tiles"]  = ReadMapDescription(nmsg, CurrentPosition.X - 8, CurrentPosition.Y - 6, CurrentPosition.Z, 18, 1);
                           return props;
                       }
            }
            ;
            else if (parserName == "MoveSouth")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           CurrentPosition.Y++;
                           props["Center"] = CurrentPosition;
                           props["Tiles"]  = ReadMapDescription(nmsg, CurrentPosition.X - 8, CurrentPosition.Y + 7, CurrentPosition.Z, 18, 1);
                           return props;
                       }
            }
            ;
            else if (parserName == "MoveWest")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           CurrentPosition.X--;
                           props["Center"] = CurrentPosition;
                           props["Tiles"]  = ReadMapDescription(nmsg, CurrentPosition.X - 8, CurrentPosition.Y - 6, CurrentPosition.Z, 1, 14);
                           return props;
                       }
            }
            ;
            else if (parserName == "MoveEast")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           CurrentPosition.X++;
                           props["Center"] = CurrentPosition;
                           props["Tiles"]  = ReadMapDescription(nmsg, CurrentPosition.X + 9, CurrentPosition.Y - 6, CurrentPosition.Z, 1, 14);
                           return props;
                       }
            }
            ;
            else if (parserName == "FloorUp")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet            props = new Packet(parserName);
                           List <ClientTile> Tiles = new List <ClientTile>();
                           int skipTiles           = 0;

                           CurrentPosition.Z--;
                           if (CurrentPosition.Z == 7)
                           {
                               for (int i = 5; i >= 0; i--)
                               {
                                   Tiles.AddRange(ReadFloorDescription(nmsg, ref skipTiles, CurrentPosition.X - 8, CurrentPosition.Y - 6, i, 18, 14, 8 - i));
                               }
                           }
                           else if (CurrentPosition.Z > 7)
                           {
                               Tiles.AddRange(ReadFloorDescription(nmsg, ref skipTiles, CurrentPosition.X - 8, CurrentPosition.Y - 6, CurrentPosition.Z - 2, 18, 14, 3));
                           }
                           CurrentPosition.X++;
                           CurrentPosition.Y++;

                           props["Tiles"]  = Tiles;
                           props["Center"] = CurrentPosition;
                           return props;
                       }
            }
            ;
            else if (parserName == "FloorDown")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet            props = new Packet(parserName);
                           List <ClientTile> Tiles = new List <ClientTile>();
                           int skipTiles           = 0;

                           CurrentPosition.Z++;
                           if (CurrentPosition.Z == 8)
                           {
                               int j = -1;
                               for (int i = CurrentPosition.Z; i < CurrentPosition.Z + 3; ++i, --j)
                               {
                                   Tiles.AddRange(ReadFloorDescription(nmsg, ref skipTiles, CurrentPosition.X - 8, CurrentPosition.Y - 6, i, 18, 14, j));
                               }
                           }
                           else if (CurrentPosition.Z > 8 && CurrentPosition.Z < 14)
                           {
                               Tiles.AddRange(ReadFloorDescription(nmsg, ref skipTiles, CurrentPosition.X - 8, CurrentPosition.Y - 6, CurrentPosition.Z + 2, 18, 14, -3));
                           }
                           CurrentPosition.X--;
                           CurrentPosition.Y--;

                           props["Tiles"]  = Tiles;
                           props["Center"] = CurrentPosition;
                           return props;
                       }
            }
            ;

            else if (parserName == "RefreshTile")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet      props = new Packet(parserName);
                           MapPosition pos   = ReadMapPosition(nmsg);
                           props["Position"] = pos;
                           props["Clear"]    = false;
                           if (nmsg.PeekU16() == 0xFF01)
                           {
                               nmsg.ReadU16();
                               props["Clear"] = true;
                               return props;
                           }
                           else
                           {
                               props["NewTile"] = ReadTileDescription(nmsg, pos);
                               // Skip extra bytes after data (it signifies the end of data)
                               nmsg.ReadU16();
                               return props;
                           }
                       }
            }
            ;
            else if (parserName == "AddThing")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Position"] = ReadMapPosition(nmsg);
                           props["Thing"]    = ReadThing(nmsg);
                           props["Push"]     = true;
                           // TODO: >= 8.53, push thing should be false
                           return props;
                       }
            }
            ;
            else if (parserName == "TransformThing")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Position"]   = ReadMapPosition(nmsg);
                           props["StackIndex"] = (int)nmsg.ReadByte();

                           if (nmsg.PeekU16() == 0x63)
                           {
                               nmsg.Skip(2);
                               // CreatureTurn2
                               props["Thing"]     = KnownCreatures[nmsg.ReadU32()];
                               props["Direction"] = (Direction)nmsg.ReadByte();
                           }
                           else
                           {
                               props["Thing"] = ReadThing(nmsg);
                           }
                           return props;
                       }
            }
            ;
            else if (parserName == "RemoveThing")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Position"]   = ReadMapPosition(nmsg);
                           props["StackIndex"] = (int)nmsg.ReadByte();

                           return props;
                       }
            }
            ;
            else if (parserName == "CreatureMove")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["OldPosition"]   = ReadMapPosition(nmsg);
                           props["OldStackIndex"] = (int)nmsg.ReadByte();
                           props["Position"]      = ReadMapPosition(nmsg);

                           if ((int)props["OldStackIndex"] > 9)
                           {
                               Log.Warning("CreatureMove - Old stack pos out of range.", this);
                           }

                           props["Push"] = true;
                           // TODO: >= 8.53, pushThing = false
                           return props;
                       }
            }
            ;

            else if (parserName == "WorldLight")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Level"] = (int)nmsg.ReadByte();
                           props["Color"] = (int)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "Effect")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Position"] = ReadMapPosition(nmsg);
                           props["Effect"]   = 1 + (int)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "AnimatedText")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Position"] = ReadMapPosition(nmsg);
                           props["Color"]    = (int)nmsg.ReadByte();
                           props["Text"]     = nmsg.ReadString();
                           return props;
                       }
            }
            ;
            else if (parserName == "ShootEffect")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["From"]   = ReadMapPosition(nmsg);
                           props["To"]     = ReadMapPosition(nmsg);
                           props["Effect"] = (int)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "SquareEffect")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Creature"] = KnownCreatures[nmsg.ReadU32()];
                           props["Color"]    = nmsg.ReadByte();
                           return props;
                       }
            }
            ;

            else if (parserName == "CreatureHealth")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Creature"] = KnownCreatures[nmsg.ReadU32()];
                           props["Health"]   = (int)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "CreatureLight")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Creature"] = KnownCreatures[nmsg.ReadU32()];
                           props["Level"]    = (int)nmsg.ReadByte();
                           props["Color"]    = (int)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "CreatureRefresh")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Creature"] = KnownCreatures[nmsg.ReadU32()];
                           return props;
                       }
            }
            ;
            else if (parserName == "CreatureTurn")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Creature"]  = KnownCreatures[nmsg.ReadU32()];
                           props["Direction"] = (Direction)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "CreatureSpeed")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Creature"] = KnownCreatures[nmsg.ReadU32()];
                           props["Speed"]    = (int)nmsg.ReadU16();
                           return props;
                       }
            }
            ;
            else if (parserName == "CreatureSkull")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Creature"] = KnownCreatures[nmsg.ReadU32()];
                           props["Skull"]    = (CreatureSkull)nmsg.ReadByte();
                           return props;
                       }
            }
            ;
            else if (parserName == "CreatureShield")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["Creature"]    = KnownCreatures[nmsg.ReadU32()];
                           props["PartyShield"] = (PartyShield)nmsg.ReadByte();
                           return props;
                       }
            }
            ;

            else if (parserName == "CreatureSpeak")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           ClientMessage Message = new ClientMessage();

                           //props["Creature"] = KnownCreatures[nmsg.ReadU32()];
                           Message.Speaker = nmsg.ReadString();
                           //props["Level"] = nmsg.ReadU16();
                           Message.Type = (MessageType)nmsg.ReadByte();

                           switch (Message.Type)
                           {
                           case MessageType.Say:
                           case MessageType.Whisper:
                           case MessageType.Yell:
                           case MessageType.MonsterSay:
                           case MessageType.MonsterYell:
                           case MessageType.PrivateNPCToPlayer:
                           case MessageType.PrivatePlayerToNPC:
                           {
                               props["Position"] = ReadMapPosition(nmsg);
                               Message.Text      = nmsg.ReadString();
                               break;
                           }

                           case MessageType.ChannelAnonymousRed:
                           case MessageType.ChannelOrange:
                           case MessageType.ChannelRed:
                           case MessageType.ChannelYellow:
                           {
                               props["ChannelID"] = nmsg.ReadU16();
                               Message.Text       = nmsg.ReadString();
                               break;
                           }

                           case MessageType.Private:
                           case MessageType.Broadcast:
                           case MessageType.PrivateRed:
                           {
                               Message.Text = nmsg.ReadString();
                               break;
                           }

                           case MessageType.ReportRuleViolation:
                           {
                               Message.Time = Common.UnixTime(nmsg.ReadU32());  // time
                               Message.Text = nmsg.ReadString();
                               break;
                           }

                           case MessageType.RuleViolationGameMaster:
                           case MessageType.RuleViolationPlayer:
                           {
                               Message.Text = nmsg.ReadString();
                               break;
                           }

                           default:
                               Log.Warning("Unknown speak class " + (int)props["MessageType"], this);
                               return null;
                           }
                           props["Message"] = Message;
                           return props;
                       }
            }
            ;
            else if (parserName == "ChannelList")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           int count = nmsg.ReadByte();
                           props["ChannelCount"] = count;
                           while (count > 0)
                           {
                               int    channelID   = nmsg.ReadU16();
                               string channelName = nmsg.ReadString();
                               --count;
                           }
                           return null;
                       }
            }
            ;
            else if (parserName == "OpenChannel")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["ChannelID"]   = nmsg.ReadU16();
                           props["ChannelName"] = nmsg.ReadString();
                           return props;
                       }
            }
            ;
            else if (parserName == "OpenPrivateChat")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["PlayerName"] = nmsg.ReadString();
                           return props;
                       }
            }
            ;
            else if (parserName == "TextMessage")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           MessageType Type = (MessageType)nmsg.ReadByte();
                           String      Text = nmsg.ReadString();
                           props["Message"] = new ClientMessage(Type, DateTime.Now, Text);
                           return props;
                       }
            }
            ;

            else if (parserName == "VIPState")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);

                           props["CreatureID"] = nmsg.ReadU32();
                           props["Name"]       = nmsg.ReadString();
                           props["Online"]     = nmsg.ReadByte() != 0;
                           return props;
                       }
            }
            ;
            else if (parserName == "VIPLogin")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["CreatureID"] = nmsg.ReadU32();
                           return props;
                       }
            }
            ;
            else if (parserName == "VIPLogout")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           props["CreatureID"] = nmsg.ReadU32();
                           return props;
                       }
            }
            ;
            else if (parserName == "RuleViolationChannel")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           return props;
                       }
            }
            ;
            else if (parserName == "RuleViolationRemove")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           return props;
                       }
            }
            ;
            else if (parserName == "RuleViolationCancel")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           return props;
                       }
            }
            ;
            else if (parserName == "RuleViolationLock")
            {
                return delegate(NetworkMessage nmsg)
                       {
                           Packet props = new Packet(parserName);
                           return props;
                       }
            }
            ;



            throw new System.ArgumentException("Unknown packet handler.");
        }