43 opcode = msg->
getU8();
49 m_gameInitialized =
true;
55 if(callLuaField<bool>(
"onOpcode", opcode, msg))
63 parsePendingGame(msg);
71 parseUpdateNeeded(msg);
77 parseLoginAdvice(msg);
100 parseMapDescription(msg);
103 parseMapMoveNorth(msg);
106 parseMapMoveEast(msg);
109 parseMapMoveSouth(msg);
112 parseMapMoveWest(msg);
115 parseUpdateTile(msg);
118 parseTileAddThing(msg);
121 parseTileTransformThing(msg);
124 parseTileRemoveThing(msg);
127 parseCreatureMove(msg);
130 parseOpenContainer(msg);
133 parseCloseContainer(msg);
136 parseContainerAddItem(msg);
139 parseContainerUpdateItem(msg);
142 parseContainerRemoveItem(msg);
145 parseAddInventoryItem(msg);
148 parseRemoveInventoryItem(msg);
151 parseOpenNpcTrade(msg);
154 parsePlayerGoods(msg);
157 parseCloseNpcTrade(msg);
163 parseCounterTrade(msg);
166 parseCloseTrade(msg);
169 parseWorldLight(msg);
172 parseMagicEffect(msg);
175 parseAnimatedText(msg);
178 parseDistanceMissile(msg);
181 parseCreatureMark(msg);
187 parseCreatureHealth(msg);
190 parseCreatureLight(msg);
193 parseCreatureOutfit(msg);
196 parseCreatureSpeed(msg);
199 parseCreatureSkulls(msg);
202 parseCreatureShields(msg);
205 parseCreatureUnpass(msg);
215 parsePremiumTrigger(msg);
218 parsePlayerStats(msg);
221 parsePlayerSkills(msg);
224 parsePlayerState(msg);
227 parsePlayerCancelAttack(msg);
230 parsePlayerModes(msg);
236 parseChannelList(msg);
239 parseOpenChannel(msg);
242 parseOpenPrivateChannel(msg);
245 parseRuleViolationChannel(msg);
248 parseRuleViolationRemove(msg);
251 parseRuleViolationCancel(msg);
254 parseRuleViolationLock(msg);
257 parseOpenOwnPrivateChannel(msg);
260 parseCloseChannel(msg);
263 parseTextMessage(msg);
266 parseCancelWalk(msg);
272 parseFloorChangeUp(msg);
275 parseFloorChangeDown(msg);
278 parseOpenOutfitWindow(msg);
290 parseTutorialHint(msg);
293 parseAutomapFlag(msg);
303 parseSpellCooldown(msg);
306 parseSpellGroupCooldown(msg);
309 parseMultiUseCooldown(msg);
313 parseChannelEvent(msg);
319 parsePlayerInventory(msg);
323 parsePlayerInfo(msg);
327 parseModalDialog(msg);
337 parsePlayerHelpers(msg);
341 parseCreaturesMark(msg);
344 parseCreatureType(msg);
351 parseUnjustifiedStats(msg);
354 parsePvpSituations(msg);
361 parseCoinBalanceUpdating(msg);
364 parseCoinBalance(msg);
367 parseRequestPurchaseData(msg);
370 parseCompleteStorePurchase(msg);
373 parseStoreOffers(msg);
376 parseStoreTransactionHistory(msg);
379 parseStoreError(msg);
386 parseStoreButtonIndicators(msg);
389 parseSetStoreDeepLink(msg);
393 parseExtendedOpcode(msg);
396 parseChangeMapAwareRange(msg);
413 int serverBeat = msg->
getU16();
427 int expertModeEnabled = msg->
getU8();
440 m_localPlayer->
setId(playerId);
458 if(!m_gameInitialized) {
460 m_gameInitialized =
true;
464 void ProtocolGame::parseStoreButtonIndicators(
const InputMessagePtr& msg)
486 void ProtocolGame::parseRequestPurchaseData(
const InputMessagePtr& msg)
494 parseCoinBalance(msg);
496 int categories = msg->
getU16();
497 for(
int i = 0; i < categories; i++) {
499 std::string description = msg->
getString();
501 int highlightState = 0;
503 highlightState = msg->
getU8();
505 std::vector<std::string> icons;
506 int iconCount = msg->
getU8();
507 for(
int j = 0; j < iconCount; j++) {
509 icons.push_back(icon);
520 bool update = msg->
getU8() == 1;
522 int transferableCoins = -1;
530 transferableCoins = msg->
getU32();
534 void ProtocolGame::parseCoinBalanceUpdating(
const InputMessagePtr& msg)
537 bool isUpdating = msg->
getU8() == 1;
540 void ProtocolGame::parseCompleteStorePurchase(
const InputMessagePtr& msg)
546 int coins = msg->
getU32();
547 int transferableCoins = msg->
getU32();
549 g_logger.
info(
stdext::format(
"Purchase Complete: %s\nAvailable coins: %d (transferable: %d)", message, coins, transferableCoins));
552 void ProtocolGame::parseStoreTransactionHistory(
const InputMessagePtr &msg)
556 currentPage = msg->
getU16();
559 currentPage = msg->
getU32();
563 int entries = msg->
getU8();
564 for(
int i = 0; i < entries; i++) {
566 int productType = msg->
getU8();
567 int coinChange = msg->
getU32();
568 std::string productName = msg->
getString();
577 int offers = msg->
getU16();
578 for(
int i = 0; i < offers; i++) {
584 int highlightState = msg->
getU8();
590 int disabledState = msg->
getU8();
595 std::vector<std::string> icons;
596 int iconCount = msg->
getU8();
597 for(
int j = 0; j < iconCount; j++) {
599 icons.push_back(icon);
602 int subOffers = msg->
getU16();
603 for(
int j = 0; j < subOffers; j++) {
607 int subIcons = msg->
getU8();
608 for(
int k = 0; k < subIcons; k++) {
618 int errorType = msg->
getU8();
647 int helpers = msg->
getU16();
658 std::vector<uint8> actions;
660 int numViolationReasons;
663 numViolationReasons = 20;
665 numViolationReasons = 23;
667 numViolationReasons = 32;
669 for(
int i = 0; i < numViolationReasons; ++i)
670 actions.push_back(msg->
getU8());
676 std::string signature = msg->
getString();
704 bool unknown = (msg->
getU8() == 0);
732 deathType = msg->
getU8();
735 penality = msg->
getU8();
828 stackPos = msg->
getU8();
844 Position pos = thing->getPosition();
845 int stackpos = thing->getStackPos();
848 g_logger.traceError(
"unable to remove thing");
864 g_logger.traceError(
"unable to remove thing");
872 if(!thing || !thing->isCreature()) {
873 g_logger.traceError(
"no creature found to move");
878 g_logger.traceError(
"unable to remove creature");
883 creature->allowAppearWalk();
890 int containerId = msg->
getU8();
893 int capacity = msg->
getU8();
894 bool hasParent = (msg->
getU8() != 0);
896 bool isUnlocked =
true;
897 bool hasPages =
false;
898 int containerSize = 0;
902 isUnlocked = (msg->
getU8() != 0);
903 hasPages = (msg->
getU8() != 0);
904 containerSize = msg->
getU16();
905 firstIndex = msg->
getU16();
908 int itemCount = msg->
getU8();
910 std::vector<ItemPtr> items(itemCount);
911 for(
int i = 0; i < itemCount; i++)
914 g_game.
processOpenContainer(containerId, containerItem, name, capacity, hasParent, items, isUnlocked, hasPages, containerSize, firstIndex);
919 int containerId = msg->
getU8();
925 int containerId = msg->
getU8();
934 void ProtocolGame::parseContainerUpdateItem(
const InputMessagePtr& msg)
936 int containerId = msg->
getU8();
947 void ProtocolGame::parseContainerRemoveItem(
const InputMessagePtr& msg)
949 int containerId = msg->
getU8();
955 int itemId = msg->
getU16();
957 lastItem =
getItem(msg, itemId);
966 int slot = msg->
getU8();
971 void ProtocolGame::parseRemoveInventoryItem(
const InputMessagePtr& msg)
973 int slot = msg->
getU8();
979 std::vector<std::tuple<ItemPtr, std::string, int, int, int>> items;
988 listCount = msg->
getU16();
990 listCount = msg->
getU8();
992 for(
int i = 0; i < listCount; ++i) {
1000 int weight = msg->
getU32();
1001 int buyPrice = msg->
getU32();
1002 int sellPrice = msg->
getU32();
1003 items.emplace_back(item, name, weight, buyPrice, sellPrice);
1011 std::vector<std::tuple<ItemPtr, int>> goods;
1019 int size = msg->
getU8();
1020 for(
int i = 0; i < size; i++) {
1021 int itemId = msg->
getU16();
1027 amount = msg->
getU8();
1043 int count = msg->
getU8();
1045 std::vector<ItemPtr> items(count);
1046 for(
int i = 0; i < count; i++)
1055 int count = msg->
getU8();
1057 std::vector<ItemPtr> items(count);
1058 for(
int i = 0; i < count; i++)
1083 effectId = msg->
getU16();
1085 effectId = msg->
getU8();
1093 effect->setId(effectId);
1100 int color = msg->
getU8();
1104 animatedText->setColor(color);
1105 animatedText->setText(text);
1113 int shotId = msg->
getU8();
1121 missile->setId(shotId);
1122 missile->setPath(fromPos, toPos);
1129 int color = msg->
getU8();
1133 creature->addTimedSquare(color);
1135 g_logger.traceError(
"could not get creature");
1140 int numTrappers = msg->
getU8();
1143 g_logger.traceError(
"too many trappers");
1145 for(
int i=0;i<numTrappers;++i) {
1151 g_logger.traceError(
"could not get creature");
1158 int healthPercent = msg->
getU8();
1162 creature->setHealthPercent(healthPercent);
1182 creature->setLight(light);
1184 g_logger.traceError(
"could not get creature");
1194 creature->setOutfit(outfit);
1196 g_logger.traceError(
"could not get creature");
1205 baseSpeed = msg->
getU16();
1207 int speed = msg->
getU16();
1211 creature->setSpeed(speed);
1213 creature->setBaseSpeed(baseSpeed);
1227 int skull = msg->
getU8();
1231 creature->setSkull(skull);
1233 g_logger.traceError(
"could not get creature");
1239 int shield = msg->
getU8();
1243 creature->setShield(shield);
1245 g_logger.traceError(
"could not get creature");
1251 bool unpass = msg->
getU8();
1255 creature->setPassable(!unpass);
1257 g_logger.traceError(
"could not get creature");
1268 itemId = item->
getId();
1272 int maxLength = msg->
getU16();
1276 std::string date =
"";
1285 int doorId = msg->
getU8();
1287 const std::string& text = msg->
getString();
1294 int triggerCount = msg->
getU8();
1295 std::vector<int> triggers;
1296 for(
int i=0;i<triggerCount;++i) {
1297 triggers.push_back(msg->
getU8());
1301 bool something = msg->
getU8() == 1;
1307 bool premium = msg->
getU8();
1310 int vocation = msg->
getU8();
1312 int spellCount = msg->
getU16();
1313 std::vector<int> spells;
1314 for(
int i=0;i<spellCount;++i)
1315 spells.push_back(msg->
getU8());
1329 maxHealth = msg->
getU32();
1332 maxHealth = msg->
getU16();
1335 double freeCapacity;
1337 freeCapacity = msg->
getU32() / 100.0;
1339 freeCapacity = msg->
getU16() / 100.0;
1341 double totalCapacity = 0;
1343 totalCapacity = msg->
getU32() / 100.0;
1347 experience = msg->
getU64();
1349 experience = msg->
getU32();
1351 double level = msg->
getU16();
1352 double levelPercent = msg->
getU8();
1377 double magicLevel = msg->
getU8();
1379 double baseMagicLevel;
1381 baseMagicLevel = msg->
getU8();
1383 baseMagicLevel = magicLevel;
1385 double magicLevelPercent = msg->
getU8();
1386 double soul = msg->
getU8();
1391 double baseSpeed = 0;
1393 baseSpeed = msg->
getU16();
1395 double regeneration = 0;
1397 regeneration = msg->
getU16();
1399 double training = 0;
1401 training = msg->
getU16();
1403 int remainingStoreXpBoostSeconds = msg->
getU16();
1404 bool canBuyMoreStoreXpBoosts = msg->
getU8();
1408 m_localPlayer->
setHealth(health, maxHealth);
1412 m_localPlayer->
setLevel(level, levelPercent);
1413 m_localPlayer->
setMana(mana, maxMana);
1414 m_localPlayer->
setMagicLevel(magicLevel, magicLevelPercent);
1429 for(
int skill = 0; skill < lastSkill; skill++) {
1435 level = msg->
getU8();
1440 baseLevel = msg->
getU16();
1442 baseLevel = msg->
getU8();
1446 int levelPercent = 0;
1449 levelPercent = msg->
getU8();
1462 states = msg->
getU8();
1467 void ProtocolGame::parsePlayerCancelAttack(
const InputMessagePtr& msg)
1479 int fightMode = msg->
getU8();
1480 int chaseMode = msg->
getU8();
1481 bool safeMode = msg->
getU8();
1485 pvpMode = msg->
getU8();
1492 int spellId = msg->
getU8();
1493 int delay = msg->
getU32();
1498 void ProtocolGame::parseSpellGroupCooldown(
const InputMessagePtr& msg)
1500 int groupId = msg->
getU8();
1501 int delay = msg->
getU32();
1508 int delay = msg->
getU32();
1545 channelId = msg->
getU16();
1569 int count = msg->
getU8();
1570 std::vector<std::tuple<int, std::string> > channelList;
1571 for(
int i = 0; i < count; i++) {
1574 channelList.emplace_back(
id, name);
1582 int channelId = msg->
getU16();
1586 int joinedPlayers = msg->
getU16();
1587 for(
int i=0;i<joinedPlayers;++i)
1589 int invitedPlayers = msg->
getU16();
1590 for(
int i=0;i<invitedPlayers;++i)
1597 void ProtocolGame::parseOpenPrivateChannel(
const InputMessagePtr& msg)
1604 void ProtocolGame::parseOpenOwnPrivateChannel(
const InputMessagePtr& msg)
1606 int channelId = msg->
getU16();
1614 int channelId = msg->
getU16();
1619 void ProtocolGame::parseRuleViolationChannel(
const InputMessagePtr& msg)
1621 int channelId = msg->
getU16();
1626 void ProtocolGame::parseRuleViolationRemove(
const InputMessagePtr& msg)
1633 void ProtocolGame::parseRuleViolationCancel(
const InputMessagePtr& msg)
1647 int code = msg->
getU8();
1672 value[0] = msg->
getU32();
1673 color[0] = msg->
getU8();
1676 value[1] = msg->
getU32();
1677 color[1] = msg->
getU8();
1680 for(
int i=0;i<2;++i) {
1684 animatedText->setColor(color[i]);
1697 int color = msg->
getU8();
1701 animatedText->setColor(color);
1779 std::vector<std::tuple<int, std::string, int> > outfitList;
1782 int outfitCount = msg->
getU8();
1783 for(
int i = 0; i < outfitCount; i++) {
1784 int outfitId = msg->
getU16();
1785 std::string outfitName = msg->
getString();
1786 int outfitAddons = msg->
getU8();
1788 outfitList.emplace_back(outfitId, outfitName, outfitAddons);
1791 int outfitStart, outfitEnd;
1793 outfitStart = msg->
getU16();
1794 outfitEnd = msg->
getU16();
1796 outfitStart = msg->
getU8();
1797 outfitEnd = msg->
getU8();
1800 for(
int i = outfitStart; i <= outfitEnd; i++)
1801 outfitList.emplace_back(i,
"", 0);
1804 std::vector<std::tuple<int, std::string> > mountList;
1806 int mountCount = msg->
getU8();
1807 for(
int i = 0; i < mountCount; ++i) {
1808 int mountId = msg->
getU16();
1809 std::string mountName = msg->
getString();
1811 mountList.emplace_back(mountId, mountName);
1820 uint id, iconId = 0, status;
1821 std::string name, desc =
"";
1822 bool notifyLogin =
false;
1829 notifyLogin = msg->
getU8();
1831 status = msg->
getU8();
1856 int id = msg->
getU8();
1863 int icon = msg->
getU8();
1864 std::string description = msg->
getString();
1866 bool remove =
false;
1868 remove = msg->
getU8() != 0;
1878 std::vector<std::tuple<int, std::string, bool> > questList;
1879 int questsCount = msg->
getU16();
1880 for(
int i = 0; i < questsCount; i++) {
1883 bool completed = msg->
getU8();
1884 questList.emplace_back(
id, name, completed);
1892 std::vector<std::tuple<std::string, std::string>> questMissions;
1893 int questId = msg->
getU16();
1894 int missionCount = msg->
getU8();
1895 for(
int i = 0; i < missionCount; i++) {
1896 std::string missionName = msg->
getString();
1897 std::string missionDescrition = msg->
getString();
1898 questMissions.emplace_back(missionName, missionDescrition);
1915 std::vector<std::tuple<ItemPtr, std::string>> list;
1916 int size = msg->
getU8();
1917 for(
int i=0;i<size;++i) {
1923 list.emplace_back(item, desc);
1931 int size = msg->
getU16();
1932 for(
int i=0;i<size;++i) {
1945 int sizeButtons = msg->
getU8();
1946 std::vector<std::tuple<int, std::string> > buttonList;
1947 for(
int i = 0; i < sizeButtons; ++i) {
1949 int buttonId = msg->
getU8();
1950 buttonList.push_back(std::make_tuple(buttonId, value));
1953 int sizeChoices = msg->
getU8();
1954 std::vector<std::tuple<int, std::string> > choiceList;
1955 for(
int i = 0; i < sizeChoices; ++i) {
1957 int choideId = msg->
getU8();
1958 choiceList.push_back(std::make_tuple(choideId, value));
1961 int enterButton, escapeButton;
1963 escapeButton = msg->
getU8();
1964 enterButton = msg->
getU8();
1967 enterButton = msg->
getU8();
1968 escapeButton = msg->
getU8();
1971 bool priority = msg->
getU8() == 0x01;
1978 int opcode = msg->
getU8();
1982 m_enableSendExtendedOpcode =
true;
1983 else if(opcode == 2)
1989 void ProtocolGame::parseChangeMapAwareRange(
const InputMessagePtr& msg)
1991 int xrange = msg->
getU8();
1992 int yrange = msg->
getU8();
1995 range.
left = xrange/2 - ((xrange+1) % 2);
1996 range.
right = xrange/2;
1997 range.
top = yrange/2 - ((yrange+1) % 2);
2013 for(
int i=0; i<len; ++i) {
2015 bool isPermanent = msg->
getU8() != 1;
2021 if(markType == 0xff)
2022 creature->hideStaticSquare();
2026 creature->addTimedSquare(markType);
2028 g_logger.traceError(
"could not get creature");
2039 creature->setType(type);
2041 g_logger.traceError(
"could not get creature");
2046 int startz, endz, zstep;
2060 for(
int nz = startz; nz != endz + zstep; nz += zstep)
2066 for(
int nx = 0; nx < width; nx++) {
2067 for(
int ny = 0; ny < height; ny++) {
2068 Position tilePos(x + nx + offset, y + ny + offset,
z);
2084 bool gotEffect =
false;
2085 for(
int stackPos=0;stackPos<256;stackPos++) {
2087 return msg->
getU16() & 0xff;
2110 lookType = msg->
getU16();
2112 lookType = msg->
getU8();
2116 int head = msg->
getU8();
2117 int body = msg->
getU8();
2118 int legs = msg->
getU8();
2119 int feet = msg->
getU8();
2122 addons = msg->
getU8();
2129 outfit.
setId(lookType);
2137 int lookTypeEx = msg->
getU16();
2138 if(lookTypeEx == 0) {
2189 assert(stackpos != 255);
2215 g_logger.traceError(
"server said that a creature is known, but it's not");
2224 creatureType = msg->
getU8();
2236 if(
id == m_localPlayer->
getId())
2237 creature = m_localPlayer;
2240 if(m_localPlayer->
getId() == 0 && name == m_localPlayer->
getName())
2241 creature = m_localPlayer;
2250 g_logger.traceError(
"creature type is invalid");
2253 creature->
setId(
id);
2260 int healthPercent = msg->
getU8();
2268 int speed = msg->
getU16();
2269 int skull = msg->
getU8();
2270 int shield = msg->
getU8();
2274 int8 creatureType = -1;
2280 emblem = msg->
getU8();
2283 creatureType = msg->
getU8();
2287 icon = msg->
getU8();
2291 mark = msg->
getU8();
2303 unpass = msg->
getU8();
2318 if(creatureType != -1)
2319 creature->
setType(creatureType);
2324 if(creature == m_localPlayer && !m_localPlayer->
isKnown())
2332 g_logger.traceError(
"invalid creature");
2336 creature->
turn(direction);
2339 bool unpass = msg->
getU8();
2358 if(item->
getId() == 0)
2383 int colorByte = msg->
getU8();
2385 std::string fontName = msg->
getString();
2388 staticText->setText(text);
2389 staticText->setFont(fontName);
2390 staticText->setColor(color);