void ChangeStatsHandler::handle(InPacket& recv) const { recv.read_bool(); // 'itemreaction' int32_t updatemask = recv.read_int(); Player& player = Stage::get().getplayer(); bool recalculate = false; for (auto it = Maplestat::it(); it.hasnext(); it.increment()) { Maplestat::Value stat = it.get(); if (Maplestat::compare(stat, updatemask)) { bool updatesingle = false; switch (stat) { case Maplestat::SKIN: player.changelook(stat, recv.read_short()); break; case Maplestat::FACE: case Maplestat::HAIR: player.changelook(stat, recv.read_int()); break; case Maplestat::LEVEL: player.changelevel(recv.read_byte()); updatesingle = true; break; case Maplestat::JOB: player.changejob(recv.read_short()); updatesingle = true; break; case Maplestat::EXP: player.getstats().set_exp(recv.read_int()); break; case Maplestat::MESO: player.getinvent().setmeso(recv.read_int()); break; default: player.getstats().set_stat(stat, recv.read_short()); recalculate = true; break; } if (updatesingle) { UI::get().with_element<UIStatsinfo>([&stat](auto& si) { si.updatestat(stat); }); } } } if (recalculate) { player.recalcstats(false); } UI::get().enable(); }
void SetfieldHandler::parse_questlog(InPacket& recv, Questlog& quests) const { int16_t size = recv.read_short(); for (int16_t i = 0; i < size; i++) { int16_t qid = recv.read_short(); std::string qdata = recv.read_string(); if (quests.is_started(qid)) { int16_t qidl = quests.get_last_started(); quests.add_in_progress(qidl, qid, qdata); i--; } else { quests.add_started(qid, qdata); } } std::map<int16_t, int64_t> completed; size = recv.read_short(); for (int16_t i = 0; i < size; i++) { int16_t qid = recv.read_short(); int64_t time = recv.read_long(); quests.add_completed(qid, time); } }
void SetfieldHandler::parseareainfo(InPacket& recv) const { std::map<int16_t, std::string> areainfo; int16_t arsize = recv.read_short(); for (int16_t i = 0; i < arsize; i++) { int16_t area = recv.read_short(); areainfo[area] = recv.read_string(); } }
void SetfieldHandler::parsemonsterbook(InPacket& recv, Monsterbook& monsterbook) const { monsterbook.setcover(recv.read_int()); recv.skip(1); int16_t size = recv.read_short(); for (int16_t i = 0; i < size; i++) { int16_t cid = recv.read_short(); int8_t mblv = recv.read_byte(); monsterbook.addcard(cid, mblv); } }
void SetfieldHandler::parsering3(InPacket& recv) const { int16_t rsize = recv.read_short(); for (int16_t i = 0; i < rsize; i++) { recv.read_int(); recv.read_int(); recv.read_int(); recv.read_short(); recv.read_int(); recv.read_int(); recv.read_padded_string(13); recv.read_padded_string(13); } }
void ServerIPHandler::handle(InPacket& recv) const { recv.skip(2); // Read the ipv4 adress in a string. std::string addrstr; for (int i = 0; i < 4; i++) { uint8_t num = static_cast<uint8_t>(recv.read_byte()); addrstr.append(std::to_string(num)); if (i < 3) { addrstr.push_back('.'); } } // Read the port adress in a string. std::string portstr = std::to_string(recv.read_short()); int32_t cid = recv.read_int(); // Attempt to reconnect to the server and if successfull, login to the game. Session::get().reconnect(addrstr.c_str(), portstr.c_str()); PlayerLoginPacket(cid).dispatch(); }
void SetfieldHandler::parsenewyear(InPacket& recv) const { int16_t nysize = recv.read_short(); for (int16_t i = 0; i < nysize; i++) { } }
void SetfieldHandler::parseminigame(InPacket& recv) const { int16_t mgsize = recv.read_short(); for (int16_t i = 0; i < mgsize; i++) { } }
void AddCooldownHandler::handle(InPacket& recv) const { int32_t skillid = recv.read_int(); int16_t time = recv.read_short(); int32_t seconds = Timer::get().seconds() + time; Stage::get().getplayer().getskills().set_cd(skillid, seconds); }
void SetfieldHandler::parse_inventory(InPacket& recv, Inventory& invent) const { invent.setmeso(recv.read_int()); invent.setslots(Inventory::EQUIP, recv.read_byte()); invent.setslots(Inventory::USE, recv.read_byte()); invent.setslots(Inventory::SETUP, recv.read_byte()); invent.setslots(Inventory::ETC, recv.read_byte()); invent.setslots(Inventory::CASH, recv.read_byte()); recv.skip(8); for (size_t i = 0; i < 3; i++) { Inventory::Type inv = (i == 0) ? Inventory::EQUIPPED : Inventory::EQUIP; int16_t pos = recv.read_short(); while (pos != 0) { int16_t slot = (i == 1) ? -pos : pos; ItemParser::parseitem(recv, inv, slot, invent); pos = recv.read_short(); } } recv.skip(2); Inventory::Type toparse[4] = { Inventory::USE, Inventory::SETUP, Inventory::ETC, Inventory::CASH }; for (size_t i = 0; i < 4; i++) { Inventory::Type inv = toparse[i]; int8_t pos = recv.read_byte(); while (pos != 0) { ItemParser::parseitem(recv, inv, pos, invent); pos = recv.read_byte(); } } }
void ApplyBuffHandler::handlebuff(InPacket& recv, Buff::Stat bs) const { int16_t value = recv.read_short(); int32_t skillid = recv.read_int(); int32_t duration = recv.read_int(); Stage::get().getplayer().givebuff({ bs, value, skillid, duration }); UI::get().with_element<UIBuffList>([&skillid, &duration](auto& bl) { bl.add_buff(skillid, duration); }); }
void SetfieldHandler::parse_skillbook(InPacket& recv, Skillbook& skills) const { int16_t size = recv.read_short(); for (int16_t i = 0; i < size; i++) { int32_t skillid = recv.read_int(); int32_t level = recv.read_int(); int64_t expiration = recv.read_long(); bool fourthtjob = ((skillid % 100000) / 10000 == 2); int32_t masterlevel = fourthtjob ? recv.read_int() : -1; skills.set_skill(skillid, level, masterlevel, expiration); } size = recv.read_short(); for (int16_t i = 0; i < size; i++) { int32_t skillid = recv.read_int(); int32_t cooldown = recv.read_short(); skills.set_cd(skillid, cooldown); } }
StatsEntry LoginParser::parse_stats(InPacket& recv) { StatsEntry statsentry; statsentry.name = recv.read_padded_string(13); recv.read_bool(); //gender recv.read_byte(); //skin recv.read_int(); //face recv.read_int(); //hair for (size_t i = 0; i < 3; i++) { statsentry.petids.push_back(recv.read_long()); } statsentry.stats[Maplestat::LEVEL] = recv.read_byte(); statsentry.stats[Maplestat::JOB] = recv.read_short(); statsentry.stats[Maplestat::STR] = recv.read_short(); statsentry.stats[Maplestat::DEX] = recv.read_short(); statsentry.stats[Maplestat::INT] = recv.read_short(); statsentry.stats[Maplestat::LUK] = recv.read_short(); statsentry.stats[Maplestat::HP] = recv.read_short(); statsentry.stats[Maplestat::MAXHP] = recv.read_short(); statsentry.stats[Maplestat::MP] = recv.read_short(); statsentry.stats[Maplestat::MAXMP] = recv.read_short(); statsentry.stats[Maplestat::AP] = recv.read_short(); statsentry.stats[Maplestat::SP] = recv.read_short(); statsentry.exp = recv.read_int(); statsentry.stats[Maplestat::FAME] = recv.read_short(); recv.skip(4); //gachaexp statsentry.mapid = recv.read_int(); statsentry.portal = recv.read_byte(); recv.skip(4); //timestamp return statsentry; }
Account LoginParser::parse_account(InPacket & recv) { Account account; recv.skip(2); account.accid = recv.read_int(); account.female = recv.read_bool(); recv.read_bool(); //is admin account.gmlevel = recv.read_byte(); recv.skip(1); account.name = recv.read_string(); recv.skip(1); account.muted = recv.read_bool(); recv.read_long(); //muted until recv.read_long(); //creation date recv.skip(4); account.pin = recv.read_short(); return account; }
void ModifyInventoryHandler::handle(InPacket& recv) const { recv.read_bool(); // 'updatetick' Inventory& inventory = Stage::get().getplayer().getinvent(); struct Mod { int8_t mode; Inventory::Type type; int16_t pos; int16_t arg; }; std::vector<Mod> mods; int8_t size = recv.read_byte(); for (int8_t i = 0; i < size; i++) { Mod mod; mod.mode = recv.read_byte(); mod.type = Inventory::typebyvalue(recv.read_byte()); mod.pos = recv.read_short(); mod.arg = 0; switch (mod.mode) { case 0: ItemParser::parseitem(recv, mod.type, mod.pos, inventory); break; case 1: mod.arg = recv.read_short(); if (inventory.changecount(mod.type, mod.pos, mod.arg)) mod.mode = 4; break; case 2: mod.arg = recv.read_short(); break; case 3: inventory.modify(mod.type, mod.pos, mod.mode, mod.arg, Inventory::MOVE_INTERNAL); break; } mods.push_back(mod); } Inventory::Movement move = (recv.length() > 0) ? Inventory::movementbyvalue(recv.read_byte()) : Inventory::MOVE_INTERNAL; for (Mod& mod : mods) { if (mod.mode == 2) { inventory.modify(mod.type, mod.pos, mod.mode, mod.arg, move); } UI::get().with_element<UIShop>([&mod](auto& s) { s.modify(mod.type); }); auto eqinvent = UI::get().get_element<UIEquipInventory>(); auto itinvent = UI::get().get_element<UIItemInventory>(); switch (move) { case Inventory::MOVE_INTERNAL: switch (mod.type) { case Inventory::EQUIPPED: if (eqinvent) eqinvent->modify(mod.pos, mod.mode, mod.arg); Stage::get().getplayer().changecloth(-mod.pos); Stage::get().getplayer().changecloth(-mod.arg); break; case Inventory::EQUIP: case Inventory::USE: case Inventory::SETUP: case Inventory::ETC: case Inventory::CASH: if (itinvent) itinvent->modify(mod.type, mod.pos, mod.mode, mod.arg); break; } break; case Inventory::MOVE_EQUIP: case Inventory::MOVE_UNEQUIP: if (mod.pos < 0) { if (eqinvent) eqinvent->modify(-mod.pos, 3, 0); if (itinvent) itinvent->modify(Inventory::EQUIP, mod.arg, 0, 0); Stage::get().getplayer().changecloth(-mod.pos); } else if (mod.arg < 0) { if (eqinvent) eqinvent->modify(-mod.arg, 0, 0); if (itinvent) itinvent->modify(Inventory::EQUIP, mod.pos, 3, 0); Stage::get().getplayer().changecloth(-mod.arg); } break; } } Stage::get().getplayer().recalcstats(true); UI::get().enable(); }