private void ParseOpenContainer(Internal.CommunicationStream message) { byte containerId = message.ReadUnsignedByte(); var objectIcon = ProtocolGameExtentions.ReadObjectInstance(message); string name = message.ReadString(); byte nOfSlotsPerPage = message.ReadUnsignedByte(); // capacity of shown view bool isSubContainer = message.ReadBoolean(); bool canUseDepotSearch = false; bool isDragAndDropEnabled = true; bool isPaginationEnabled = false; int nOfTotalObjects; int indexOfFirstObject = 0; int nOfContentObjects; // objects in the current shown view // if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameContainerPagination)) { if (OpenTibiaUnity.GameManager.ClientVersion >= 1220) { canUseDepotSearch = message.ReadBoolean(); } isDragAndDropEnabled = message.ReadBoolean(); isPaginationEnabled = message.ReadBoolean(); nOfTotalObjects = message.ReadUnsignedShort(); indexOfFirstObject = message.ReadUnsignedShort(); nOfContentObjects = message.ReadUnsignedByte(); if (nOfContentObjects > nOfSlotsPerPage) { throw new System.Exception("ProtocolGame.ParseOpenContainer: Number of content objects " + nOfContentObjects + " exceeds number of slots per page " + nOfSlotsPerPage); } if (nOfContentObjects > nOfTotalObjects) { throw new System.Exception("ProtocolGame.ParseOpenContainer: Number of content objects " + nOfContentObjects + " exceeds number of total objects " + nOfTotalObjects); } } else { nOfContentObjects = message.ReadUnsignedByte(); nOfTotalObjects = nOfContentObjects; if (nOfContentObjects > nOfSlotsPerPage) { throw new System.Exception("ProtocolGame.ParseOpenContainer: Number of content objects " + nOfContentObjects + " exceeds the capaciy " + nOfSlotsPerPage); } } var containerView = ContainerStorage.CreateContainerView(containerId, objectIcon, name, isSubContainer, isDragAndDropEnabled, isPaginationEnabled, nOfSlotsPerPage, nOfTotalObjects - nOfContentObjects, indexOfFirstObject, nOfContentObjects); for (int i = 0; i < nOfContentObjects; i++) { containerView.AddObject(indexOfFirstObject + i, ProtocolGameExtentions.ReadObjectInstance(message)); } }
private void ParseSetStoreDeepLink(Internal.CommunicationStream message) { message.ReadUnsignedByte(); if (OpenTibiaUnity.GameManager.ClientVersion >= 1200) { message.ReadUnsignedByte(); message.ReadUnsignedByte(); } }
private void ParsePreyPrices(Internal.CommunicationStream message) { message.ReadUnsignedInt(); // rerollPrice in gold if (OpenTibiaUnity.GameManager.ClientVersion >= 1190) { message.ReadUnsignedByte(); // unknown message.ReadUnsignedByte(); // selectCreatureDirectly in preyWildCards } }
private void ParseAmbientLight(Internal.CommunicationStream message) { int intensity = message.ReadUnsignedByte(); int rawColor = message.ReadUnsignedByte(); var color = Colors.ColorFrom8Bit(rawColor); WorldMapStorage.SetAmbientLight(color, intensity); }
private void ParseBuddyState(Internal.CommunicationStream message) { uint creatureId = message.ReadUnsignedInt(); byte state = 1; if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameLoginPending)) { state = message.ReadUnsignedByte(); } }
private void ReadCyclopediaCharacterInfoRecentDeaths(Internal.CommunicationStream message) { ushort count = message.ReadUnsignedShort(); for (int i = 0; i < count; i++) { uint time = message.ReadUnsignedInt(); string cause = message.ReadString(); } }
private void ParseMarketStatistics(Internal.CommunicationStream message) { int count = message.ReadUnsignedShort(); for (int i = 0; i < count; i++) { ushort objectId = message.ReadUnsignedShort(); uint objectPrice = message.ReadUnsignedInt(); } }
private void ParseUnjustifiedPoints(Internal.CommunicationStream message) { message.ReadUnsignedByte(); // dailyProgress message.ReadUnsignedByte(); // dailyRemaining message.ReadUnsignedByte(); // weeklyProgress message.ReadUnsignedByte(); // weeklyRemaining message.ReadUnsignedByte(); // monthlyProgress message.ReadUnsignedByte(); // monthlyRemaining message.ReadUnsignedByte(); // skullDuration }
private void ParsePremiumTrigger(Internal.CommunicationStream message) { int triggers = message.ReadUnsignedByte(); for (int i = 0; i < triggers; i++) { message.ReadUnsignedByte(); // trigger // TODO } }
private void ParseGraphicalEffects(Internal.CommunicationStream message) { var initialPosition = message.ReadPosition(); int modifier = message.ReadUnsignedByte(); Appearances.AppearanceInstance effect = null; byte effectId = 0; var fromPosition = initialPosition; ushort unclampedOffset = 0; while (modifier != 0) { if (modifier == 1) { unclampedOffset = message.ReadUnsignedShort(); int offset = unclampedOffset % 256; fromPosition.x += offset % Constants.MapSizeX; fromPosition.y += offset / Constants.MapSizeX; } // the effect is far away from the initial position while (fromPosition.x - initialPosition.x >= Constants.MapSizeX) { fromPosition.x -= Constants.MapSizeX; fromPosition.y++; } if ((unclampedOffset >= 1024 && modifier == 1) || (modifier & 3) == 0) { effectId = message.ReadUnsignedByte(); int deltaX = message.ReadSignedByte(); int deltaY = message.ReadSignedByte(); var toPosition = new Vector3Int(fromPosition.x + deltaX, fromPosition.y + deltaY, fromPosition.z); effect = AppearanceStorage.CreateMissileInstance(effectId, fromPosition, toPosition); } else if (unclampedOffset >= 768 || modifier == 3) { effectId = message.ReadUnsignedByte(); effect = AppearanceStorage.CreateEffectInstance(effectId); } else { throw new System.NotImplementedException(); } if (!effect) { throw new System.Exception("ProtocolGame.ParseGraphicalEffects: Unknown effect: " + effectId); } WorldMapStorage.AppendEffect(fromPosition, effect); modifier = message.ReadUnsignedByte(); } }
private void ParseStoreOffers(Internal.CommunicationStream message) { var gameManager = OpenTibiaUnity.GameManager; string categoryName = message.ReadString(); if (gameManager.ClientVersion >= 1180) { uint selectedOfferId = message.ReadUnsignedInt(); var sortType = message.ReadEnum <StoreOfferSortType>(); int filterCount = message.ReadUnsignedByte(); for (int i = 0; i < filterCount; i++) { string filter = message.ReadString(); } if (gameManager.ClientVersion >= 1185) { // if a filter is not included, then if "Show all" is not selected // the offer will be hidden until then.. // if the offer has no filter, then this value won't affect it int shownFiltersCount = message.ReadUnsignedShort(); for (int i = 0; i < shownFiltersCount; i++) { int filterIndex = message.ReadUnsignedByte(); } } } var storeCategory = OpenTibiaUnity.StoreStorage.FindCategory(categoryName); int offerCount = message.ReadUnsignedShort(); for (int i = 0; i < offerCount; i++) { var offer = ReadStoreOffer(message); // server may be sending information about non-existant category if (storeCategory != null) { storeCategory.AddOffer(offer); } } if (gameManager.ClientVersion >= 1180 && categoryName == Constants.StoreHomeCategoryName) { byte featuredOfferCount = message.ReadUnsignedByte(); for (int i = 0; i < featuredOfferCount; i++) { var storeFeaturedOffer = ReadStoreFeaturedOffer(message); } byte unknown = message.ReadUnsignedByte(); } }
public void ParseKillTracking(Internal.CommunicationStream message) { string name = message.ReadString(); var outfit = ProtocolGameExtentions.ReadCreatureOutfit(message); int lootCount = message.ReadUnsignedByte(); for (int i = 0; i < lootCount; i++) { var @object = ProtocolGameExtentions.ReadObjectInstance(message); } }
private void ParseObjectInfo(Internal.CommunicationStream message) { int objectCount = message.ReadUnsignedByte(); for (int i = 0; i < objectCount; i++) { ushort objectId = message.ReadUnsignedShort(); byte data = message.ReadUnsignedByte(); string name = message.ReadString(); } }
private int ReadField(Internal.CommunicationStream message, int x, int y, int z) { var mapPosition = new UnityEngine.Vector3Int(x, y, z); var absolutePosition = WorldMapStorage.ToAbsolute(mapPosition); int typeOrId; int stackPos = 0; bool gotEffect = false; while (true) { typeOrId = message.ReadUnsignedShort(); if (typeOrId >= 65280) { break; } if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameEnvironmentEffect) && !gotEffect) { var effectObject = AppearanceStorage.CreateEnvironmentalEffect((uint)typeOrId); WorldMapStorage.SetEnvironmentalEffect(mapPosition, effectObject); gotEffect = true; continue; } if (typeOrId == AppearanceInstance.UnknownCreature || typeOrId == AppearanceInstance.OutdatedCreature || typeOrId == AppearanceInstance.Creature) { var creature = ReadCreatureInstance(message, typeOrId, absolutePosition); var @object = AppearanceStorage.CreateObjectInstance(AppearanceInstance.Creature, creature.Id); if (stackPos < Constants.MapSizeW) { WorldMapStorage.AppendObject(mapPosition, @object); } } else { var @object = ReadObjectInstance(message, typeOrId); if (stackPos < Constants.MapSizeW) { WorldMapStorage.AppendObject(mapPosition, @object); } else { throw new System.Exception("ProtocolGameUtility.ReadField: Expected creatures but received regular object."); } } stackPos++; } return(typeOrId - 65280); }
private StoreOffer ReadStoreOffer(Internal.CommunicationStream message) { if (OpenTibiaUnity.GameManager.ClientVersion >= 1180) { return(ReadExtendedStoreOffer(message)); } else { return(ReadLegacyStoreOffer(message)); } }
private void ParseUpdateLootContainers(Internal.CommunicationStream message) { byte unknown = message.ReadUnsignedByte(); int count = message.ReadUnsignedByte(); for (int i = 0; i < count; i++) { var type = message.ReadEnum <ObjectCategory>(); ushort objectId = message.ReadUnsignedShort(); } }
private void ReadCyclopediaCharacterInfoRecentPvpKills(Internal.CommunicationStream message) { ushort count = message.ReadUnsignedShort(); for (int i = 0; i < count; i++) { uint time = message.ReadUnsignedInt(); string description = message.ReadString(); var status = message.ReadEnum <CyclopediaPvpKillStatus>(); } }
private void ParsePlayerInventory(Internal.CommunicationStream message) { //List<KeyValuePair<ushort, ushort>> items = new List<KeyValuePair<ushort, ushort>>(); ushort size = message.ReadUnsignedShort(); for (int i = 0; i < size; i++) { ushort id = message.ReadUnsignedShort(); byte subType = message.ReadUnsignedByte(); ushort count = message.ReadUnsignedShort(); } }
private void ParseMapLeftRow(Internal.CommunicationStream message) { UnityEngine.Vector3Int position = WorldMapStorage.Position; position.x--; WorldMapStorage.Position = position; MiniMapStorage.Position = position; WorldMapStorage.ScrollMap(1, 0); WorldMapStorage.InvalidateOnscreenMessages(); ProtocolGameExtentions.ReadArea(message, 0, 0, 0, Constants.MapSizeY - 1); WorldMapStorage.CacheRefresh = true; }
private void ParseNPCOffer(Internal.CommunicationStream message) { string npcName = null; if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameNameOnNpcTrade)) { npcName = message.ReadString(); } var buyObjects = new List <Trade.TradeObjectRef>(); var sellObjects = new List <Trade.TradeObjectRef>(); ushort currencyObjectId = 0; if (OpenTibiaUnity.GameManager.ClientVersion >= 1203) { currencyObjectId = message.ReadUnsignedShort(); } int listCount; if (OpenTibiaUnity.GameManager.ClientVersion >= 900) { listCount = message.ReadUnsignedShort(); } else { listCount = message.ReadUnsignedByte(); } for (int i = 0; i < listCount; i++) { ushort objectId = message.ReadUnsignedShort(); ushort objectData = message.ReadUnsignedByte(); string name = message.ReadString(); uint weight = message.ReadUnsignedInt(); uint buyPrice = message.ReadUnsignedInt(); uint sellPrice = message.ReadUnsignedInt(); if (buyPrice > 0) { buyObjects.Add(new Trade.TradeObjectRef(objectId, objectData, name, buyPrice, weight)); } if (sellPrice > 0) { sellObjects.Add(new Trade.TradeObjectRef(objectId, objectData, name, sellPrice, weight)); } } OpenTibiaUnity.GameManager.onRequestNPCTrade.Invoke(npcName, buyObjects, sellObjects); }
private void ParseChannels(Internal.CommunicationStream message) { int count = message.ReadUnsignedByte(); List <Chat.Channel> channels = new List <Chat.Channel>(); for (int i = 0; i < count; i++) { int id = message.ReadUnsignedShort(); string name = message.ReadString(); channels.Add(new Chat.Channel(id, name, MessageModeType.None)); } }
private void ParseMapBottomRow(Internal.CommunicationStream message) { UnityEngine.Vector3Int position = WorldMapStorage.Position; position.y++; WorldMapStorage.Position = position; MiniMapStorage.Position = position; WorldMapStorage.ScrollMap(0, -1); WorldMapStorage.InvalidateOnscreenMessages(); ReadArea(message, 0, Constants.MapSizeY - 1, Constants.MapSizeX - 1, Constants.MapSizeY - 1); WorldMapStorage.CacheRefresh = true; }
private ObjectInstance ReadObjectInstance(Internal.CommunicationStream message, int id = -1) { if (id == -1) { id = message.ReadUnsignedShort(); } if (id == 0) { return(null); } else if (id <= AppearanceInstance.Creature) { throw new System.Exception("ProtocolGameUtility.ReadObjectInstance: Invalid type (id = " + id + ")"); } var @object = AppearanceStorage.CreateObjectInstance((uint)id, 0); if (!@object) { throw new System.Exception("ProtocolGameUtility.ReadObjectInstance: Invalid instance with id " + id); } if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameObjectMarks)) { @object.Marks.SetMark(MarkType.Permenant, message.ReadUnsignedByte()); } if (@object.Type.IsStackable || @object.Type.IsFluidContainer || @object.Type.IsSplash) { @object.Data = message.ReadUnsignedByte(); } if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameItemAnimationPhase)) { if (@object.Type.FrameGroups[(int)Protobuf.Shared.FrameGroupType.Idle].SpriteInfo.IsAnimation) { int phase = message.ReadUnsignedByte(); @object.Phase = phase == 0 ? Constants.PhaseAutomatic : phase; } } if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameQuickLoot) && @object.Type.IsContainer) { bool assignedToQuickLoot = message.ReadBoolean(); if (assignedToQuickLoot) { uint lootContainers = message.ReadUnsignedInt(); // 1 << ObjectCategory | .... } } return(@object); }
private void ParseSupplyStash(Internal.CommunicationStream message) { int availableItems = message.ReadUnsignedShort(); for (int i = 0; i < availableItems; i++) { ushort objectID = message.ReadUnsignedShort(); uint objectCount = message.ReadUnsignedInt(); } int freeSlots = message.ReadUnsignedShort(); }
public StoreOpenParameters ReadStoreOpenParameters(Internal.CommunicationStream message) { var openAction = message.ReadEnum <StoreOpenParameterAction>(); Store.OpenParameters.IStoreOpenParamater openParam = null; switch (openAction) { case StoreOpenParameterAction.Invalid: { break; } case StoreOpenParameterAction.CategoryType: { var categoryType = message.ReadEnum <StoreCategoryType>(); openParam = new Store.OpenParameters.StoreCategoryTypeOpenParamater(categoryType); break; } case StoreOpenParameterAction.CategoryAndFilter: { var categoryAndFilter = ReadStoreCategoryAndFilter(message); openParam = new Store.OpenParameters.StoreCategoryAndFilterOpenParamater(categoryAndFilter); break; } case StoreOpenParameterAction.OfferType: { var offerType = message.ReadEnum <StoreOfferType>(); openParam = new Store.OpenParameters.StoreOfferTypeOpenParamater(offerType); break; } case StoreOpenParameterAction.OfferId: { var offerId = message.ReadUnsignedInt(); openParam = new Store.OpenParameters.StoreOfferIdOpenParamater(offerId); break; } case StoreOpenParameterAction.CategoryName: { var categoryName = message.ReadString(); openParam = new Store.OpenParameters.StoreCategoryNameOpenParamater(categoryName); break; } } // enum too, 0, 1, 2, 3 message.ReadUnsignedByte(); /** * 0: default * 1: home * // 2, 3? */ message.ReadBoolean(); // 0, 1, 2, 3 (enum) return(new StoreOpenParameters(openAction, openParam)); }
private void ParseDailyRewardHistory(Internal.CommunicationStream message) { int count = message.ReadUnsignedByte(); for (int i = 0; i < count; i++) { var timestamp = message.ReadUnsignedInt(); // timestamp message.ReadUnsignedByte(); // some state (0: none, 1: active[green]) message.ReadString(); // description message.ReadUnsignedShort(); // streak } }
private void ParseMonsterCyclopedia(Internal.CommunicationStream message) { int count = message.ReadUnsignedShort(); for (int i = 0; i < count; i++) { string classification = message.ReadString(); uint total = message.ReadUnsignedShort(); uint known = message.ReadUnsignedShort(); } }
private Creatures.Skill ReadSkill(Internal.CommunicationStream message, bool special = false) { int level; if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameDoubleSkills)) { level = message.ReadUnsignedShort(); } else { level = message.ReadUnsignedByte(); } int baseLevel; if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameSkillsBase)) { if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameBaseSkillU16)) { baseLevel = message.ReadUnsignedShort(); } else { baseLevel = message.ReadUnsignedByte(); } } else { baseLevel = level; } if (!special && OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePercentSkillU16)) { ushort loyaltyBonus = message.ReadUnsignedShort(); } float percentage = 0.0f; if (!special) { if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePercentSkillU16)) { percentage = message.ReadUnsignedShort() / 100f; } else { percentage = message.ReadUnsignedByte(); } } return(new Creatures.Skill(level, baseLevel, percentage)); }
private int ReadArea(Internal.CommunicationStream message, int startx, int starty, int endx, int endy) { UnityEngine.Vector3Int position = WorldMapStorage.Position; int z, endz, zstep; if (position.z <= Constants.GroundLayer) { z = 0; endz = Constants.GroundLayer + 1; zstep = 1; } else { z = 2 * Constants.UndergroundLayer; endz = System.Math.Max(-1, position.z - Constants.MapMaxZ + 1); zstep = -1; } int skip = 0; for (; z != endz; z += zstep) { for (int x = startx; x <= endx; x++) { for (int y = starty; y <= endy; y++) { if (skip > 0) { skip--; } else { skip = ReadField(message, x, y, z); } UnityEngine.Vector3Int mapPosition = new UnityEngine.Vector3Int(x, y, z); UnityEngine.Vector3Int absolutePosition = WorldMapStorage.ToAbsolute(mapPosition); if (absolutePosition.z == MiniMapStorage.PositionZ) { WorldMapStorage.UpdateMiniMap(mapPosition); uint color = WorldMapStorage.GetMiniMapColour(mapPosition); int cost = WorldMapStorage.GetMiniMapCost(mapPosition); MiniMapStorage.UpdateField(absolutePosition, color, cost, false); } } } } return(skip); }
private void ParsePlayerSkills(Internal.CommunicationStream message) { // magic level is being parsed if (OpenTibiaUnity.GameManager.ClientVersion >= 1200) { var skillStruct = ReadSkill(message); Player.SetSkill(SkillType.MagLevel, skillStruct.Level, skillStruct.BaseLevel, skillStruct.Percentage); } var skills = new SkillType[] { SkillType.Fist, SkillType.Club, SkillType.Sword, SkillType.Axe, SkillType.Distance, SkillType.Shield, SkillType.Fishing }; foreach (var skill in skills) { var skillStruct = ReadSkill(message); Player.SetSkill(skill, skillStruct.Level, skillStruct.BaseLevel, skillStruct.Percentage); } if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameAdditionalSkills)) { SkillType[] specialSkills = new SkillType[] { SkillType.CriticalHitChance, SkillType.CriticalHitDamage, SkillType.LifeLeechChance, SkillType.LifeLeechAmount, SkillType.ManaLeechChance, SkillType.ManaLeechAmount }; foreach (var skill in specialSkills) { var skillStruct = ReadSkill(message, true); Player.SetSkill(skill, skillStruct.Level, skillStruct.BaseLevel); } } // todo: find if this is capacity if (OpenTibiaUnity.GameManager.ClientVersion >= 1150) { int totalCapacity = message.ReadInt(); int baseCapacity = message.ReadInt(); Player.SetSkill(SkillType.Capacity, totalCapacity, baseCapacity); } }