void TradeHandler::processTradeItemAdd(Net::MessageIn &msg) { const int amount = msg.readInt32("amount"); const int type = msg.readInt16("type"); const uint8_t identify = msg.readUInt8("identify"); msg.readUInt8("attribute"); const uint8_t refine = msg.readUInt8("refine"); int cards[4]; for (int f = 0; f < 4; f++) cards[f] = msg.readInt16("card"); if (tradeWindow) { if (type == 0) { tradeWindow->setMoney(amount); } else { tradeWindow->addItem2(type, 0, cards, 4, false, amount, refine, 1, fromBool(identify, Identified), Damaged_false, Favorite_false, Equipm_false); } } }
void MailRecv::processReadMail(Net::MessageIn &msg) { const int sz = msg.readInt16("len") - 101; MailMessage *const mail = new MailMessage; mail->id = msg.readInt32("message id"); mail->title = msg.readString(40, "title"); mail->sender = msg.readString(24, "sender name"); msg.readInt32("unused"); mail->money = msg.readInt32("money"); mail->itemAmount = msg.readInt32("item amount"); mail->itemId = msg.readInt16("item id"); mail->itemType = msg.readInt16("item type"); mail->itemIdentify = msg.readUInt8("identify"); mail->itemAttribute = msg.readUInt8("attribute"); mail->itemRefine = msg.readUInt8("refine"); for (int f = 0; f < maxCards; f ++) mail->card[f] = msg.readUInt16("card"); const int msgLen = msg.readUInt8("msg len"); if (msgLen != sz) logger->log("error: wrong message size"); mail->text = msg.readString(sz, "message"); msg.readUInt8("zero"); mail->strTime = timeToStr(mail->time); mailWindow->showMessage(mail); }
void AuctionRecv::processAuctionResults(Net::MessageIn &msg) { UNIMPLEMENTEDPACKET; msg.readInt16("len"); msg.readInt32("pages"); const int itemCount = msg.readInt32("items count"); for (int f = 0; f < itemCount; f ++) { msg.readInt32("auction id"); msg.readString(24, "seller name"); msg.readInt16("item id"); // here item always 16 bit msg.readInt32("auction type"); msg.readInt16("item amount"); // always 1 msg.readUInt8("identify"); msg.readUInt8("attribute"); msg.readUInt8("refine"); for (int d = 0; d < maxCards; d ++) msg.readUInt16("card"); // here item always 16 bit msg.readInt32("price"); msg.readInt32("buy now"); msg.readString(24, "buyer name"); msg.readInt32("timestamp"); // +++ need use ItemColorManager for color } }
void ItemRecv::processItemDropped2(Net::MessageIn &msg) { const BeingId id = msg.readBeingId("id"); const int itemId = msg.readInt16("item id"); const ItemTypeT itemType = static_cast<ItemTypeT>(msg.readUInt8("type")); const Identified identified = fromInt( msg.readUInt8("identify"), Identified); const Damaged damaged = fromBool(msg.readUInt8("attribute"), Damaged); const uint8_t refine = msg.readUInt8("refine"); int cards[maxCards]; for (int f = 0; f < maxCards; f++) cards[f] = msg.readInt16("card"); const int x = msg.readInt16("x"); const int y = msg.readInt16("y"); const int amount = msg.readInt16("amount"); const int subX = CAST_S32(msg.readInt8("subx")); const int subY = CAST_S32(msg.readInt8("suby")); if (actorManager) { actorManager->createItem(id, itemId, x, y, itemType, amount, refine, ItemColorManager::getColorFromCards(&cards[0]), identified, damaged, subX, subY, &cards[0]); } }
void VendingHandler::processItemsList(Net::MessageIn &msg) { const int count = (msg.readInt16("len") - 12) / 22; const BeingId id = msg.readBeingId("id"); Being *const being = actorManager->findBeing(id); if (!being) return; int cards[4]; CREATEWIDGETV(mBuyDialog, BuyDialog, being->getName()); mBuyDialog->setMoney(PlayerInfo::getAttribute(Attributes::MONEY)); msg.readInt32("vender id"); for (int f = 0; f < count; f ++) { const int value = msg.readInt32("price"); const int amount = msg.readInt16("amount"); const int index = msg.readInt16("inv index"); const int type = msg.readUInt8("item type"); const int itemId = msg.readInt16("item id"); msg.readUInt8("identify"); msg.readUInt8("attribute"); msg.readUInt8("refine"); for (int d = 0; d < 4; d ++) cards[d] = msg.readInt16("card"); const ItemColor color = ItemColorManager::getColorFromCards(&cards[0]); ShopItem *const item = mBuyDialog->addItem(itemId, type, color, amount, value); if (item) item->setInvIndex(index); } mBuyDialog->sort(); }
void VendingRecv::processOpen(Net::MessageIn &msg) { const int count = (msg.readInt16("len") - 8) / 22; msg.readInt32("id"); for (int f = 0; f < count; f ++) { msg.readInt32("price"); msg.readInt16("inv index"); msg.readInt16("amount"); msg.readUInt8("item type"); msg.readInt16("item id"); msg.readUInt8("identify"); msg.readUInt8("attribute"); msg.readUInt8("refine"); for (int d = 0; d < 4; d ++) msg.readInt16("card"); if (serverVersion >= 8 && packetVersion >= 20150226) { for (int d = 0; d < 5; d ++) { msg.readInt16("rnd index"); msg.readInt16("rnd value"); msg.readUInt8("rnd param"); } } } PlayerInfo::enableVending(true); VendingModeListener::distributeEvent(true); }
void ItemRecv::processItemMvpDropped(Net::MessageIn &msg) { UNIMPLIMENTEDPACKET; msg.readInt16("len"); msg.readUInt8("type"); msg.readInt16("item id"); msg.readUInt8("len"); msg.readString(24, "name"); msg.readUInt8("monster name len"); msg.readString(24, "monster name"); }
void CharServerRecv::processCharLogin2(Net::MessageIn &msg) { // ignored msg.readInt16("len"); msg.readUInt8("char slots"); msg.readUInt8("left slots"); msg.readUInt8("left slots"); msg.readUInt8("char slots"); msg.readUInt8("char slots"); msg.skip(20, "unused"); }
void ItemHandler::processGraffiti(Net::MessageIn &msg) { UNIMPLIMENTEDPACKET; msg.readInt32("graffiti id"); msg.readInt32("creator id"); msg.readInt16("x"); msg.readInt16("y"); msg.readUInt8("job"); msg.readUInt8("visible"); msg.readUInt8("is content"); msg.readString(80, "text"); }
void PlayerHandler::processPlayerShortcuts(Net::MessageIn &msg) { // +++ player shortcuts ignored. It also disabled on server side. // may be in future better use it? msg.readUInt8("unused?"); for (int f = 0; f < 27; f ++) { msg.readUInt8("type 0: item, 1: skill"); msg.readInt32("item or skill id"); msg.readInt16("skill level"); } msg.skip(77, "unused"); }
void TradeRecv::processTradeItemAdd(Net::MessageIn &msg) { const int type = msg.readInt16("type"); ItemTypeT itemType = ItemType::Unknown; if (msg.getVersion() >= 20100223) { itemType = static_cast<ItemTypeT>( msg.readUInt8("item type")); } const int amount = msg.readInt32("amount"); const uint8_t identify = msg.readUInt8("identify"); const Damaged damaged = fromBool(msg.readUInt8("attribute"), Damaged); const uint8_t refine = msg.readUInt8("refine"); int cards[maxCards]; for (int f = 0; f < maxCards; f++) cards[f] = msg.readInt16("card"); if ((serverVersion >= 8 || serverVersion == 0) && msg.getVersion() >= 20150226) { for (int f = 0; f < 5; f ++) { msg.readInt16("rnd index"); msg.readInt16("rnd value"); msg.readUInt8("rnd param"); } } if (tradeWindow) { if (type == 0) { tradeWindow->setMoney(amount); } else { tradeWindow->addItem2(type, itemType, cards, 4, false, amount, refine, ItemColorManager::getColorFromCards(&cards[0]), fromBool(identify, Identified), damaged, Favorite_false, Equipm_false); } } }
void AchievementRecv::processAchievementUpdate(Net::MessageIn &msg) { UNIMPLEMENTEDPACKET; msg.readInt32("total points"); msg.readInt16("rank level"); msg.readInt32("rank points"); msg.readInt32("rank points need"); msg.readInt32("ach id"); msg.readUInt8("completed"); for (int d = 0; d < 10; d ++) msg.readInt32("objective"); msg.readInt32("completed at"); msg.readUInt8("reward"); }
void SearchStoreRecv::processSearchFailed(Net::MessageIn &msg) { UNIMPLIMENTEDPACKET; const int result = msg.readUInt8("result"); switch (result) { case 0: NotifyManager::notify( NotifyTypes::SEARCH_STORE_FAILED_NO_STORES); break; case 1: NotifyManager::notify( NotifyTypes::SEARCH_STORE_FAILED_MANY_RESULTS); break; case 2: NotifyManager::notify( NotifyTypes::SEARCH_STORE_FAILED_CANT_SEARCH_ANYMORE); break; case 3: NotifyManager::notify( NotifyTypes::SEARCH_STORE_FAILED_CANT_SEARCH_YET); break; case 4: NotifyManager::notify( NotifyTypes::SEARCH_STORE_FAILED_NO_INFORMATION); break; default: NotifyManager::notify( NotifyTypes::SEARCH_STORE_FAILED); break; } }
void GameRecv::processMapLogin(Net::MessageIn &msg) { unsigned char direction; uint16_t x; uint16_t y; msg.readInt32("start time"); msg.readCoordinates(x, y, direction, "position"); msg.readInt8("x size"); msg.readInt8("y size"); logger->log("Protocol: Player start position: " "(%d, %d), Direction: %d", x, y, direction); if (msg.getVersion() >= 20080102) msg.readInt16("font"); if (msg.getVersion() >= 20141022 && msg.getVersion() < 20160330) msg.readUInt8("sex"); mLastHost &= 0xffffff; Network *const network = Network::mInstance; if (network != nullptr) network->pauseDispatch(); // Switch now or we'll have problems client->setState(State::GAME); if (localPlayer != nullptr) localPlayer->setTileCoords(x, y); }
void PartyHandler::processPartyCreate(Net::MessageIn &msg) const { if (msg.readUInt8()) NotifyManager::notify(NotifyTypes::PARTY_CREATE_FAILED); else NotifyManager::notify(NotifyTypes::PARTY_CREATED); }
void NpcHandler::processNpcCutin(Net::MessageIn &msg) { UNIMPLIMENTEDPACKET; mRequestLang = false; msg.readString(64, "image name"); msg.readUInt8("type"); }
void NpcHandler::processShowDigit(Net::MessageIn &msg) { UNIMPLIMENTEDPACKET; msg.readUInt8("type"); msg.readInt32("value"); }
void ItemRecv::processItemDropped(Net::MessageIn &msg) { const BeingId id = msg.readBeingId("id"); const int itemId = msg.readInt16("item id"); ItemTypeT itemType = ItemType::Unknown; if (msg.getVersion() >= 20130000) itemType = static_cast<ItemTypeT>(msg.readInt16("type")); const Identified identified = fromInt( msg.readUInt8("identify"), Identified); const int x = msg.readInt16("x"); const int y = msg.readInt16("y"); const int subX = CAST_S32(msg.readInt8("subx")); const int subY = CAST_S32(msg.readInt8("suby")); const int amount = msg.readInt16("count"); if (actorManager) { actorManager->createItem(id, itemId, x, y, itemType, amount, 0, ItemColor_one, identified, Damaged_false, subX, subY, nullptr); } }
void SkillRecv::processSkillAdd(Net::MessageIn &msg) { int updateSkill = 0; const int skillId = msg.readInt16("skill id"); const SkillType::SkillType inf = static_cast<SkillType::SkillType>( msg.readInt32("inf")); const int level = msg.readInt16("skill level"); const int sp = msg.readInt16("sp"); const int range = msg.readInt16("range"); const std::string name = msg.readString(24, "skill name"); const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable); const int oldLevel = PlayerInfo::getSkillLevel(skillId); if ((oldLevel != 0) && oldLevel != level) updateSkill = skillId; PlayerInfo::setSkillLevel(skillId, level); if (skillDialog != nullptr) { if (!skillDialog->updateSkill(skillId, range, up, inf, sp)) { skillDialog->addSkill(SkillOwner::Player, skillId, name, level, range, up, inf, sp); } skillDialog->update(); if (updateSkill != 0) skillDialog->playUpdateEffect(updateSkill); } }
void SkillRecv::processSkillUpdate2(Net::MessageIn &msg) { int updateSkill = 0; msg.readInt16("len"); // for now unused const int skillId = msg.readInt16("skill id"); const SkillType::SkillType inf = static_cast<SkillType::SkillType>( msg.readInt32("inf")); msg.readInt32("inf2"); const int level = msg.readInt16("skill level"); const int sp = msg.readInt16("sp"); const int range = msg.readInt16("range"); const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable); const int oldLevel = PlayerInfo::getSkillLevel(skillId); if (oldLevel && oldLevel != level) updateSkill = skillId; PlayerInfo::setSkillLevel(skillId, level); if (skillDialog) { if (!skillDialog->updateSkill(skillId, range, up, inf, sp)) { skillDialog->addSkill(SkillOwner::Player, skillId, "", level, range, up, inf, sp); } skillDialog->update(); if (updateSkill) skillDialog->playUpdateEffect(updateSkill); } }
void BuySellHandler::processNpcBuyResponse(Net::MessageIn &msg) { const uint8_t response = msg.readUInt8("response"); if (response == 0U) { NotifyManager::notify(NotifyTypes::BUY_DONE); return; } // Reset player money since buy dialog already assumed purchase // would go fine if (mBuyDialog) mBuyDialog->setMoney(PlayerInfo::getAttribute(Attributes::MONEY)); switch (response) { case 1: NotifyManager::notify(NotifyTypes::BUY_FAILED_NO_MONEY); break; case 2: NotifyManager::notify(NotifyTypes::BUY_FAILED_OVERWEIGHT); break; case 3: NotifyManager::notify(NotifyTypes::BUY_FAILED_TOO_MANY_ITEMS); break; default: NotifyManager::notify(NotifyTypes::BUY_FAILED); break; }; }
void ItemRecv::processItemVisible(Net::MessageIn &msg) { const BeingId id = msg.readBeingId("item object id"); const int itemId = msg.readInt16("item id"); const Identified identified = fromInt( msg.readUInt8("identify"), Identified); const int x = msg.readInt16("x"); const int y = msg.readInt16("y"); const int amount = msg.readInt16("amount"); const int subX = static_cast<int>(msg.readInt8("sub x")); const int subY = static_cast<int>(msg.readInt8("sub y")); if (actorManager) { actorManager->createItem(id, itemId, x, y, 0, amount, 0, ItemColor_one, identified, Damaged_false, subX, subY, nullptr); } }
void TradeRecv::processTradeResponse(Net::MessageIn &msg) { const uint8_t type = msg.readUInt8("type"); msg.readInt32("char id"); msg.readInt16("base level"); Ea::TradeRecv::processTradeResponseContinue(type); }
void VendingHandler::processBuyAck(Net::MessageIn &msg) { UNIMPLIMENTEDPACKET; msg.readInt16("inv index"); msg.readInt16("amount"); msg.readUInt8("flag"); }
void BuyingStoreRecv::processBuyingStoreItemsList(Net::MessageIn &msg) { const int count = (msg.readInt16("len") - 16) / 9; const BeingId id = msg.readBeingId("account id"); const int storeId = msg.readInt32("store id"); // +++ in future need use it too msg.readInt32("money limit"); const Being *const dstBeing = actorManager->findBeing(id); if (!dstBeing) return; SellDialog *const dialog = CREATEWIDGETR(BuyingStoreSellDialog, dstBeing->getId(), storeId); dialog->setMoney(PlayerInfo::getAttribute(Attributes::MONEY)); const Inventory *const inv = PlayerInfo::getInventory(); for (int f = 0; f < count; f ++) { const int price = msg.readInt32("price"); const int amount = msg.readInt16("amount"); const ItemTypeT itemType = static_cast<ItemTypeT>( msg.readUInt8("item type")); const int itemId = msg.readInt16("item id"); if (!inv) continue; const Item *const item = inv->findItem(itemId, ItemColor_one); if (!item) continue; // +++ need add colors support dialog->addItem(itemId, itemType, ItemColor_one, amount, price); } }
void LoginHandler::procecessCharPasswordResponse(Net::MessageIn &msg) const { // 0: acc not found, 1: success, 2: password mismatch, 3: pass too short const uint8_t errMsg = msg.readUInt8(); // Successful pass change if (errMsg == 1) { client->setState(STATE_CHANGEPASSWORD_SUCCESS); } // pass change failed else { switch (errMsg) { case 0: errorMessage = // TRANSLATORS: error message _("Account was not found. Please re-login."); break; case 2: // TRANSLATORS: error message errorMessage = _("Old password incorrect."); break; case 3: // TRANSLATORS: error message errorMessage = _("New password too short."); break; default: // TRANSLATORS: error message errorMessage = _("Unknown error."); break; } client->setState(STATE_ACCOUNTCHANGE_ERROR); } }
void GuildRecv::processGuildSkillInfo(Net::MessageIn &msg) { const int count = (msg.readInt16("len") - 6) / 37; msg.readInt16("skill points"); if (skillDialog != nullptr) skillDialog->hideSkills(SkillOwner::Guild); for (int i = 0; i < count; i++) { const int skillId = msg.readInt16("skill id"); const SkillType::SkillType inf = static_cast<SkillType::SkillType>( msg.readInt32("inf")); const int level = msg.readInt16("skill level"); const int sp = msg.readInt16("sp"); const int range = msg.readInt16("range"); const std::string name = msg.readString(24, "skill name"); const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable); PlayerInfo::setSkillLevel(skillId, level); if (skillDialog != nullptr) { if (!skillDialog->updateSkill(skillId, range, up, inf, sp)) { skillDialog->addSkill(SkillOwner::Guild, skillId, name, level, range, up, inf, sp); } } } if (skillDialog != nullptr) skillDialog->updateModels(); }
void GuildRecv::processGuildInviteAck(Net::MessageIn &msg) { const uint8_t flag = msg.readUInt8("flag"); if (guildTab == nullptr) return; switch (flag) { case 0: NotifyManager::notify(NotifyTypes::GUILD_INVITE_FAILED); break; case 1: NotifyManager::notify(NotifyTypes::GUILD_INVITE_REJECTED); break; case 2: NotifyManager::notify(NotifyTypes::GUILD_INVITE_JOINED); break; case 3: NotifyManager::notify(NotifyTypes::GUILD_INVITE_FULL); break; default: NotifyManager::notify(NotifyTypes::GUILD_INVITE_ERROR); break; } }
void TradeHandler::processTradeItemAddResponse(Net::MessageIn &msg) { // Trade: New Item add response (was 0x00ea, now 01b1) const int index = msg.readInt16("index") - INVENTORY_OFFSET; Item *item = nullptr; if (PlayerInfo::getInventory()) item = PlayerInfo::getInventory()->getItem(index); if (!item) { if (tradeWindow) tradeWindow->receivedOk(true); return; } const int quantity = msg.readInt16("amount"); const uint8_t res = msg.readUInt8("status"); switch (res) { case 0: // Successfully added item if (tradeWindow) { tradeWindow->addItem2(item->getId(), item->getType(), item->getCards(), 4, true, quantity, item->getRefine(), item->getColor(), item->getIdentified(), item->getDamaged(), item->getFavorite(), item->isEquipment()); } item->increaseQuantity(-quantity); break; case 1: // Add item failed - player overweighted NotifyManager::notify(NotifyTypes:: TRADE_ADD_PARTNER_OVER_WEIGHT); break; case 2: // Add item failed - player has no free slot NotifyManager::notify(NotifyTypes::TRADE_ADD_PARTNER_NO_SLOTS); break; case 3: // Add item failed - non tradable item NotifyManager::notify(NotifyTypes::TRADE_ADD_UNTRADABLE_ITEM); break; default: NotifyManager::notify(NotifyTypes::TRADE_ADD_ERROR); UNIMPLIMENTEDPACKET; logger->log("QQQ SMSG_TRADE_ITEM_ADD_RESPONSE: " + toString(res)); break; } }
void NpcRecv::processNpcCutin(Net::MessageIn &msg) { Ea::NpcRecv::mRequestLang = false; const std::string image = msg.readString(64, "image name"); const CutInT cutin = static_cast<CutInT>(msg.readUInt8("type")); if (cutInWindow) cutInWindow->show(image, cutin); }