예제 #1
0
파일: Prey.cs 프로젝트: Cjaker/TibiaUnity3D
 private void ParsePreyFreeListRerollAvailability(Internal.CommunicationStream message)
 {
     byte   slot    = message.ReadUnsignedByte();
     ushort minutes = message.ReadUnsignedShort();
 }
예제 #2
0
 private void ParseMonsterCyclopediaNewDetails(Internal.CommunicationStream message)
 {
     ushort raceID = message.ReadUnsignedShort();
 }
예제 #3
0
파일: Prey.cs 프로젝트: Cjaker/TibiaUnity3D
 private void ParsePreyTimeLeft(Internal.CommunicationStream message)
 {
     byte   slot    = message.ReadUnsignedByte();
     ushort minutes = message.ReadUnsignedShort();
 }
예제 #4
0
파일: Prey.cs 프로젝트: Cjaker/TibiaUnity3D
        private void ParsePreyData(Internal.CommunicationStream message)
        {
            int slot  = message.ReadUnsignedByte();
            var state = message.ReadEnum <PreySlotStates>();

            switch (state)
            {
            case PreySlotStates.Locked:
            {
                message.ReadEnum <PreySlotUnlockType>();
                break;
            }

            case PreySlotStates.Inactive:
            {
                break;
            }

            case PreySlotStates.Active:
            {
                string monsterName   = message.ReadString();
                var    monsterOutfit = ProtocolGameExtentions.ReadCreatureOutfit(message);
                var    bonusType     = message.ReadEnum <PreyBonusTypes>();
                int    bonusValue    = message.ReadUnsignedShort();
                int    bonusGrade    = message.ReadUnsignedByte();
                int    timeLeft      = message.ReadUnsignedShort();
                break;
            }

            case PreySlotStates.Selection:
            {
                byte size = message.ReadUnsignedByte();
                for (int i = 0; i < size; i++)
                {
                    string monsterName   = message.ReadString();
                    var    monsterOutfit = ProtocolGameExtentions.ReadCreatureOutfit(message);
                }
                break;
            }

            case PreySlotStates.SelectionChangeMonster:
            {
                var  bonusType  = message.ReadEnum <PreyBonusTypes>();
                int  bonusValue = message.ReadUnsignedShort();
                int  bonusGrade = message.ReadUnsignedByte();
                byte size       = message.ReadUnsignedByte();
                for (int i = 0; i < size; i++)
                {
                    string monsterName   = message.ReadString();
                    var    monsterOutfit = ProtocolGameExtentions.ReadCreatureOutfit(message);
                }
                break;
            }

            default:
                break;
            }

            message.ReadUnsignedShort(); // timeUntilFreeListReroll
            if (OpenTibiaUnity.GameManager.ClientVersion >= 1190)
            {
                message.ReadUnsignedByte(); // preyWildCards
            }
        }
예제 #5
0
        private void ParsePlayerStats(Internal.CommunicationStream message)
        {
            int ticks = OpenTibiaUnity.TicksMillis;

            int health    = message.ReadUnsignedShort();
            int maxHealth = message.ReadUnsignedShort();

            Player.SetSkill(SkillType.Health, health, maxHealth, 0);

            int freeCapacity;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameDoubleFreeCapacity))
            {
                freeCapacity = message.ReadInt();
            }
            else
            {
                freeCapacity = message.ReadShort();
            }

            Player.FreeCapacity = freeCapacity;

            int totalCapacity = 0;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameTotalCapacity))
            {
                totalCapacity = message.ReadInt();
            }


            Player.SetSkill(SkillType.Capacity, freeCapacity, totalCapacity, 0);

            long experience;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameDoubleExperience))
            {
                experience = message.ReadLong();
            }
            else
            {
                experience = message.ReadInt();
            }

            Player.SetSkill(SkillType.Experience, experience, 1, 0);

            ushort level        = message.ReadUnsignedShort();
            byte   levelPercent = message.ReadUnsignedByte();

            Player.SetSkill(SkillType.Level, level, 1, levelPercent);

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameExperienceGain))
            {
                float baseXpGain    = message.ReadUnsignedShort() / 100f;
                float voucherAddend = 0;
                if (OpenTibiaUnity.GameManager.ClientVersion < 1150)
                {
                    voucherAddend = message.ReadUnsignedShort() / 100f;
                }
                float grindingAddend     = message.ReadUnsignedShort() / 100f;
                float storeBoostAddend   = message.ReadUnsignedShort() / 100f;
                float huntingBoostFactor = message.ReadUnsignedShort() / 100f;

                Player.ExperienceGainInfo.UpdateGainInfo(baseXpGain, voucherAddend, grindingAddend, storeBoostAddend, huntingBoostFactor);
            }
            else if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameExperienceBonus))
            {
                double experienceBonus = message.ReadDouble();
                Player.ExperienceBonus = experienceBonus;
            }

            int mana    = message.ReadUnsignedShort();
            int maxMana = message.ReadUnsignedShort();

            Player.SetSkill(SkillType.Mana, mana, maxMana, 0);

            if (OpenTibiaUnity.GameManager.ClientVersion < 1200)
            {
                byte magicLevel        = message.ReadUnsignedByte();
                byte baseMagicLevel    = OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameSkillsBase) ? message.ReadUnsignedByte() : magicLevel;
                byte magicLevelPercent = message.ReadUnsignedByte();

                Player.SetSkill(SkillType.MagLevel, magicLevel, baseMagicLevel, magicLevelPercent);
            }

            int soul = message.ReadUnsignedByte();

            Player.SetSkill(SkillType.SoulPoints, soul, 1, 0);

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePlayerStamina))
            {
                int stamina = ticks + 60000 * message.ReadUnsignedShort();
                Player.SetSkill(SkillType.Stamina, stamina, ticks, 0);
            }

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameSkillsBase))
            {
                ushort baseSpeed = message.ReadUnsignedShort();
                Player.SetSkill(SkillType.Speed, Player.GetSkillValue(SkillType.Speed), baseSpeed, 0);
            }

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePlayerRegenerationTime))
            {
                int regeneration = ticks + 1000 * message.ReadUnsignedShort();
                Player.SetSkill(SkillType.Food, regeneration, ticks, 0);
            }

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameOfflineTrainingTime))
            {
                int training = ticks + 60000 * message.ReadUnsignedShort();
                Player.SetSkill(SkillType.OfflineTraining, training, ticks, 0);

                if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameExperienceGain))
                {
                    uint remainingSeconds   = message.ReadUnsignedShort();
                    bool canBuyMoreXpBoosts = message.ReadBoolean();
                    Player.ExperienceGainInfo.UpdateStoreXpBoost(remainingSeconds, canBuyMoreXpBoosts);
                }
            }
        }
예제 #6
0
        private void ParseTalk(Internal.CommunicationStream message)
        {
            uint statementId = 0;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameMessageStatements))
            {
                statementId = message.ReadUnsignedInt();
            }

            string speaker      = message.ReadString();
            ushort speakerLevel = 0;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameMessageLevel))
            {
                speakerLevel = message.ReadUnsignedShort();
            }

            int             rawMode = message.ReadUnsignedByte();
            MessageModeType mode    = TranslateMessageModeFromServer(rawMode);

            Vector3Int?absolutePosition = null;

            Utils.UnionStrInt channelId = null;

            switch (mode)
            {
            case MessageModeType.Say:
            case MessageModeType.Whisper:
            case MessageModeType.Yell:
                absolutePosition = message.ReadPosition();
                channelId        = Chat.ChatStorage.LocalChannelId;
                break;

            case MessageModeType.PrivateFrom:
                channelId = speaker;
                break;

            case MessageModeType.Channel:
            case MessageModeType.ChannelManagement:
            case MessageModeType.ChannelHighlight:
                channelId = message.ReadUnsignedShort();
                break;

            case MessageModeType.Spell:
                absolutePosition = message.ReadPosition();
                channelId        = Chat.ChatStorage.LocalChannelId;
                break;

            case MessageModeType.NpcFromStartBlock:
                absolutePosition = message.ReadPosition();
                break;

            case MessageModeType.NpcFrom:
                break;

            case MessageModeType.GamemasterBroadcast:
                break;

            case MessageModeType.GamemasterChannel:
                channelId = message.ReadUnsignedShort();
                break;

            case MessageModeType.GamemasterPrivateFrom:
                channelId = speaker;
                break;

            case MessageModeType.BarkLow:
            case MessageModeType.BarkLoud:
            case MessageModeType.MonsterSay:
            case MessageModeType.MonsterYell:
                absolutePosition = message.ReadPosition();
                channelId        = -1;
                break;

            case MessageModeType.Game:
                break;

            case MessageModeType.RVRAnswer:
            case MessageModeType.RVRContinue:
                channelId = Chat.ChatStorage.RVRChannelId;
                break;

            case MessageModeType.RVRChannel:
                message.ReadUnsignedInt();
                channelId = Chat.ChatStorage.RVRChannelId;
                break;

            default:
                throw new System.Exception(string.Format("ProtocolGame.ParseTalk: invalid message mode (raw = {0}, mode = {1})", rawMode, mode));
            }

            string text = message.ReadString();

            if (mode != MessageModeType.NpcFromStartBlock && mode != MessageModeType.NpcFrom)
            {
                try {
                    WorldMapStorage.AddOnscreenMessage(absolutePosition, (int)statementId, speaker, speakerLevel, mode, text);
                    if (mode != MessageModeType.BarkLoud)
                    {
                        ChatStorage.AddChannelMessage(channelId, (int)statementId, speaker, speakerLevel, mode, text);
                    }
                } catch (System.Exception e) {
                    throw new System.Exception("ProtocolGame.ParseTalk: Failed to add message: " + e.Message + "\n" + e.StackTrace);
                }
            }
            else if (mode == MessageModeType.NpcFromStartBlock)
            {
                MessageStorage.StartMessageBlock(speaker, absolutePosition, text);
            }
            else if (mode == MessageModeType.NpcFrom)
            {
                MessageStorage.AddTextToBlock(speaker, text);
            }
        }
예제 #7
0
        private void ParseDeleteOnMap(Internal.CommunicationStream message)
        {
            int x = message.ReadUnsignedShort();

            Appearances.ObjectInstance objectInstance;
            Creatures.Creature         creature = null;

            UnityEngine.Vector3Int absolutePosition;
            UnityEngine.Vector3Int mapPosition;

            if (x != 65535)
            {
                absolutePosition = message.ReadPosition(x);

                if (!WorldMapStorage.IsVisible(absolutePosition, true))
                {
                    throw new System.Exception($"ProtocolGame.ParseDeleteOnMap: Co-oridnate ({absolutePosition.x}, {absolutePosition.y}, {absolutePosition.z}) is out of range.");
                }

                mapPosition = WorldMapStorage.ToMap(absolutePosition);

                int stackPos = message.ReadUnsignedByte();
                if (!(objectInstance = WorldMapStorage.GetObject(mapPosition, stackPos)))
                {
                    throw new System.Exception($"ProtocolGame.ParseDeleteOnMap: Object not found.");
                }

                if (objectInstance.IsCreature && (creature = CreatureStorage.GetCreature(objectInstance.Data)) == null)
                {
                    throw new System.Exception($"ProtocolGame.ParseDeleteOnMap: Creature not found.");
                }

                WorldMapStorage.DeleteObject(mapPosition, stackPos);
            }
            else
            {
                uint creatureId = message.ReadUnsignedInt();
                if ((creature = CreatureStorage.GetCreature(creatureId)) == null)
                {
                    throw new System.Exception($"ProtocolGame.ParseDeleteOnMap: Object not found.");
                }

                absolutePosition = creature.Position;
                if (!WorldMapStorage.IsVisible(absolutePosition, true))
                {
                    throw new System.Exception($"ProtocolGame.ParseDeleteOnMap: Co-oridnate ({absolutePosition.x}, {absolutePosition.y}, {absolutePosition.z}) is out of range.");
                }

                mapPosition = WorldMapStorage.ToMap(absolutePosition);
            }

            if (!!creature)
            {
                CreatureStorage.MarkOpponentVisible(creature, false);
            }

            if (absolutePosition.z == MiniMapStorage.Position.z)
            {
                WorldMapStorage.UpdateMiniMap(mapPosition);
                uint color = WorldMapStorage.GetMiniMapColour(mapPosition);
                int  cost  = WorldMapStorage.GetMiniMapCost(mapPosition);
                MiniMapStorage.UpdateField(absolutePosition, color, cost, false);
            }

            WorldMapStorage.CacheRefresh = true;
        }
예제 #8
0
        private void ParseMonsterCyclopediaRace(Internal.CommunicationStream message)
        {
            ushort raceID         = message.ReadUnsignedShort();
            var    classification = message.ReadString();

            int  unlockState = message.ReadUnsignedByte();
            uint totalKills  = message.ReadUnsignedInt();

            int killsToFirstDetailStage  = message.ReadUnsignedShort();
            int killsToSecondDetailStage = message.ReadUnsignedShort();
            int killsToThirdDetailStage  = message.ReadUnsignedShort();

            if (unlockState >= 1)
            {
                var difficulty = message.ReadEnum <CyclopediaRaceDifficulty>();
                var occurrence = message.ReadEnum <CyclopediaRaceOccurence>();

                int count = message.ReadUnsignedByte();
                for (int i = 0; i < count; i++)
                {
                    ushort objectID         = message.ReadUnsignedShort();
                    var    rarity           = message.ReadEnum <CyclopediaRaceLootRarity>();
                    bool   specialEventLoot = message.ReadBoolean();
                    if (objectID != 0)
                    {
                        var objectName = message.ReadString();
                        var lootType   = message.ReadEnum <CyclopediaRaceLootType>();
                    }
                }
            }

            if (unlockState >= 2)
            {
                ushort charmPoints           = message.ReadUnsignedShort();
                var    attackType            = message.ReadEnum <CyclopediaRaceAttackType>();
                bool   castSpellsOrUseSkills = message.ReadBoolean(); // shows the icon of spells
                uint   health     = message.ReadUnsignedInt();
                uint   experience = message.ReadUnsignedInt();
                ushort speed      = message.ReadUnsignedShort();
                ushort armor      = message.ReadUnsignedShort();
            }

            if (unlockState >= 3)
            {
                int count = message.ReadUnsignedByte();
                for (int i = 0; i < count; i++)
                {
                    var combatType = message.ReadEnum <CyclopediaCombatType>();
                    int value      = message.ReadShort();
                }

                count = message.ReadUnsignedShort();
                for (int i = 0; i < count; i++)
                {
                    string location = message.ReadString();
                }
            }

            if (unlockState >= 4)
            {
                bool hasCharmSelected = message.ReadBoolean();
                if (hasCharmSelected)
                {
                    int selectedCharmID = message.ReadUnsignedByte();
                    int unknown0        = message.ReadUnsignedByte();
                    int unknown1        = message.ReadUnsignedByte();
                    int unknown2        = message.ReadUnsignedByte();
                }

                bool canSelectCharm = message.ReadBoolean();
            }
        }
예제 #9
0
        private Creatures.Creature ReadCreatureInstance(Internal.CommunicationStream message, int type = -1,
                                                        UnityEngine.Vector3Int?absolutePosition        = null)
        {
            if (type == -1)
            {
                type = message.ReadUnsignedShort();
            }

            if (type != AppearanceInstance.Creature && type != AppearanceInstance.OutdatedCreature && type != AppearanceInstance.UnknownCreature)
            {
                throw new System.Exception("ProtocolGame.ReadCreatureInstance: Invalid creature type");
            }

            var gameManager = OpenTibiaUnity.GameManager;

            Creatures.Creature creature;
            switch (type)
            {
            case AppearanceInstance.UnknownCreature:
            case AppearanceInstance.OutdatedCreature: {
                if (type == AppearanceInstance.UnknownCreature)
                {
                    uint         removeId = message.ReadUnsignedInt();
                    uint         newId    = message.ReadUnsignedInt();
                    CreatureType creatureType;

                    if (gameManager.ClientVersion >= 910)
                    {
                        creatureType = message.ReadEnum <CreatureType>();
                    }
                    else
                    {
                        if (newId >= Constants.PlayerStartId && newId < Constants.PlayerEndId)
                        {
                            creatureType = CreatureType.Player;
                        }
                        else if (newId >= Constants.MonsterStartId && newId < Constants.MonsterEndId)
                        {
                            creatureType = CreatureType.Monster;
                        }
                        else
                        {
                            creatureType = CreatureType.NPC;
                        }
                    }

                    if (newId == Player.Id)
                    {
                        creature = Player;
                    }
                    else
                    {
                        creature = new Creatures.Creature(newId);
                    }

                    creature = CreatureStorage.ReplaceCreature(creature, removeId);
                    if (!creature)
                    {
                        throw new System.Exception("ProtocolGame.ReadCreatureInstance: Failed to append creature.");
                    }

                    creature.Type = creatureType;
                    if (gameManager.ClientVersion >= 1120)
                    {
                        creature.SetSummonerId(creature.IsSummon ? message.ReadUnsignedInt() : 0);
                    }

                    creature.Name = message.ReadString();
                }
                else
                {
                    uint creatureId = message.ReadUnsignedInt();
                    creature = CreatureStorage.GetCreature(creatureId);
                    if (!creature)
                    {
                        throw new System.Exception("ProtocolGame.ReadCreatureInstance: Outdated creature not found.");
                    }
                }

                creature.SetSkill(SkillType.HealthPercent, message.ReadUnsignedByte());
                creature.Direction = message.ReadEnum <Direction>();
                creature.Outfit    = ReadCreatureOutfit(message, creature.Outfit);
                if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePlayerMounts))
                {
                    creature.MountOutfit = ReadMountOutfit(message, creature.MountOutfit);
                }
                creature.Brightness = message.ReadUnsignedByte();
                creature.LightColor = Colors.ColorFrom8Bit(message.ReadUnsignedByte());
                creature.SetSkill(SkillType.Speed, message.ReadUnsignedShort());
                creature.SetPKFlag(message.ReadEnum <PKFlag>());
                creature.SetPartyFlag(message.ReadEnum <PartyFlag>());

                if (gameManager.GetFeature(GameFeature.GameCreatureEmblems) && type == AppearanceInstance.UnknownCreature)
                {
                    creature.SetGuildFlag(message.ReadEnum <GuildFlag>());
                }

                if (gameManager.GetFeature(GameFeature.GameCreatureMarks))
                {
                    creature.Type = message.ReadEnum <CreatureType>();
                    if (gameManager.ClientVersion >= 1120)
                    {
                        creature.SetSummonerId(creature.IsSummon ? message.ReadUnsignedInt() : 0);
                    }
                }

                if (gameManager.ClientVersion >= 1220 && creature.Type == CreatureType.Player)
                {
                    byte unknown = message.ReadUnsignedByte();     // suggestion: boolean isFriend (friend system)
                }

                if (gameManager.GetFeature(GameFeature.GameCreatureIcons))
                {
                    creature.SetSpeechCategory(message.ReadEnum <SpeechCategory>());
                }

                if (gameManager.GetFeature(GameFeature.GameCreatureMarks))
                {
                    creature.Marks.SetMark(MarkType.Permenant, message.ReadUnsignedByte());

                    if (gameManager.GetFeature(GameFeature.GameInspectionWindow))
                    {
                        message.ReadUnsignedByte();     // inspection state
                    }
                    if (gameManager.ClientVersion < 1185)
                    {
                        creature.NumberOfPvPHelpers = message.ReadUnsignedShort();
                    }
                }

                if (gameManager.ClientVersion >= 854)
                {
                    creature.Unpassable = message.ReadUnsignedByte() != 0;
                }
                else
                {
                    creature.Unpassable = true;
                }
                break;
            }

            case AppearanceInstance.Creature: {
                uint creatureId = message.ReadUnsignedInt();
                creature = CreatureStorage.GetCreature(creatureId);
                if (!creature)
                {
                    throw new System.Exception(string.Format("ProtocolGame.ReadCreatureInstance: Known creature not found ({0}).", creatureId));
                }

                creature.Direction = message.ReadEnum <Direction>();

                if (gameManager.ClientVersion >= 953)
                {
                    creature.Unpassable = message.ReadUnsignedByte() != 0;
                }
                break;
            }

            default:
                throw new System.Exception("ProtocolGame.ReadCreatureInstance: unknown creature identity type.");
            }

            if (absolutePosition.HasValue)
            {
                creature.Position = absolutePosition.Value;
            }

            CreatureStorage.MarkOpponentVisible(creature, true);
            CreatureStorage.InvalidateOpponents();
            return(creature);
        }
예제 #10
0
        private void ParseChangeOnMap(Internal.CommunicationStream message)
        {
            int x = message.ReadUnsignedShort();

            Appearances.ObjectInstance objectInstance;
            Creatures.Creature         creature = null;

            UnityEngine.Vector3Int absolutePosition;
            UnityEngine.Vector3Int mapPosition;

            if (x != 65535)
            {
                absolutePosition = message.ReadPosition(x);
                if (!WorldMapStorage.IsVisible(absolutePosition, true))
                {
                    throw new System.Exception("ProtocolGame.ParseChangeOnMap: Co-ordinate " + absolutePosition + " is out of range.");
                }

                mapPosition = WorldMapStorage.ToMap(absolutePosition);
                int stackPos = message.ReadUnsignedByte();
                if (!(objectInstance = WorldMapStorage.GetObject(mapPosition, stackPos)))
                {
                    throw new System.Exception("ProtocolGame.ParseChangeOnMap: Object not found.");
                }

                if (objectInstance.IsCreature && !(creature = CreatureStorage.GetCreature(objectInstance.Data)))
                {
                    throw new System.Exception("ProtocolGame.ParseChangeOnMap: Creature not found: " + objectInstance.Data);
                }

                if (!!creature)
                {
                    CreatureStorage.MarkOpponentVisible(creature, false);
                }

                int typeOrId = message.ReadUnsignedShort();
                if (typeOrId == Appearances.AppearanceInstance.UnknownCreature ||
                    typeOrId == Appearances.AppearanceInstance.OutdatedCreature ||
                    typeOrId == Appearances.AppearanceInstance.Creature)
                {
                    creature       = ProtocolGameExtentions.ReadCreatureInstance(message, typeOrId, absolutePosition);
                    objectInstance = AppearanceStorage.CreateObjectInstance(Appearances.AppearanceInstance.Creature, creature.Id);
                }
                else
                {
                    objectInstance = ProtocolGameExtentions.ReadObjectInstance(message, typeOrId);
                }

                WorldMapStorage.ChangeObject(mapPosition, stackPos, objectInstance);
            }
            else
            {
                uint creatureId = message.ReadUnsignedInt();

                if (!(creature = CreatureStorage.GetCreature(creatureId)))
                {
                    throw new System.Exception("ProtocolGame.ParseChangeOnMap: Creature " + creatureId + " not found");
                }

                absolutePosition = creature.Position;
                if (!WorldMapStorage.IsVisible(absolutePosition, true))
                {
                    throw new System.Exception("ProtocolGame.ParseChangeOnMap: Co-ordinate " + absolutePosition + " is out of range.");
                }

                mapPosition = WorldMapStorage.ToMap(absolutePosition);
                CreatureStorage.MarkOpponentVisible(creature, false);

                int otherType = message.ReadUnsignedShort();
                if (otherType == Appearances.AppearanceInstance.Creature || otherType == Appearances.AppearanceInstance.OutdatedCreature ||
                    otherType == Appearances.AppearanceInstance.UnknownCreature)
                {
                    creature = ProtocolGameExtentions.ReadCreatureInstance(message, otherType);
                }
                else
                {
                    throw new System.Exception("ProtocolGame.ParseChangeOnMap: Received object of type " + otherType + " when a creature was expected.");
                }
            }

            if (absolutePosition.z == MiniMapStorage.PositionZ)
            {
                WorldMapStorage.UpdateMiniMap(mapPosition);
                uint color = WorldMapStorage.GetMiniMapColour(mapPosition);
                int  cost  = WorldMapStorage.GetMiniMapCost(mapPosition);
                MiniMapStorage.UpdateField(absolutePosition, color, cost, false);
            }

            WorldMapStorage.CacheRefresh = true;
        }
예제 #11
0
        public void Parse(Internal.CommunicationStream message)
        {
            if (OpenTibiaUnity.GameManager.ClientVersion >= 1010)
            {
                byte worlds = message.ReadUnsignedByte();
                for (int i = 0; i < worlds; i++)
                {
                    var world = new World {
                        _id      = message.ReadUnsignedByte(),
                        Name     = message.ReadString(),
                        HostName = message.ReadString(),
                        Port     = message.ReadUnsignedShort(),
                        Preview  = message.ReadBoolean()
                    };
                    Worlds.Add(world);
                }

                byte characters = message.ReadUnsignedByte();
                for (int i = 0; i < characters; i++)
                {
                    Character character = new Character {
                        WorldId = message.ReadUnsignedByte(),
                        Name    = message.ReadString()
                    };
                    Characters.Add(character);
                }
            }
            else
            {
                byte characters = message.ReadUnsignedByte();
                for (int i = 0; i < characters; i++)
                {
                    var characterName = message.ReadString();
                    var worldName     = message.ReadString();
                    var worldIpLong   = message.ReadUnsignedInt();
                    var worldPort     = message.ReadUnsignedShort();

                    var world     = GetOrCreateWorld(worldName, worldIpLong, worldPort);
                    var character = new Character {
                        Name    = characterName,
                        WorldId = world._id
                    };
                    Characters.Add(character);
                }
            }

            uint now = (uint)System.DateTime.Now.Second;

            if (OpenTibiaUnity.GameManager.ClientVersion >= 1077)
            {
                AccountState     = message.ReadUnsignedByte();
                IsPremium        = message.ReadBoolean();
                PremiumTimeStamp = message.ReadUnsignedInt();
                if (PremiumTimeStamp > now)
                {
                    PremiumDays = (ushort)((PremiumTimeStamp - now) / 86400U);
                }
                else
                {
                    PremiumDays = 0;
                }

                InfinitePremium = (IsPremium && PremiumTimeStamp == 0);
            }
            else
            {
                AccountState = 0;
                PremiumDays  = message.ReadUnsignedShort();
                if (PremiumDays > 0)
                {
                    PremiumTimeStamp = now + PremiumDays * 86400U;
                }
                else
                {
                    PremiumTimeStamp = 0;
                }

                IsPremium       = PremiumDays > 0;
                InfinitePremium = PremiumDays == 65535;
            }
        }
예제 #12
0
        private void ParseTextMessage(Internal.CommunicationStream message)
        {
            var rawMode = message.ReadUnsignedByte();
            var mode    = TranslateMessageModeFromServer(rawMode);

            try {
                int    channelId = 0;
                string text      = null;

                switch (mode)
                {
                case MessageModeType.ChannelManagement:
                    channelId = message.ReadUnsignedShort();
                    text      = message.ReadString();
                    // TODO name filter
                    //var regex = new System.Text.RegularExpressions.Regex(@"^(.+?) invites you to |^You have been excluded from the channel ([^']+)'s Channel\.$");
                    //var match = regex.Match(text);
                    //string speaker = match != null && match.Success ? match.Value : null;

                    WorldMapStorage.AddOnscreenMessage(null, -1, null, 0, mode, text);
                    ChatStorage.AddChannelMessage(channelId, -1, null, 0, mode, text);
                    break;

                case MessageModeType.Guild:
                case MessageModeType.PartyManagement:
                case MessageModeType.Party:
                    channelId = message.ReadUnsignedShort();
                    text      = message.ReadString();
                    WorldMapStorage.AddOnscreenMessage(null, -1, null, 0, mode, text);
                    ChatStorage.AddChannelMessage(channelId, -1, null, 0, mode, text);
                    break;

                case MessageModeType.Login:
                case MessageModeType.Admin:
                case MessageModeType.Game:
                case MessageModeType.GameHighlight:
                case MessageModeType.Failure:
                case MessageModeType.Look:
                case MessageModeType.Status:
                case MessageModeType.Loot:
                case MessageModeType.TradeNpc:
                case MessageModeType.HotkeyUse:
                case MessageModeType.BoostedCreature:
                    channelId = -1;
                    text      = message.ReadString();
                    WorldMapStorage.AddOnscreenMessage(null, -1, null, 0, mode, text);
                    ChatStorage.AddChannelMessage(channelId, -1, null, 0, mode, text);
                    break;

                case MessageModeType.Market:
                    text = message.ReadString();
                    // TODO: market
                    break;

                case MessageModeType.Report:
                    // TODO
                    //ReportWidget.s_ReportTimestampReset();
                    text = message.ReadString();
                    WorldMapStorage.AddOnscreenMessage(null, -1, null, 0, mode, text);
                    ChatStorage.AddChannelMessage(-1, -1, null, 0, mode, text);
                    break;

                case MessageModeType.DamageDealed:
                case MessageModeType.DamageReceived:
                case MessageModeType.DamageOthers:
                    Vector3Int absolutePosition = message.ReadPosition();
                    int        value            = message.ReadInt();
                    int        color            = message.ReadUnsignedByte();
                    if (value > 0)
                    {
                        WorldMapStorage.AddOnscreenMessage(absolutePosition, -1, null, 0, mode, value, color);
                    }

                    value = message.ReadInt();
                    color = message.ReadUnsignedByte();
                    if (value > 0)
                    {
                        WorldMapStorage.AddOnscreenMessage(absolutePosition, -1, null, 0, mode, value, color);
                    }

                    text = message.ReadString();
                    ChatStorage.AddChannelMessage(-1, -1, null, 0, mode, text);
                    break;

                case MessageModeType.Heal:
                case MessageModeType.Mana:
                case MessageModeType.Exp:
                case MessageModeType.HealOthers:
                case MessageModeType.ExpOthers:
                    absolutePosition = message.ReadPosition();
                    value            = message.ReadInt();
                    color            = message.ReadUnsignedByte();
                    WorldMapStorage.AddOnscreenMessage(absolutePosition, -1, null, 0, mode, value, color);

                    text = message.ReadString();
                    ChatStorage.AddChannelMessage(-1, -1, null, 0, mode, text);
                    break;

                default:
                    text = message.ReadString();
                    ChatStorage.AddChannelMessage(-1, -1, null, 0, mode, text);
                    break;
                }
            } catch (System.Exception e) {
                throw new System.Exception("ProtocolGame.ParseTextMessage: Failed to add message of type " + rawMode + ": " + e.Message + "\n" + e.StackTrace);
            }
        }
예제 #13
0
        private void ParseCloseChannel(Internal.CommunicationStream message)
        {
            int channelId = message.ReadUnsignedShort();

            ChatStorage.CloseChannel(channelId);
        }
예제 #14
0
        private void ParseCyclopediaMapData(Internal.CommunicationStream message)
        {
            int dataType = message.ReadUnsignedByte();

            // unfinished packet, more information needed....
            switch (dataType)
            {
            case 0:
            {         // StaticMarker (sure)
                var    position        = message.ReadPosition();
                int    markType        = message.ReadUnsignedByte();
                string markDescription = message.ReadString();
                break;
            }

            case 1:
            {         // idk?
                int count = message.ReadUnsignedShort();
                for (int i = 0; i < count; i++)
                {
                    // UnlockedArea (struct)
                    int unknown1 = message.ReadUnsignedByte();         // unknown
                    int unknown2 = message.ReadUnsignedByte();         // unknown
                    int unknown3 = message.ReadUnsignedByte();         // (enum) maximum value: 3
                    int unknown4 = message.ReadUnsignedByte();         // unknown
                }

                count = message.ReadUnsignedShort();
                for (int i = 0; i < count; i++)
                {
                    ushort unknown = message.ReadUnsignedShort();         // unknown
                }

                count = message.ReadUnsignedShort();
                for (int i = 0; i < count; i++)
                {
                    ushort unknown = message.ReadUnsignedShort();         // unknown
                }

                break;
            }

            case 2:
            {         // Raid (sure)
                var  position = message.ReadPosition();
                bool inactive = message.ReadBoolean();
                break;
            }

            case 3:
            {                               // ImminentRaid (not sure)
                message.ReadUnsignedByte(); // unknown
                message.ReadUnsignedByte(); // unknown
                message.ReadUnsignedByte(); // unknown
                break;
            }

            case 4:
            {                               // ViewPoints (not sure)
                message.ReadUnsignedByte(); // unknown
                message.ReadUnsignedByte(); // unknown
                message.ReadUnsignedByte(); // unknown
                break;
            }


            case 5:
            {                                                   // idk? (but it unlocks areas)
                ushort areaId    = message.ReadUnsignedShort(); // this is likely to be areaId
                byte   totalPois = message.ReadUnsignedByte();  // unknown

                // points of interest unlocked!
                int poiCount = message.ReadUnsignedByte();
                for (int i = 0; i < poiCount; i++)
                {
                    // point of interest
                    var position = message.ReadPosition();
                    int unknown6 = message.ReadUnsignedByte();
                }

                break;
            }

            case 6:
            {
                break;
            }

            case 7:
            {
                break;
            }

            case 8:
            {
                break;
            }

            case 9:
            {
                //
                uint maximumGold = message.ReadUnsignedInt();      // maximum gold? (used for progress)
                uint unknown2    = message.ReadUnsignedInt();      // unknown

                // these are area donations,
                byte listCount = message.ReadUnsignedByte();
                for (int i = 0; i < listCount; i++)
                {
                    // ushort areaId, uint gold contributed
                    //
                    uint unknown5 = message.ReadUnsignedShort();
                    uint unknown3 = message.ReadUnsignedInt();
                    uint unknown4 = message.ReadUnsignedInt();
                    uint unknown6 = message.ReadUnsignedByte();
                }
                break;
            }

            case 10:
            {
                ushort unknown = message.ReadUnsignedShort();
                break;
            }

            case 11:
            {
                break;
            }
            }
        }
예제 #15
0
        private void ParseCreatureMove(Internal.CommunicationStream message)
        {
            int x = message.ReadUnsignedShort();

            UnityEngine.Vector3Int oldAbsolutePosition;
            UnityEngine.Vector3Int oldMapPosition;
            int stackPos = -1;

            Appearances.ObjectInstance @object;
            Creatures.Creature         creature;

            if (x != 65535)
            {
                oldAbsolutePosition = message.ReadPosition(x);
                if (!WorldMapStorage.IsVisible(oldAbsolutePosition, true))
                {
                    throw new System.Exception("ProtocolGame.ParseCreatureMove: Start Co-ordinate " + oldAbsolutePosition + " is out of range.");
                }

                oldMapPosition = WorldMapStorage.ToMap(oldAbsolutePosition);
                stackPos       = message.ReadUnsignedByte();

                @object = WorldMapStorage.GetObject(oldMapPosition, stackPos);
                if (!@object || [email protected] || !(creature = CreatureStorage.GetCreature(@object.Data)))
                {
                    throw new System.Exception("ProtocolGame.ParseCreatureMove: No creature at position " + oldAbsolutePosition);
                }
            }
            else
            {
                uint creatureId = message.ReadUnsignedInt();
                @object = AppearanceStorage.CreateObjectInstance(Appearances.AppearanceInstance.Creature, creatureId);
                if (!(creature = CreatureStorage.GetCreature(creatureId)))
                {
                    throw new System.Exception("ProtocolGame.ParseCreatureMove: Creature " + creatureId + " not found");
                }

                oldAbsolutePosition = creature.Position;
                if (!WorldMapStorage.IsVisible(oldAbsolutePosition, true))
                {
                    throw new System.Exception("ProtocolGame.ParseCreatureMove: Start Co-ordinate " + oldAbsolutePosition + " is out of range.");
                }

                oldMapPosition = WorldMapStorage.ToMap(oldAbsolutePosition);
            }

            var newAbsolutePosition = message.ReadPosition();

            if (!WorldMapStorage.IsVisible(newAbsolutePosition, true))
            {
                throw new System.Exception("ProtocolGame.ParseCreatureMove: Target Co-ordinate " + oldAbsolutePosition + " is out of range.");
            }

            var newMapPosition = WorldMapStorage.ToMap(newAbsolutePosition);
            var delta          = newMapPosition - oldMapPosition;

            // if the movement is not actually a move (usually he is teleported)
            bool pushMovement = delta.z != 0 || System.Math.Abs(delta.x) > 1 || System.Math.Abs(delta.y) > 1;

            Appearances.ObjectInstance otherObj = null;
            if (!pushMovement && (!(otherObj = WorldMapStorage.GetObject(newMapPosition, 0)) || !otherObj.Type || !otherObj.Type.IsGround))
            {
                throw new System.Exception("ProtocolGame.ParseCreatureMove: Target field " + newAbsolutePosition + " has no BANK.");
            }

            if (x != 65535)
            {
                WorldMapStorage.DeleteObject(oldMapPosition, stackPos);
            }

            WorldMapStorage.PutObject(newMapPosition, @object);
            creature.Position = newAbsolutePosition;

            if (pushMovement)
            {
                if (creature.Id == Player.Id)
                {
                    Player.StopAutowalk(true);
                }

                if (delta.x > 0)
                {
                    creature.Direction = Direction.East;
                }
                else if (delta.x < 0)
                {
                    creature.Direction = Direction.West;
                }
                else if (delta.y < 0)
                {
                    creature.Direction = Direction.North;
                }
                else if (delta.y > 0)
                {
                    creature.Direction = Direction.South;
                }

                if (creature.Id != Player.Id)
                {
                    creature.StopMovementAnimation();
                }
            }
            else
            {
                creature.StartMovementAnimation(delta.x, delta.y, (int)otherObj.Type.GroundSpeed);
            }

            CreatureStorage.MarkOpponentVisible(creature, true);
            CreatureStorage.InvalidateOpponents();

            if (oldAbsolutePosition.z == MiniMapStorage.PositionZ)
            {
                WorldMapStorage.UpdateMiniMap(oldMapPosition);
                uint color = WorldMapStorage.GetMiniMapColour(oldMapPosition);
                int  cost  = WorldMapStorage.GetMiniMapCost(oldMapPosition);
                MiniMapStorage.UpdateField(oldAbsolutePosition, color, cost, false);
            }

            if (newAbsolutePosition.z == MiniMapStorage.PositionZ)
            {
                WorldMapStorage.UpdateMiniMap(newMapPosition);
                uint color = WorldMapStorage.GetMiniMapColour(newMapPosition);
                int  cost  = WorldMapStorage.GetMiniMapCost(newMapPosition);
                MiniMapStorage.UpdateField(newAbsolutePosition, color, cost, false);
            }

            WorldMapStorage.CacheRefresh = true;
        }
예제 #16
0
        private void ReadCyclopediaCharacterInfoGeneralStats(Internal.CommunicationStream message)
        {
            ulong  experience   = message.ReadUnsignedLong();
            ushort level        = message.ReadUnsignedShort();
            int    levelPercent = message.ReadUnsignedByte();

            float baseXpGain         = message.ReadUnsignedShort() / 100f;
            float grindingAddend     = message.ReadUnsignedShort() / 100f;
            float storeBoostAddend   = message.ReadUnsignedShort() / 100f;
            float huntingBoostFactor = message.ReadUnsignedShort() / 100f;

            message.ReadUnsignedShort(); // yet unknown
            bool canBuyXpBoost = message.ReadBoolean();

            int health    = message.ReadUnsignedShort();
            int maxHealth = message.ReadUnsignedShort();
            int mana      = message.ReadUnsignedShort();
            int maxMana   = message.ReadUnsignedShort();
            int soul      = message.ReadUnsignedByte();

            int ticks        = OpenTibiaUnity.TicksMillis;
            int stamina      = ticks + 60000 * message.ReadUnsignedShort();
            int regeneration = ticks + 1000 * message.ReadUnsignedShort();
            int training     = ticks + 60000 * message.ReadUnsignedShort();

            int speed     = message.ReadUnsignedShort();
            int baseSpeed = message.ReadUnsignedShort();

            uint totalCapacity = message.ReadUnsignedInt();
            uint baseCapacity  = message.ReadUnsignedInt();
            uint freeCapacity  = message.ReadUnsignedInt();

            int skillCount = message.ReadUnsignedByte();

            for (int i = 0; i < skillCount; i++)
            {
                var skillType = message.ReadEnum <SkillType>();
                var skill     = ReadSkill(message);
            }
        }
예제 #17
0
        private void ParseWait(Internal.CommunicationStream message)
        {
            ushort ticks = message.ReadUnsignedShort();

            Player.EarliestMoveTime += ticks;
        }
예제 #18
0
        private DailyReward.DailyReward ReadDailyReward(Internal.CommunicationStream message)
        {
            var rewardType = message.ReadEnum <DailyRewardType>();
            var reward     = new DailyReward.DailyReward(rewardType);

            switch (rewardType)
            {
            case DailyRewardType.PickedItems:
            {
                reward.AllowedMaximumItems = message.ReadUnsignedByte();
                int objectCount = message.ReadUnsignedByte();

                for (int i = 0; i < objectCount; i++)
                {
                    ushort objectId     = message.ReadUnsignedShort();
                    string objectName   = message.ReadString();
                    uint   objectWeight = message.ReadUnsignedInt();

                    reward.AddItem(new DailyReward.Types.Object(objectId, objectName, objectWeight, -1));
                }

                break;
            }

            case DailyRewardType.FixedItems:
            {
                int itemsCount = message.ReadUnsignedByte();
                for (int i = 0; i < itemsCount; i++)
                {
                    var subType = message.ReadEnum <DailyRewardSubType>();
                    switch (subType)
                    {
                    case DailyRewardSubType.Object:
                    {
                        ushort objectId     = message.ReadUnsignedShort();
                        string objectName   = message.ReadString();
                        int    objectAmount = message.ReadUnsignedByte();

                        reward.AddItem(new DailyReward.Types.Object(objectId, objectName, 0, objectAmount));
                        break;
                    }

                    case DailyRewardSubType.PreyBonusRerolls:
                    {
                        int amount = message.ReadUnsignedByte();
                        reward.AddItem(new DailyReward.Types.PreyBonusRerolls(amount));
                        break;
                    }

                    case DailyRewardSubType.FiftyPercentXpBoost:
                    {
                        ushort minutes = message.ReadUnsignedShort();
                        reward.AddItem(new DailyReward.Types.XpBoost(minutes));
                        break;
                    }

                    default:
                        throw new System.Exception("ProtocolGame.ReadDailyReward: Invalid reward sub-type " + (int)subType + ".");
                    }
                }

                break;
            }
            }

            return(reward);
        }
예제 #19
0
 private void ParseItemWasted(Internal.CommunicationStream message)
 {
     ushort objectId = message.ReadUnsignedShort();
 }
예제 #20
0
        private void ParseOutfitDialog(Internal.CommunicationStream message)
        {
            var outfit = ProtocolGameExtentions.ReadCreatureOutfit(message);

            Appearances.AppearanceInstance mountOutfit = null;
            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePlayerMounts))
            {
                mountOutfit = ProtocolGameExtentions.ReadMountOutfit(message);
            }

            var outfitList = new List <ProtocolOutfit>();

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameNewOutfitProtocol))
            {
                int count;
                if (OpenTibiaUnity.GameManager.ClientVersion >= 1185)
                {
                    count = message.ReadUnsignedShort();
                }
                else
                {
                    count = message.ReadUnsignedByte();
                }

                for (int i = 0; i < count; i++)
                {
                    outfitList.Add(ReadNewProtocolOutfit(message));
                }
            }
            else
            {
                ushort outfitStart, outfitEnd;
                if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameOutfitIdU16))
                {
                    outfitStart = message.ReadUnsignedShort();
                    outfitEnd   = message.ReadUnsignedShort();
                }
                else
                {
                    outfitStart = message.ReadUnsignedByte();
                    outfitEnd   = message.ReadUnsignedByte();
                }

                for (ushort i = outfitStart; i <= outfitEnd; i++)
                {
                    outfitList.Add(new ProtocolOutfit()
                    {
                        _id = i
                    });
                }
            }

            List <ProtocolMount> mountList = null;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePlayerMounts))
            {
                mountList = new List <ProtocolMount>();
                int count;
                if (OpenTibiaUnity.GameManager.ClientVersion >= 1185)
                {
                    count = message.ReadUnsignedShort();
                }
                else
                {
                    count = message.ReadUnsignedByte();
                }

                for (int i = 0; i < count; i++)
                {
                    mountList.Add(ReadProtocolMount(message));
                }
            }

            OutfitDialogType type = 0;

            if (OpenTibiaUnity.GameManager.ClientVersion >= 1185)
            {
                type = message.ReadEnum <OutfitDialogType>();
                bool mounted = message.ReadBoolean();
            }

            OpenTibiaUnity.GameManager.onRequestOutfitDialog.Invoke(outfit, mountOutfit, outfitList, mountList);
        }
예제 #21
0
        private PlayData ReadPlayData(Internal.CommunicationStream stream)
        {
            var playData = new PlayData();

            if (OpenTibiaUnity.GameManager.ClientVersion >= 1010)
            {
                byte worldCount = stream.ReadUnsignedByte();
                for (int i = 0; i < worldCount; i++)
                {
                    int    id       = stream.ReadUnsignedByte();
                    string name     = stream.ReadString();
                    string hostname = stream.ReadString();
                    ushort port     = stream.ReadUnsignedShort();
                    bool   preview  = stream.ReadBoolean();

                    playData.Worlds.Add(new PlayData.PlayDataWorld
                    {
                        Id              = id,
                        Name            = name,
                        ExternalAddress = hostname,
                        ExternalPort    = port,
                        PreviewState    = preview ? 1 : 0
                    });
                }

                byte characterCount = stream.ReadUnsignedByte();
                for (int i = 0; i < characterCount; i++)
                {
                    var    worldId = stream.ReadUnsignedByte();
                    string name    = stream.ReadString();

                    playData.Characters.Add(new PlayData.PlayDataCharacter
                    {
                        WorldId = worldId,
                        Name    = name
                    });
                }
            }
            else
            {
                int characterCount = stream.ReadUnsignedByte();
                for (int i = 0; i < characterCount; i++)
                {
                    string characterName = stream.ReadString();
                    string worldName     = stream.ReadString();
                    uint   worldIpLong   = stream.ReadUnsignedInt();
                    ushort worldPort     = stream.ReadUnsignedShort();

                    int worldId = 0;
                    int index   = playData.Worlds.FindIndex(x => x.Name == worldName);
                    if (index == -1)
                    {
                        worldId = playData.Worlds.Count;
                        playData.Worlds.Add(new PlayData.PlayDataWorld
                        {
                            Id              = worldId,
                            Name            = worldName,
                            ExternalAddress = new System.Net.IPAddress((long)worldIpLong).ToString(),
                            ExternalPort    = worldPort
                        });
                    }
                    else
                    {
                        worldId = playData.Worlds[index].Id;
                    }

                    playData.Characters.Add(new PlayData.PlayDataCharacter
                    {
                        Name    = characterName,
                        WorldId = worldId
                    });
                }
            }

            uint now = (uint)System.DateTime.Now.Second;

            if (OpenTibiaUnity.GameManager.ClientVersion >= 1077)
            {
                stream.ReadUnsignedByte(); // todo map accountState to strings
                playData.Session.IsPremium       = stream.ReadBoolean();
                playData.Session.PremiumUntil    = stream.ReadUnsignedInt();
                playData.Session.InfinitePremium = playData.Session.IsPremium && playData.Session.PremiumUntil == 0;
            }
            else
            {
                uint premiumDays = stream.ReadUnsignedShort();
                playData.Session.IsPremium       = premiumDays > 0;
                playData.Session.PremiumUntil    = premiumDays > 0 ? (now + premiumDays * 86400U) : 0;
                playData.Session.InfinitePremium = premiumDays == ushort.MaxValue;
            }
            return(playData);
        }