diff --git a/modules/game_protocol/protocol.lua b/modules/game_protocol/protocol.lua index 59bb933..e1ca2bf 100644 --- a/modules/game_protocol/protocol.lua +++ b/modules/game_protocol/protocol.lua @@ -12,7 +12,27 @@ local ServerPackets = { BestiaryMonsterData = 0xd7, BestiaryCharmsData = 0xd8, BestiaryTracker = 0xd9, - BestiaryTrackerTab = 0xB9 + BestiaryTrackerTab = 0xB9, + OpenStashSupply = 0x29, + UpdateLootTracker = 0xCF, + UpdateTrackerAnalyzer = 0xCC, + UpdateSupplyTracker = 0xCE, + KillTracker = 0xD1, + SpecialContainer = 0x2A, + isUpdateCoinBalance = 0xF2, + UpdateCoinBalance = 0xDF, + PartyAnalyzer = 0x2B, + GameNews = 0x98, + ClientCheck = 0x63, + LootStats = 0xCF, + LootContainer = 0xC0, + TournamentLeaderBoard = 0xC5, + CyclopediaCharacterInfo = 0xDA, + Tutorial = 0xDC, + Highscores = 0xB1, + Inspection = 0x76, + TeamFinderList = 0x2D, + TeamFinderLeader = 0x2C } -- Server Types @@ -53,6 +73,526 @@ function registerProtocol() registredOpcodes = {} + registerOpcode(ServerPackets.TeamFinderLeader, function(protocol, msg) + local bool = msg:getU8() -- reset + if bool > 0 then + return -- Server internal changes + end + + msg:getU16() -- Min level + msg:getU16() -- Max level + msg:getU8() -- Vocation flag + msg:getU16() -- Slots + msg:getU16() -- Free slots + msg:getU32() -- Timestamp + local type = msg:getU8() -- Team type + msg:getU16() -- Type flag + if type == 2 then + msg:getU16() -- Hunt area + end + + local size = msg:getU16() -- Members size + for i = 1, size do + msg:getU32() -- Character id + msg:getString() -- Character name + msg:getU16() -- Character level + msg:getU8() -- Vocation + msg:getU8() -- Member type (Leader == 3) + end + end) + + registerOpcode(ServerPackets.TeamFinderList, function(protocol, msg) + msg:getU8() + local size = msg:getU32() -- List size + for i = 1, size do + msg:getU32() -- Leader Id + msg:addString() -- Leader name + msg:getU16() -- Min level + msg:getU16() -- Max level + msg:getU8() -- Vocations flag + msg:getU16() -- Slots + msg:getU16() -- Used slots + msg:getU32() -- Timestamp + local type = msg:getU8() -- Team type [1]: Boss, [2]: Hunt and [3]: Quest + msg:getU16() -- Type flag + if type == 2 then + msg:getU16() -- Hunt area + end + msg:getU8() -- Player status + end + end) + + registerOpcode(ServerPackets.Inspection, function(protocol, msg) + local bool = msg:getU8() -- IsPlayer + if g_game.getClientVersion() >= 1230 then + msg:getU8() + end + local size = msg:getU8() -- List + for i = 1, size do + if bool > 0 then + msg:getU8() + end + msg:getString() -- Name + readAddItem(msg) + local size_2 = msg:getU8() -- Imbuements + for u = 1, size_2 do + msg:getU16() -- Imbue + end + local size_3 = msg:getU8() -- Details + for j = 1, size_3 do + msg:getString() -- Name + msg:getString() -- Description + end + end + + if bool > 0 then + msg:getString() -- Player name + local outfit = msg:getU16() -- lookType + if outfit ~= 0 then + msg:getU8() -- lookHead + msg:getU8() -- lookBody + msg:getU8() -- lookLegs + msg:getU8() -- lookFeet + msg:getU8() -- lookAddons + else + msg:getU16() -- lookTypeEx + end + local size_4 = msg:getU8() -- Detail + for l = 1, size_4 do + msg:getString() -- Name + msg:getString() -- Description + end + end + end) + + registerOpcode(ServerPackets.Highscores, function(protocol, msg) + msg:getU8() + local size = msg:getU8() -- Worlds + for i = 1, size do + msg:getString() -- World name + end + msg:getString() -- Selected world + local size_2 = msg:getU8() -- Vocations + for u = 1, size_2 do + msg:getU32() -- Id + msg:getString() -- Name + end + msg:getU32() -- Vocation selected Id + local size_3 = msg:getU8() -- Categories + for j = 1, size_3 do + msg:getU8() -- Id + msg:getString() -- Name + end + msg:getU8() -- Category selected Id + msg:getU16() -- Pages + msg:getU16() -- Selected page + local size_4 = msg:getU8() -- Entries + for l = 1, size_4 do + msg:getU32() -- Rank + msg:getString() -- Character name + msg:getString() -- Character title + msg:getU8() -- Vocation + msg:getString() -- World + msg:getU16() -- Level + msg:getU8() -- Is player? then highlight + msg:getU64() -- Points + end + msg:getU8() + msg:getU8() + msg:getU8() + msg:getU32() -- Last update + end) + + registerOpcode(ServerPackets.Tutorial, function(protocol, msg) + msg:getU8() -- Tutorial id + end) + + registerOpcode(ServerPackets.CyclopediaCharacterInfo, function(protocol, msg) + local type = msg:getU8() + if g_game.getClientVersion() >= 1215 then + local error = msg:getU8() + if error > 0 then + -- [1] 'No data available at the moment.' + -- [2] 'You are not allowed to see this character's data.' + -- [3] 'You are not allowed to inspect this character.' + end + end + if type == 0 then -- Basic Information + msg:getString() -- Player name + msg:getString() -- Vocation + msg:getU16() -- Level + local outfit = msg:getU16() -- lookType + if outfit ~= 0 then + msg:getU8() -- lookHead + msg:getU8() -- lookBody + msg:getU8() -- lookLegs + msg:getU8() -- lookFeet + msg:getU8() -- lookAddons + else + msg:getU16() -- lookTypeEx + end + msg:getU8() -- Hide stamina + if g_game.getClientVersion() >= 1220 then + msg:getU8() -- Personal habs + msg:getString() -- Title + end + elseif type == 1 then -- Character Stats + msg:getU64() -- Experience + msg:getU16() -- Level + msg:getU8() -- LevelPercent + msg:getU16() -- BaseXpGain + msg:getU32() -- Tournament + msg:getU16() -- Grinding + msg:getU16() -- Store XP + msg:getU16() -- Hunting + msg:getU16() -- Store XP Time + msg:getU8() -- Show store XP button (bool) + msg:getU16() -- Health + msg:getU16() -- Health max + msg:getU16() -- Mana + msg:getU16() -- Mana max + msg:getU8() -- Soul + msg:getU16() -- Stamina + msg:getU16() -- Food + msg:getU16() -- Offline training + msg:getU16() -- Speed + msg:getU16() -- Speed base + msg:getU32() -- Capacity bonus + msg:getU32() -- Capacity + msg:getU32() -- Capacity max + local size = msg:getU8() -- Skills + for i = 1, size do + msg:getU8() -- Skill id + msg:getU16() -- Skill level + msg:getU16() -- Base skill + msg:getU16() -- Base skill + msg:getU16() -- Skill percent + end + if g_game.getClientVersion() < 1215 then + msg:getU16() + msg:getString() -- Player name + msg:getString() -- Vocation + msg:getU16() -- Level + local outfit = msg:getU16() -- lookType + if outfit ~= 0 then + msg:getU8() -- lookHead + msg:getU8() -- lookBody + msg:getU8() -- lookLegs + msg:getU8() -- lookFeet + msg:getU8() -- lookAddons + else + msg:getU16() -- lookTypeEx + end + end + elseif type == 2 then -- Combat Stats + msg:getU16() -- Critical chance base + msg:getU16() -- Critical chance bonus + msg:getU16() -- Critical damage base + msg:getU16() -- Critical damage bonus + msg:getU16() -- Life leech chance base + msg:getU16() -- Life leech chance bonus + msg:getU16() -- Life leech amount base + msg:getU16() -- Life leech amount bonus + msg:getU16() -- Mana leech chance base + msg:getU16() -- Mana leech chance bonus + msg:getU16() -- Mana leech amount base + msg:getU16() -- Mana leech amount bonus + msg:getU8() -- Blessing amount + msg:getU8() -- Blessing max + msg:getU16() -- Attack + msg:getU8() -- Attack type + msg:getU8() -- Convert damage + msg:getU8() -- Convert damage type + msg:getU16() -- Armor + msg:getU16() -- Defense + local size = msg:getU8() -- Reductions + for i = 1, size do + msg:getU8() -- Element + msg:getU8() -- Percent + end + elseif type == 3 then -- Recent Deaths + msg:getU16() -- Page + msg:getU16() -- Page max + local size = msg:getU16() + for i = 1, size do + msg:getU32() -- Timestamp + msg:getString() -- Cause + end + elseif type == 4 then -- Recent PvP Kills + msg:getU16() -- Page + msg:getU16() -- Page max + local size = msg:getU16() + for i = 1, size do + msg:getU32() -- Timestamp + msg:getString() -- Description + msg:getU8() -- Status + end + elseif type == 5 then -- Achievements + msg:getU16() -- Points + msg:getU16() -- Secret max + local size = msg:getU16() -- Unlocked + for i = 1, size do + msg:getU16() -- Id + msg:getU32() -- Timestamp + local size_2 = msg:getU8() -- Is secret + if size_2 > 0 then + msg:getString() -- Name + msg:getString() -- Description + msg:getU8() -- Grade + end + end + elseif type == 6 then -- Item Summary + local size = msg:getU16() -- Item list size + for i = 1, size do + msg:getU16() -- Item client Id + msg:getU32() -- Item count + end + elseif type == 7 then -- Outfits and Mounts + local size = msg:getU16() -- Outfit list size + for i = 1, size do + msg:getU16() -- Id + msg:getString() -- Name + msg:getU8() -- Addon + msg:getU8() -- Category 0 = Standard, 1 = Quest, 2 = Store + msg:getU32() -- Is current ? then 1000 or 0 + end + msg:getU8() -- lookHead + msg:getU8() -- lookBody + msg:getU8() -- lookLegs + msg:getU8() -- lookFeet + + local size_2 = msg:getU16() -- Mount list size + for u = 1, size_2 do + msg:getU16() -- Id + msg:getString() -- Name + msg:getU8() -- Addon + msg:getU8() -- Category 0 = Standard, 1 = Quest, 2 = Store + msg:getU32() -- Is current ? then 1000 or 0 + end + if g_game.getClientVersion() >= 1260 then + msg:getU8() -- Mount lookHead + msg:getU8() -- Mount lookBody + msg:getU8() -- Mount lookLegs + msg:getU8() -- Mount lookFeet + end + elseif type == 8 then -- Store Summary + msg:getU32() -- Store XP boost time + msg:getU32() -- Daily reward XP boost time + local size = msg:getU8() -- Blessings + for i = 1, size do + msg:getString() -- Name + msg:getU8() -- Amount + end + msg:getU8() -- Prey slots + msg:getU8() -- Prey wildcard + msg:getU8() -- Instant reward + msg:getU8() -- Charm expansion + msg:getU8() -- Hireling + local size_2 = msg:getU8() -- Hireling jogs + for u = 1, size_2 do + msg:getU8() -- Job id + end + local size_3 = msg:getU8() -- Hireling outfit + for j = 1, size_3 do + msg:getU8() -- Outfit id + end + msg:getU16() -- House items + elseif type == 9 then -- Inspect + local size = msg:getU8() -- Items + for i = 1, size do + msg:getU8() -- Slot index + msg:getString() -- Item name + readAddItem(msg) + local size_2 = msg:getU8() -- Imbuements + for u = 1, size_2 do + msg:getU16() -- Imbue + end + local size_3 = msg:getU8() -- Detail + for j = 1, size_3 do + msg:getString() -- Name + msg:getString() -- Description + end + end + msg:getString() -- Player name + local outfit = msg:getU16() -- lookType + if outfit ~= 0 then + msg:getU8() -- lookHead + msg:getU8() -- lookBody + msg:getU8() -- lookLegs + msg:getU8() -- lookFeet + msg:getU8() -- lookAddons + else + msg:getU16() -- lookTypeEx + end + local size_4 = msg:getU8() -- Player detail + for k = 1, size_4 do + msg:getString() -- Name + msg:getString() -- Description + end + elseif type == 10 then -- Badges + local bool = msg:getU8() -- Show account + if bool > 0 then + msg:getU8() -- Is online + msg:getU8() -- Is premium + msg:getString() -- Loyality title + local size = msg:getU8() -- Badges + for i = 1, size do + msg:getU32() -- Id + msg:getString() -- Name + end + end + elseif type == 11 then -- Titles + msg:getU8() -- Title + local size = msg:getU8() -- Titles + for i = 1, size do + msg:getU8() -- Id + msg:getString() -- Name + msg:getString() -- Description + msg:getU8() -- Permanent + msg:getU8() -- Unlocked + end + end + end) + + registerOpcode(ServerPackets.TournamentLeaderBoard, function(protocol, msg) + msg:getU16() + local capacity = msg:getU8() -- Worlds + for i = 1, capacity do + msg:getString() -- World name + end + + msg:getString() -- World selected + msg:getU16() -- Refresh rate + msg:getU16() -- Current page + msg:getU16() -- Total pages + local size = msg:getU8() -- Players on page + for u = 1, size do + msg:getU32() -- Rank + msg:getU32() -- Previous rank + msg:getString() -- Name + msg:getU8() -- Vocation + msg:getU64() -- Points + msg:getU8() -- Rank chance direction (arrow0 + msg:getU8() -- Rank chance bool + end + msg:getU8() + msg:getString() -- Rewards + end) + + registerOpcode(ServerPackets.LootContainer, function(protocol, msg) + msg:getU8() -- Fallback + local size = msg:getU8() -- Quickloot size + for i = 1, size do + msg:getU8() -- Category Id + msg:getU16() -- Client Id + end + end) + + registerOpcode(ServerPackets.LootStats, function(protocol, msg) + readAddItem(msg) + msg:getString() -- Item name + end) + + registerOpcode(ServerPackets.ClientCheck, function(protocol, msg) + local size = msg:getU32() -- Data size + for i = 1, size do + msg:getU8() -- Data + end + end) + + registerOpcode(ServerPackets.GameNews, function(protocol, msg) + msg:getU32() -- Category + msg:getU8() -- Page + end) + + registerOpcode(ServerPackets.PartyAnalyzer, function(protocol, msg) + msg:getU32() -- Timestamp + msg:getU32() -- Party leader id + msg:getU8() -- Price type (client/market) + local size = msg:getU8() -- Party size + for i = 1, size do + msg:getU32() -- Player ID + msg:getU8() -- (Highlight text bool) + + msg:getU64() -- Loot count + msg:getU64() -- Supply count + msg:getU64() -- Impact count + msg:getU64() -- Heal count + end + + msg:getU8() + local size_2 = msg:getU8() -- Size + for u = 1, size_2 do + msg:getU32() -- Player ID + msg:getString() -- Player name + end + end) + + registerOpcode(ServerPackets.UpdateCoinBalance, function(protocol, msg) + msg:getU8() -- Is updating + msg:getU32() -- Normal coin + msg:getU32() -- Transferable coin + if g_game.getClientVersion() >= 1220 then + msg:getU32() -- Reserved auction coin + msg:getU32() -- Tournament coin + end + end) + + registerOpcode(ServerPackets.isUpdateCoinBalance, function(protocol, msg) + msg:getU8() -- Is updating + end) + + registerOpcode(ServerPackets.SpecialContainer, function(protocol, msg) + local supplyStashMenu = msg:getU8() -- ('Stow item', 'Stow container' ...) + local marketMenu = msg:getU8() -- ('Show in market') + end) + + registerOpcode(ServerPackets.KillTracker, function(protocol, msg) + msg:getString() -- Name + msg:getU16() -- lookType + msg:getU8() -- lookHead + msg:getU8() -- lookBody + msg:getU8() -- lookLegs + msg:getU8() -- lookFeet + msg:getU8() -- lookAddons + local size = msg:getU8() -- Corpse size + if size > 0 then + for i = 1, size do + readAddItem(msg) + end + end + end) + + registerOpcode(ServerPackets.UpdateSupplyTracker, function(protocol, msg) + msg:getU16() -- Item client ID + end) + + registerOpcode(ServerPackets.UpdateTrackerAnalyzer, function(protocol, msg) + local type = msg:getU8() + msg:getU32() -- Amount + if type > 0 then -- ANALYZER_DAMAGE_DEALT + msg:getU8() -- Element + if type > 1 then -- + msg:getString() -- Target + end + end + end) + + registerOpcode(ServerPackets.UpdateLootTracker, function(protocol, msg) + readAddItem(msg) + msg:getString() -- Item name + end) + + registerOpcode(ServerPackets.OpenStashSupply, function(protocol, msg) + local count = msg:getU16() -- List size + for i = 1, count do + msg:getU16() -- Item client ID + msg:getU32() -- Item count + end + + msg:getU16() -- Stash size left (total - used) + end) + registerOpcode(ServerPackets.OpenRewardWall, function(protocol, msg) msg:getU8() msg:getU32() @@ -109,6 +649,30 @@ function registerProtocol() end +function readAddItem(msg) + msg:getU16() -- Item client ID + + if g_game.getClientVersion() < 1150 then + msg:getU8() -- Unmarked + end + + local var = msg:getU8() + if g_game.getClientVersion() > 1150 then + if var == 1 then + msg:getU32() -- Loot flag + end + + if g_game.getClientVersion() >= 1260 then + local isQuiver = msg:getU8() + if isQuiver == 1 then + msg:getU32() -- Quiver count + end + end + else + msg:getU8() + end +end + function unregisterProtocol() if registredOpcodes == nil then return @@ -147,4 +711,4 @@ function readDailyReward(msg) msg:getU16() end end -end \ No newline at end of file +end diff --git a/otclient_dx.exe b/otclient_dx.exe index d1a395e..554f1b3 100644 Binary files a/otclient_dx.exe and b/otclient_dx.exe differ diff --git a/otclient_gl.exe b/otclient_gl.exe index 2567183..274a1f5 100644 Binary files a/otclient_gl.exe and b/otclient_gl.exe differ diff --git a/otclientv8.apk b/otclientv8.apk index ba81e45..c3280ba 100644 Binary files a/otclientv8.apk and b/otclientv8.apk differ