From abbd15b1c2e1856d964150e60f9d416df893ed9d Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Fri, 11 May 2012 22:44:13 -0300 Subject: [PATCH] basic protocol 910 support --- modules/game_healthbar/healthbar.lua | 2 + src/otclient/net/protocolcodes.h | 401 +++++++++++++++---------- src/otclient/net/protocolgame.h | 3 + src/otclient/net/protocolgameparse.cpp | 150 ++++++--- src/otclient/net/protocolgamesend.cpp | 6 +- 5 files changed, 352 insertions(+), 210 deletions(-) diff --git a/modules/game_healthbar/healthbar.lua b/modules/game_healthbar/healthbar.lua index 1eea9dc6..0bd794ab 100644 --- a/modules/game_healthbar/healthbar.lua +++ b/modules/game_healthbar/healthbar.lua @@ -17,6 +17,8 @@ Icons[2048] = { tooltip = tr('You are cursed'), path = '/game_healthbar/icons/cu Icons[4096] = { tooltip = tr('You are strengthened'), path = '/game_healthbar/icons/strengthened.png', id = 'condition_strengthened' } Icons[8192] = { tooltip = tr('You may not logout or enter a protection zone'), path = '/game_healthbar/icons/protection_zone_block.png', id = 'condition_protection_zone_block' } Icons[16384] = { tooltip = tr('You are within a protection zone'), path = '/game_healthbar/icons/protection_zone.png', id = 'condition_protection_zone' } +Icons[32768] = { tooltip = tr('You are bleeding'), path = '/game_healthbar/icons/bleeding.png', id = 'condition_bleeding' } +Icons[65536] = { tooltip = tr('You are hungry'), path = '/game_healthbar/icons/hungry.png', id = 'condition_hungry' } -- private variables local healthBarWindow diff --git a/src/otclient/net/protocolcodes.h b/src/otclient/net/protocolcodes.h index ba5cacaf..8232ac15 100644 --- a/src/otclient/net/protocolcodes.h +++ b/src/otclient/net/protocolcodes.h @@ -30,7 +30,8 @@ PROTOCOL != 860 && \ PROTOCOL != 861 && \ PROTOCOL != 862 && \ - PROTOCOL != 870 + PROTOCOL != 870 && \ + PROTOCOL != 910 #error "the supplied protocol version is not supported" #endif @@ -53,9 +54,10 @@ namespace Proto { constexpr int PicSignature = 0x4E119CBF; enum OsTypes { - OsWindows = 1, - OsLinux = 2, - OsMac = 3 + OsLinux = 1, + OsWindows = 2, + OsFlash = 3, + OsMac = 4 }; #ifdef OSTYPE @@ -82,169 +84,196 @@ namespace Proto { }; enum GameServerOpts { - GameServerInitGame = 10, - GameServerGMActions = 11, - GameServerLoginError = 20, - GameServerLoginAdvice = 21, - GameServerLoginWait = 22, - GameServerPing = 30, - GameServerChallange = 31, - GameServerDeath = 40, - GameServerFullMap = 100, - GameServerMapTopRow = 101, - GameServerMapRightRow = 102, - GameServerMapBottomRow = 103, - GameServerMapLeftRow = 104, - GameServerUpdateTile = 105, - GameServerCreateOnMap = 106, - GameServerChangeOnMap = 107, - GameServerDeleteOnMap = 108, - GameServerMoveCreature = 109, - GameServerOpenContainer = 110, - GameServerCloseContainer = 111, - GameServerCreateContainer = 112, - GameServerChangeInContainer = 113, - GameServerDeleteInContainer = 114, - GameServerSetInventory = 120, - GameServerDeleteInventory = 121, - GameServerOpenNpcTrade = 122, - GameServerPlayerGoods = 123, - GameServerCloseNpcTrade = 124, - GameServerOwnTrade = 125, - GameServerCounterTrade = 126, - GameServerCloseTrade = 127, - GameServerAmbient = 130, - GameServerGraphicalEffect = 131, - GameServerTextEffect = 132, - GameServerMissleEffect = 133, - GameServerMarkCreature = 134, - GameServerTrappers = 135, - GameServerCreatureHealth = 140, - GameServerCreatureLight = 141, - GameServerCreatureOutfit = 142, - GameServerCreatureSpeed = 143, - GameServerCreatureSkull = 144, - GameServerCreatureParty = 145, - GameServerCreatureUnpass = 146, - GameServerEditText = 150, - GameServerEditList = 151, - GameServerPlayerData = 160, - GameServerPlayerSkills = 161, - GameServerPlayerState = 162, - GameServerClearTarget = 163, - GameServerSpellDelay = 164, - GameServerSpellGroupDelay = 165, - GameServerTalk = 170, - GameServerChannels = 171, - GameServerOpenChannel = 172, - GameServerOpenPrivateChannel = 173, - GameServerRuleViolationChannel = 174, - GameServerRuleViolationRemove = 175, - GameServerRuleViolationCancel = 176, - GameServerRuleViolationLock = 177, - GameServerOpenOwnChannel = 178, - GameServerCloseChannel = 179, - GameServerTextMessage = 180, - GameServerCancelWalk = 181, - GameServerWait = 182, - GameServerFloorChangeUp = 190, - GameServerFloorChangeDown = 191, - GameServerChooseOutfit = 200, - GameServerVipAdd = 210, - GameServerVipLogin = 211, - GameServerVipLogout = 212, - GameServerTutorialHint = 220, - GameServerAutomapFlag = 221, - GameServerQuestLog = 240, - GameServerQuestLine = 241, - GameServerChannelEvent = 243, - GameServerObjectInfo = 244, - GameServerPlayerInventory = 245, - GameServerExtendedOpcode = 254 // otclient only + GameServerInitGame = 10, + GameServerGMActions = 11, + GameServerLoginError = 20, + GameServerLoginAdvice = 21, + GameServerLoginWait = 22, + GameServerPing = 30, + GameServerChallange = 31, + GameServerDeath = 40, + GameServerFullMap = 100, + GameServerMapTopRow = 101, + GameServerMapRightRow = 102, + GameServerMapBottomRow = 103, + GameServerMapLeftRow = 104, + GameServerUpdateTile = 105, + GameServerCreateOnMap = 106, + GameServerChangeOnMap = 107, + GameServerDeleteOnMap = 108, + GameServerMoveCreature = 109, + GameServerOpenContainer = 110, + GameServerCloseContainer = 111, + GameServerCreateContainer = 112, + GameServerChangeInContainer = 113, + GameServerDeleteInContainer = 114, + GameServerSetInventory = 120, + GameServerDeleteInventory = 121, + GameServerOpenNpcTrade = 122, + GameServerPlayerGoods = 123, + GameServerCloseNpcTrade = 124, + GameServerOwnTrade = 125, + GameServerCounterTrade = 126, + GameServerCloseTrade = 127, + GameServerAmbient = 130, + GameServerGraphicalEffect = 131, + GameServerTextEffect = 132, + GameServerMissleEffect = 133, + GameServerMarkCreature = 134, + GameServerTrappers = 135, + GameServerCreatureHealth = 140, + GameServerCreatureLight = 141, + GameServerCreatureOutfit = 142, + GameServerCreatureSpeed = 143, + GameServerCreatureSkull = 144, + GameServerCreatureParty = 145, + GameServerCreatureUnpass = 146, + GameServerEditText = 150, + GameServerEditList = 151, + GameServerPlayerData = 160, + GameServerPlayerSkills = 161, + GameServerPlayerState = 162, + GameServerClearTarget = 163, + GameServerSpellDelay = 164, // 870 + GameServerSpellGroupDelay = 165, // 870 + GameServerTalk = 170, + GameServerChannels = 171, + GameServerOpenChannel = 172, + GameServerOpenPrivateChannel = 173, + GameServerRuleViolationChannel = 174, + GameServerRuleViolationRemove = 175, + GameServerRuleViolationCancel = 176, + GameServerRuleViolationLock = 177, + GameServerOpenOwnChannel = 178, + GameServerCloseChannel = 179, + GameServerTextMessage = 180, + GameServerCancelWalk = 181, + GameServerWait = 182, + GameServerFloorChangeUp = 190, + GameServerFloorChangeDown = 191, + GameServerChooseOutfit = 200, + GameServerVipAdd = 210, + GameServerVipLogin = 211, + GameServerVipLogout = 212, + GameServerTutorialHint = 220, + GameServerAutomapFlag = 221, + GameServerQuestLog = 240, + GameServerQuestLine = 241, + GameServerChannelEvent = 243, + GameServerObjectInfo = 244, // 910 + GameServerPlayerInventory = 245, // 910 + GameServerExtendedOpcode = 254 // otclient only }; enum ClientOpts { - ClientEnterAccount = 1, - ClientEnterGame = 10, - ClientLeaveGame = 20, - ClientPingResponse = 30, - ClientAutoWalk = 100, - ClientWalkNorth = 101, - ClientWalkEast = 102, - ClientWalkSouth = 103, - ClientWalkWest = 104, - ClientStop = 105, - ClientWalkNorthEast = 106, - ClientWalkSouthEast = 107, - ClientWalkSouthWest = 108, - ClientWalkNorthWest = 109, - ClientTurnNorth = 111, - ClientTurnEast = 112, - ClientTurnSouth = 113, - ClientTurnWest = 114, - //ClientEquipObject = 119, - ClientMove = 120, - ClientInspectNpcTrade = 121, - ClientBuyItem = 122, - ClientSellItem = 123, - ClientCloseNpcTrade = 124, - ClientRequestTrade = 125, - ClientInspectTrade = 126, - ClientAcceptTrade = 127, - ClientRejectTrade = 128, - ClientUseItem = 130, - ClientUseItemWith = 131, - ClientUseOnCreature = 132, - ClientRotateItem = 133, - ClientCloseContainer = 135, - ClientUpContainer = 136, - ClientEditText = 137, - ClientEditList = 138, - ClientLook = 140, - ClientTalk = 150, - ClientRequestChannels = 151, - ClientJoinChannel = 152, - ClientLeaveChannel = 153, - ClientOpenPrivateChannel = 154, - ClientCloseNpcChannel = 158, - ClientChangeFightModes = 160, - ClientAttack = 161, - ClientFollow = 162, - ClientInviteToParty = 163, - ClientJoinParty = 164, - ClientRevokeInvitation = 165, - ClientPassLeadership = 166, - ClientLeaveParty = 167, - ClientShareExperience = 168, - ClientDisbandParty = 169, - ClientOpenOwnChannel = 170, - ClientInviteToOwnChannel = 171, - ClientExcludeFromOwnChannel = 172, - ClientCancelAttackAndFollow = 190, - ClientRefreshContainer = 202, - ClientRequestOutfit = 210, - ClientChangeOutfit = 211, - ClientMount = 212, // 870 - ClientAddVip = 220, - ClientRemoveVip = 221, - ClientBugReport = 230, - ClientRuleViolation= 231, - ClientDebugReport = 232, - ClientRequestQuestLog = 240, - ClientRequestQuestLine = 241, - //ClientRuleViolationReport = 242, - //ClientGetObjectInfo = 243 - ClientExtendedOpcode = 254 // otclient only + ClientEnterAccount = 1, + ClientEnterGame = 10, + ClientLeaveGame = 20, + ClientPingResponse = 30, + ClientAutoWalk = 100, + ClientWalkNorth = 101, + ClientWalkEast = 102, + ClientWalkSouth = 103, + ClientWalkWest = 104, + ClientStop = 105, + ClientWalkNorthEast = 106, + ClientWalkSouthEast = 107, + ClientWalkSouthWest = 108, + ClientWalkNorthWest = 109, + ClientTurnNorth = 111, + ClientTurnEast = 112, + ClientTurnSouth = 113, + ClientTurnWest = 114, + ClientEquipObject = 119, // 910 + ClientMove = 120, + ClientInspectNpcTrade = 121, + ClientBuyItem = 122, + ClientSellItem = 123, + ClientCloseNpcTrade = 124, + ClientRequestTrade = 125, + ClientInspectTrade = 126, + ClientAcceptTrade = 127, + ClientRejectTrade = 128, + ClientUseItem = 130, + ClientUseItemWith = 131, + ClientUseOnCreature = 132, + ClientRotateItem = 133, + ClientCloseContainer = 135, + ClientUpContainer = 136, + ClientEditText = 137, + ClientEditList = 138, + ClientLook = 140, + ClientTalk = 150, + ClientRequestChannels = 151, + ClientJoinChannel = 152, + ClientLeaveChannel = 153, + ClientOpenPrivateChannel = 154, + ClientCloseNpcChannel = 158, + ClientChangeFightModes = 160, + ClientAttack = 161, + ClientFollow = 162, + ClientInviteToParty = 163, + ClientJoinParty = 164, + ClientRevokeInvitation = 165, + ClientPassLeadership = 166, + ClientLeaveParty = 167, + ClientShareExperience = 168, + ClientDisbandParty = 169, + ClientOpenOwnChannel = 170, + ClientInviteToOwnChannel = 171, + ClientExcludeFromOwnChannel = 172, + ClientCancelAttackAndFollow = 190, + ClientRefreshContainer = 202, + ClientRequestOutfit = 210, + ClientChangeOutfit = 211, + ClientMount = 212, // 870 + ClientAddVip = 220, + ClientRemoveVip = 221, + ClientBugReport = 230, + ClientRuleViolation = 231, + ClientDebugReport = 232, + ClientRequestQuestLog = 240, + ClientRequestQuestLine = 241, + ClientRuleViolationReport = 242, // 910 + ClientGetObjectInfo = 243, // 910 + ClientExtendedOpcode = 254 // otclient only }; enum ServerSpeakType { -#if PROTOCOL>=861 +#if PROTOCOL>=910 + ServerSpeakSay = 1, + ServerSpeakWhisper, + ServerSpeakYell, + ServerSpeakPrivateFrom, // new + ServerSpeakPrivateTo, // new + ServerSpeakChannelManagement, // new + ServerSpeakChannelYellow, + ServerSpeakChannelOrange, + ServerSpeakSpell, // new + ServerSpeakPrivatePlayerToNpc, + ServerSpeakPrivateNpcToPlayer, + ServerSpeakBroadcast, + ServerSpeakChannelRed, + ServerSpeakPrivateRedFrom, // new + ServerSpeakPrivateRedTo, // new + // 16 - 33 ?? + ServerSpeakMonsterSay = 34, + ServerSpeakMonsterYell, + + // unsupported + ServerSpeakRVRChannel = 255, + ServerSpeakRVRAnswer, + ServerSpeakRVRContinue, + ServerSpeakChannelRed2, + ServerSpeakChannelWhite +#elif PROTOCOL>=861 ServerSpeakSay = 1, ServerSpeakWhisper, ServerSpeakYell, ServerSpeakPrivatePlayerToNpc, ServerSpeakPrivateNpcToPlayer, - ServerSpeakPrivate, + ServerSpeakPrivateTo, + ServerSpeakPrivateFrom = ServerSpeakPrivateTo, ServerSpeakChannelYellow, ServerSpeakChannelWhite, ServerSpeakBroadcast, @@ -265,7 +294,8 @@ namespace Proto { ServerSpeakYell, ServerSpeakPrivatePlayerToNpc, ServerSpeakPrivateNpcToPlayer, - ServerSpeakPrivate, + ServerSpeakPrivateTo, + ServerSpeakPrivateFrom = ServerSpeakPrivateTo, ServerSpeakChannelYellow, ServerSpeakChannelWhite, ServerSpeakRVRChannel, @@ -273,7 +303,8 @@ namespace Proto { ServerSpeakRVRContinue, ServerSpeakBroadcast, ServerSpeakChannelRed, - ServerSpeakPrivateRed, + ServerSpeakPrivateRedTo, + ServerSpeakPrivateRedFrom = ServerSpeakPrivateRedTo, ServerSpeakChannelOrange, // 16 ?? ServerSpeakChannelRed2 = 17, @@ -284,14 +315,16 @@ namespace Proto { ServerSpeakSay = 1, ServerSpeakWhisper, ServerSpeakYell, - ServerSpeakPrivate, + ServerSpeakPrivateTo, + ServerSpeakPrivateFrom = ServerSpeakPrivateTo, ServerSpeakChannelYellow, ServerSpeakRVRChannel, ServerSpeakRVRAnswer, ServerSpeakRVRContinue, ServerSpeakBroadcast, ServerSpeakChannelRed, - ServerSpeakPrivateRed, + ServerSpeakPrivateRedTo, + ServerSpeakPrivateRedFrom = ServerSpeakPrivateRedTo, ServerSpeakChannelOrange, // 13 ?? ServerSpeakChannelRed2 = 14, @@ -307,7 +340,39 @@ namespace Proto { }; enum MessageTypes { -#if PROTOCOL>=861 +#if PROTOCOL>=910 + // 1-3 ?? + MessageConsoleBlue = 4, // old + // 5-11 ?? + MessageConsoleRed = 12, // old + // 13-15 ?? + MessageStatusDefault = 16, // old + MessageWarning, // old + MessageEventAdvance, // old + MessageStatusSmall, // old + MessageInfoDescription, // old + MessageDamageDealt, // new + MessageDamageReceived, // new + MessageHealed, // new + MessageExperience, // new + MessageDamageOthers, // new + MessageHealedOthers, // new + MessageExperienceOthers, // new + MessageEventDefault, // old + MessageLoot, // new + MessageTradeNpc, // unused + MessageChannelGuild, // new + MessagePartyManagment, // unused + MessageParty, // unused + MessageEventOrange, // old + MessageConsoleOrange, // old + MessageReport, // unused + MessageHotkeyUse, // unused + MessageTutorialHint, // unused + + // unsupported + MessageConsoleOrange2 = 255 +#elif PROTOCOL>=861 MessageConsoleOrange = 13, MessageConsoleOrange2, MessageWarning, @@ -345,6 +410,12 @@ namespace Proto { #endif }; + enum CreatureType { + CreatureTypePlayer = 0, + CreatureTypeMonster, + CreatureTypeNpc + }; + enum CreaturesIdRange { PlayerStartId = 0x10000000, PlayerEndId = 0x40000000, @@ -367,10 +438,10 @@ namespace Proto { case Proto::ServerSpeakChannelRed: return Otc::SpeakChannelRed; case Proto::ServerSpeakChannelRed2: return Otc::SpeakChannelRed; case Proto::ServerSpeakChannelOrange: return Otc::SpeakChannelOrange; - case Proto::ServerSpeakPrivate: return Otc::SpeakPrivate; + case Proto::ServerSpeakPrivateTo: return Otc::SpeakPrivate; case Proto::ServerSpeakPrivatePlayerToNpc: return Otc::SpeakPrivate; case Proto::ServerSpeakBroadcast: return Otc::SpeakBroadcast; - case Proto::ServerSpeakPrivateRed: return Otc::SpeakPrivateRed; + case Proto::ServerSpeakPrivateRedTo: return Otc::SpeakPrivateRed; default: logError("unknown protocol speak type ", type); return Otc::SpeakSay; @@ -383,8 +454,8 @@ namespace Proto { case Otc::SpeakWhisper: return Proto::ServerSpeakWhisper; case Otc::SpeakYell: return Proto::ServerSpeakYell; case Otc::SpeakBroadcast: return Proto::ServerSpeakBroadcast; - case Otc::SpeakPrivate: return Proto::ServerSpeakPrivate; - case Otc::SpeakPrivateRed: return Proto::ServerSpeakPrivateRed; + case Otc::SpeakPrivate: return Proto::ServerSpeakPrivateFrom; + case Otc::SpeakPrivateRed: return Proto::ServerSpeakPrivateRedFrom; case Otc::SpeakPrivatePlayerToNpc: return Proto::ServerSpeakPrivatePlayerToNpc; case Otc::SpeakPrivateNpcToPlayer: return Proto::ServerSpeakPrivateNpcToPlayer; case Otc::SpeakChannelYellow: return Proto::ServerSpeakChannelYellow; diff --git a/src/otclient/net/protocolgame.h b/src/otclient/net/protocolgame.h index 3424af2a..f95a013e 100644 --- a/src/otclient/net/protocolgame.h +++ b/src/otclient/net/protocolgame.h @@ -181,6 +181,9 @@ private: void parseAutomapFlag(InputMessage& msg); void parseQuestLog(InputMessage& msg); void parseQuestLine(InputMessage& msg); + void parseChannelEvent(InputMessage& msg); + void parseObjectInfo(InputMessage& msg); + void parsePlayerInventory(InputMessage& msg); void parseExtendedOpcode(InputMessage& msg); void setMapDescription(InputMessage& msg, int x, int y, int z, int width, int height); diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index fe9c6542..08dd500f 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -41,6 +41,7 @@ void ProtocolGame::parseMessage(InputMessage& msg) try { while(!msg.eof()) { opcode = msg.getU8(); + //dump << opcode; if(m_firstPacket) { if(opcode != Proto::GameServerInitGame) @@ -67,7 +68,6 @@ void ProtocolGame::parseMessage(InputMessage& msg) case Proto::GameServerPing: parsePing(msg); break; - //case Proto::GameServerChallange: case Proto::GameServerDeath: parseDeath(msg); break; @@ -155,7 +155,6 @@ void ProtocolGame::parseMessage(InputMessage& msg) case Proto::GameServerMarkCreature: parseCreatureMark(msg); break; - //case Proto::GameServerTrappers case Proto::GameServerCreatureHealth: parseCreatureHealth(msg); break; @@ -195,14 +194,6 @@ void ProtocolGame::parseMessage(InputMessage& msg) case Proto::GameServerClearTarget: parsePlayerCancelAttack(msg); break; -#if PROTOCOL>=870 - case Proto::GameServerSpellDelay: - parseSpellDelay(msg); - break; - case Proto::GameServerSpellGroupDelay: - parseSpellGroupDelay(msg); - break; -#endif case Proto::GameServerTalk: parseCreatureSpeak(msg); break; @@ -239,7 +230,6 @@ void ProtocolGame::parseMessage(InputMessage& msg) case Proto::GameServerCancelWalk: parseCancelWalk(msg); break; - //case Proto::GameServerWait: case Proto::GameServerFloorChangeUp: parseFloorChangeUp(msg); break; @@ -270,12 +260,33 @@ void ProtocolGame::parseMessage(InputMessage& msg) case Proto::GameServerQuestLine: parseQuestLine(msg); break; - //case Proto::GameServerChannelEvent: - //case Proto::GameServerObjectInfo: - //case Proto::GameServerPlayerInventory: - case Proto::GameServerExtendedOpcode: // additional opcode used by otclient +#if PROTOCOL>=870 + case Proto::GameServerSpellDelay: // 870 only + parseSpellDelay(msg); + break; + case Proto::GameServerSpellGroupDelay: // 870 only + parseSpellGroupDelay(msg); + break; +#endif +#if PROTOCOL>=910 + case Proto::GameServerChannelEvent: // 910 only + parseChannelEvent(msg); + break; + case Proto::GameServerObjectInfo: // 910 only + parseObjectInfo(msg); + break; + case Proto::GameServerPlayerInventory: // 910 only + parsePlayerInventory(msg); + break; +#endif + // additional opcode used by otclient only + case Proto::GameServerExtendedOpcode: parseExtendedOpcode(msg); break; + // not handled yet + //case Proto::GameServerChallange: + //case Proto::GameServerTrappers + //case Proto::GameServerWait: default: Fw::throwException("unknown opcode"); break; @@ -520,6 +531,12 @@ void ProtocolGame::parseRemoveInventoryItem(InputMessage& msg) void ProtocolGame::parseOpenNpcTrade(InputMessage& msg) { std::vector> items; + std::string npcName; + +#if PROTOCOL>=910 + npcName = msg.getString(); +#endif + int listCount = msg.getU8(); for(int i = 0; i < listCount; ++i) { uint16 itemId = msg.getU16(); @@ -600,12 +617,7 @@ void ProtocolGame::parseWorldLight(InputMessage& msg) void ProtocolGame::parseMagicEffect(InputMessage& msg) { Position pos = parsePosition(msg); -#if PROTOCOL>=854 - // newer tibia decreased the max effects number, why??? int effectId = msg.getU8(); -#else - int effectId = msg.getU16(); -#endif EffectPtr effect = EffectPtr(new Effect()); effect->setId(effectId); @@ -777,6 +789,9 @@ void ProtocolGame::parsePlayerStats(InputMessage& msg) #else double freeCapacity = msg.getU16() / 100.0; #endif +#if PROTOCOL>=910 + msg.getU32(); // total capacity +#endif #if PROTOCOL>=870 double experience = msg.getU64(); #else @@ -787,6 +802,9 @@ void ProtocolGame::parsePlayerStats(InputMessage& msg) double mana = msg.getU16(); double maxMana = msg.getU16(); double magicLevel = msg.getU8(); +#if PROTOCOL>=910 + msg.getU8(); // base magic level +#endif double magicLevelPercent = msg.getU8(); double soul = msg.getU8(); double stamina = msg.getU16(); @@ -799,17 +817,22 @@ void ProtocolGame::parsePlayerStats(InputMessage& msg) m_localPlayer->setMagicLevel(magicLevel, magicLevelPercent); m_localPlayer->setStamina(stamina); m_localPlayer->setSoul(soul); + +#if PROTOCOL>=910 + int speed = msg.getU16(); + msg.getU16(); // regeneration time + + m_localPlayer->setSpeed(speed); +#endif } void ProtocolGame::parsePlayerSkills(InputMessage& msg) { - if(!m_localPlayer) { - logTraceError("there is no local player"); - return; - } - for(int skill = 0; skill < Otc::LastSkill; skill++) { int level = msg.getU8(); +#if PROTOCOL>=910 + msg.getU8(); // base +#endif int levelPercent = msg.getU8(); m_localPlayer->setSkill((Otc::Skill)skill, level, levelPercent); @@ -818,13 +841,8 @@ void ProtocolGame::parsePlayerSkills(InputMessage& msg) void ProtocolGame::parsePlayerState(InputMessage& msg) { - if(!m_localPlayer) { - logTraceError("there is no local player"); - return; - } - int states = msg.getU16(); - m_localPlayer->setStates((Otc::PlayerStates)states); + m_localPlayer->setStates(states); } void ProtocolGame::parsePlayerCancelAttack(InputMessage& msg) @@ -852,7 +870,7 @@ void ProtocolGame::parseSpellGroupDelay(InputMessage& msg) void ProtocolGame::parseCreatureSpeak(InputMessage& msg) { - msg.getU32(); // unknown + msg.getU32(); // channel statement guid std::string name = msg.getString(); int level = msg.getU16(); @@ -876,16 +894,18 @@ void ProtocolGame::parseCreatureSpeak(InputMessage& msg) case Proto::ServerSpeakChannelOrange: channelId = msg.getU16(); break; - case Proto::ServerSpeakPrivate: + case Proto::ServerSpeakPrivateFrom: case Proto::ServerSpeakPrivatePlayerToNpc: case Proto::ServerSpeakBroadcast: - case Proto::ServerSpeakPrivateRed: + case Proto::ServerSpeakPrivateRedFrom: break; case Proto::ServerSpeakRVRChannel: msg.getU32(); break; + //case Proto::ServerSpeakChannelManagement: + //case Proto::ServerSpeakSpell: default: - logTraceError("unknown speak type ", speakType); + Fw::throwException("unknown speak type ", speakType); break; } @@ -1106,6 +1126,23 @@ void ProtocolGame::parseQuestLine(InputMessage& msg) g_game.processQuestLine(questId, questMissions); } +void ProtocolGame::parseChannelEvent(InputMessage& msg) +{ + msg.getU16(); // channel id + msg.getString(); // player name + msg.getU8(); // event type +} + +void ProtocolGame::parseObjectInfo(InputMessage& msg) +{ + //TODO +} + +void ProtocolGame::parsePlayerInventory(InputMessage& msg) +{ + //TODO +} + void ProtocolGame::parseExtendedOpcode(InputMessage& msg) { int opcode = msg.getU8(); @@ -1162,11 +1199,16 @@ void ProtocolGame::setFloorDescription(InputMessage& msg, int32 x, int32 y, int3 void ProtocolGame::setTileDescription(InputMessage& msg, Position position) { +#if PROTOCOL>=910 + msg.getU16(); // environment effect +#endif + int stackPos = 0; while(true) { int inspectItemId = msg.getU16(true); - if(inspectItemId >= 0xFF00) + if(inspectItemId >= 0xFF00) { return; + } else { if(stackPos >= 10) logTraceError("too many things, stackpos=", stackPos, " pos=", position); @@ -1222,9 +1264,8 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg) ThingPtr thing; int thingId = msg.getU16(); - if(thingId == 0) { - Fw::throwException("[ProtocolGame::internalGetThing] thingId == 0"); - } + if(thingId == 0) + Fw::throwException("thingId == 0"); if(thingId == 0x0061 || thingId == 0x0062) { // add new creature CreaturePtr creature; @@ -1240,6 +1281,18 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg) } else if(thingId == 0x0061) { //creature is not known uint removeId = msg.getU32(); uint id = msg.getU32(); + + int creatureType; +#if PROTOCOL>=910 + creatureType = msg.getU8(); +#else + if(id >= Proto::PlayerStartId && id < Proto::PlayerEndId) + creatureType = Proto::CreatureTypePlayer; + else if(id >= Proto::MonsterStartId && id < Proto::MonsterEndId) + creatureType = Proto::CreatureTypeMonster; + else + creatureType = Proto::CreatureTypeNpc; +#endif std::string name = msg.getString(); if(name.length() > 0) // every creature name must start with a capital letter @@ -1249,14 +1302,14 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg) if(id == m_localPlayer->getId()) creature = m_localPlayer; - else if(id >= Proto::PlayerStartId && id < Proto::PlayerEndId) + else if(creatureType == Proto::CreatureTypePlayer) creature = PlayerPtr(new Player); - else if(id >= Proto::MonsterStartId && id < Proto::MonsterEndId) + else if(creatureType == Proto::CreatureTypeMonster) creature = MonsterPtr(new Monster); - else if(id >= Proto::NpcStartId && id < Proto::NpcEndId) + else if(creatureType == Proto::CreatureTypeNpc) creature = NpcPtr(new Npc); else - logTraceError("creature id is invalid"); + logTraceError("creature type is invalid"); if(creature) { creature->setId(id); @@ -1321,9 +1374,20 @@ ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, int id) id = msg.getU16(); ItemPtr item = Item::create(id); + if(item->getId() == 0) + Fw::throwException("unable to create item with invalid id"); + if(item->isStackable() || item->isFluidContainer() || item->isFluid()) item->setCountOrSubType(msg.getU8()); +#if PROTOCOL>=910 + if(item->getAnimationPhases() > 1) { + // 0xfe => random phase + // 0xff => async? + msg.getU8(); + } +#endif + return item; } diff --git a/src/otclient/net/protocolgamesend.cpp b/src/otclient/net/protocolgamesend.cpp index 697bdad6..fe8b36bf 100644 --- a/src/otclient/net/protocolgamesend.cpp +++ b/src/otclient/net/protocolgamesend.cpp @@ -406,8 +406,8 @@ void ProtocolGame::sendTalk(Otc::SpeakType speakType, int channelId, const std:: msg.addU8(serverSpeakType); switch(serverSpeakType) { - case Proto::ServerSpeakPrivate: - case Proto::ServerSpeakPrivateRed: + case Proto::ServerSpeakPrivateFrom: + case Proto::ServerSpeakPrivateRedFrom: msg.addString(receiver); break; case Proto::ServerSpeakChannelYellow: @@ -530,7 +530,9 @@ void ProtocolGame::sendShareExperience(bool active, int unknown) OutputMessage msg; msg.addU8(Proto::ClientShareExperience); msg.addU8(active ? 0x01 : 0x00); +#if PROTOCOL<910 msg.addU8(unknown); +#endif send(msg); }