void SpawnPetHandler::handle(InPacket& recv) const { using Character::Char; Optional<Char> character = Stage::get().getcharacter(recv.readint()); if (!character) return; uint8_t petindex = recv.readbyte(); int8_t mode = recv.readbyte(); if (mode == 1) { recv.skip(1); int32_t itemid = recv.readint(); string name = recv.readascii(); int32_t uniqueid = recv.readint(); recv.skip(4); Point<int16_t> pos = recv.readpoint(); uint8_t stance = recv.readbyte(); int32_t fhid = recv.readint(); character->addpet(petindex, itemid, name, uniqueid, pos, stance, fhid); } else if (mode == 0) { bool hunger = recv.readbool(); character->removepet(petindex, hunger); } }
void SpawnMobHandler::handle(InPacket& recv) const { int32_t oid = recv.readint(); bool hascontrol = recv.readbyte() == 5; int32_t id = recv.readint(); recv.skip(22); Point<int16_t> position = recv.readpoint(); int8_t stance = recv.readbyte(); recv.skip(2); uint16_t fh = recv.readshort(); int8_t effect = recv.readbyte(); if (effect > 0) { recv.readbyte(); recv.readshort(); if (effect == 15) { recv.readbyte(); } } int8_t team = recv.readbyte(); recv.skip(4); Stage::get().getmobs().addmob(oid, id, hascontrol, stance, fh, effect == -2, team, position); }
void DropItemHandler::handle(InPacket& recv) const { int8_t mode = recv.readbyte(); int32_t oid = recv.readint(); bool meso = recv.readbool(); int32_t itemid = recv.readint(); int32_t owner = recv.readint(); int8_t pickuptype = recv.readbyte(); Point<int16_t> dropto = recv.readpoint(); recv.skip(4); Point<int16_t> dropfrom; if (mode != 2) { dropfrom = recv.readpoint(); recv.skip(2); } else { dropfrom = dropto; } if (!meso) { recv.skip(8); } bool playerdrop = !recv.readbool(); Stage::get().getdrops().adddrop(oid, itemid, meso, owner, dropfrom, dropto, pickuptype, mode, playerdrop); }
World LoginParser::parse_world(InPacket& recv) { int8_t wid = recv.read_byte(); if (wid == -1) return{ {}, {}, {}, 0, 0, wid }; std::string name = recv.read_string(); uint8_t flag = recv.read_byte(); std::string message = recv.read_string(); recv.skip(5); std::vector<int32_t> chloads; uint8_t channelcount = recv.read_byte(); for (uint8_t i = 0; i < channelcount; ++i) { recv.read_string(); // channel name chloads.push_back(recv.read_int()); recv.skip(1); recv.skip(2); } recv.skip(2); return{ name, message, chloads, channelcount, flag, wid }; }
void Login::parseworlds(InPacket& recv) { int8_t worldid = recv.readbyte(); if (worldid != -1) { World world; world.wid = worldid; world.name = recv.readascii(); world.flag = recv.readbyte(); world.message = recv.readascii(); recv.skip(5); world.channelcount = recv.readbyte(); for (uint8_t i = 0; i < world.channelcount; i++) { recv.readascii(); recv.skip(4); world.chloads.push_back(recv.readbyte()); recv.skip(2); } worlds.push_back(world); } }
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::set_field(InPacket& recv) const { recv.skip(23); int32_t cid = recv.read_int(); const CharEntry& playerentry = Session::get().getlogin().getcharbyid(cid); if (playerentry.cid != cid) { Console::get().print("Nonexisting cid: " + std::to_string(cid)); } Stage::get().loadplayer(playerentry); Session::get().getlogin().parsestats(recv); Player& player = Stage::get().getplayer(); recv.read_byte(); // 'buddycap' if (recv.read_bool()) { recv.read_string(); // 'linkedname' } parse_inventory(recv, player.getinvent()); parse_skillbook(recv, player.getskills()); parse_questlog(recv, player.getquests()); parseminigame(recv); parsering1(recv); parsering2(recv); parsering3(recv); parsetelerock(recv, player.gettrock()); parsemonsterbook(recv, player.getmonsterbook()); parsenewyear(recv); parseareainfo(recv); recv.skip(10); player.recalcstats(true); stagetransition(player.getstats().getportal(), player.getstats().getmapid()); Sound(Sound::GAMESTART).play(); UI::get().changestate(UI::GAME); }
void AttackHandler::handle(InPacket& recv) const { int32_t cid = recv.readint(); uint8_t count = recv.readbyte(); recv.skip(1); using Gameplay::AttackResult; AttackResult attack; attack.type = type; attack.level = recv.readbyte(); attack.skill = (attack.level > 0) ? recv.readint() : 0; attack.display = recv.readbyte(); attack.toleft = recv.readbool(); attack.stance = recv.readbyte(); attack.speed = recv.readbyte(); recv.skip(1); attack.bullet = recv.readint(); attack.mobcount = (count >> 4) & 0xF; attack.hitcount = count & 0xF; for (uint8_t i = 0; i < attack.mobcount; i++) { int32_t oid = recv.readint(); recv.skip(1); using Gameplay::Skill; uint8_t length = (attack.skill == Skill::MESO_EXPLOSION) ? recv.readbyte() : attack.hitcount; for (uint8_t j = 0; j < length; j++) { int32_t damage = recv.readint(); bool critical = false; // todo auto singledamage = std::make_pair(damage, critical); attack.damagelines[oid].push_back(singledamage); } } using Gameplay::Stage; Stage::get().showattack(cid, attack); }
void SetfieldHandler::change_map(InPacket& recv, int32_t) const { recv.skip(3); int32_t mapid = recv.read_int(); int8_t portalid = recv.read_byte(); stagetransition(portalid, mapid); }
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 UpdateskillsHandler::handle(InPacket& recv) const { recv.skip(3); int32_t skillid = recv.readint(); int32_t level = recv.readint(); int32_t masterlevel = recv.readint(); int64_t expire = recv.readlong(); Stage::get().getplayer().getskills().setskill(skillid, level, masterlevel, expire); }
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 KeymapHandler::handle(InPacket& recv) const { recv.skip(1); for (uint8_t i = 0; i < 90; i++) { uint8_t type = recv.readbyte(); int32_t action = recv.readint(); UI::get().addkeymapping(i, type, action); } }
StatsEntry Login::parsestats(InPacket& recv) const { StatsEntry statsentry; statsentry.name = recv.readpadascii(13); recv.readbool(); //gender recv.readbyte(); //skin recv.readint(); //face recv.readint(); //hair for (size_t i = 0; i < 3; i++) { statsentry.petids.push_back(recv.readlong()); } statsentry.stats[Maplestat::LEVEL] = recv.readbyte(); statsentry.stats[Maplestat::JOB] = recv.readshort(); statsentry.stats[Maplestat::STR] = recv.readshort(); statsentry.stats[Maplestat::DEX] = recv.readshort(); statsentry.stats[Maplestat::INT] = recv.readshort(); statsentry.stats[Maplestat::LUK] = recv.readshort(); statsentry.stats[Maplestat::HP] = recv.readshort(); statsentry.stats[Maplestat::MAXHP] = recv.readshort(); statsentry.stats[Maplestat::MP] = recv.readshort(); statsentry.stats[Maplestat::MAXMP] = recv.readshort(); statsentry.stats[Maplestat::AP] = recv.readshort(); statsentry.stats[Maplestat::SP] = recv.readshort(); statsentry.exp = recv.readint(); statsentry.stats[Maplestat::FAME] = recv.readshort(); recv.skip(4); //gachaexp statsentry.mapid = recv.readint(); statsentry.portal = recv.readbyte(); recv.skip(4); //timestamp statsentry.job = CharJob(statsentry.stats[Maplestat::JOB]); return statsentry; }
void SpawnMobControllerHandler::handle(InPacket& recv) const { int8_t aggro = recv.readbyte(); if (aggro == 0) return; int32_t oid = recv.readint(); recv.skip(1); int32_t id = recv.readint(); recv.skip(22); Point<int16_t> position = recv.readpoint(); int8_t stance = recv.readbyte(); recv.skip(2); uint16_t fh = recv.readshort(); int8_t effect = recv.readbyte(); if (effect > 0) { recv.readbyte(); recv.readshort(); if (effect == 15) { recv.readbyte(); } } int8_t team = recv.readbyte(); recv.skip(4); Stage::get().getmobs().addmob(oid, id, true, stance, fh, effect == -2, team, position); }
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; }
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 CharlistHandler::handle(InPacket& recv) const { recv.skip(1); // Parse all characters. Session::get().getlogin().parsecharlist(recv); // Remove the world selection screen. UI::get().remove(UIElement::WORLDSELECT); // Add the character selection screen. UI::get().add(ElementCharSelect()); UI::get().enable(); }
void MoveCharHandler::handle(InPacket& recv) const { int32_t cid = recv.readint(); recv.skip(4); vector<Movement> movements; uint8_t nummoves = recv.readbyte(); for (uint8_t i = 0; i < nummoves; i++) { movements.push_back(parsemovement(recv)); } Stage::get().getchars().movechar(cid, movements); }
void AddNewCharEntryHandler::handle(InPacket& recv) const { recv.skip(1); // Parse info on the new character. Session::get().getlogin().addcharentry(recv); // Remove the character creation ui. UI::get().remove(UIElement::CHARCREATION); // Readd the updated character selection. UI::get().add(ElementCharSelect()); UI::get().enable(); }
void AddNewCharEntryHandler::handle(InPacket& recv) const { recv.skip(1); // Parse info on the new character. CharEntry character = LoginParser::parse_charentry(recv); // Remove the character creation ui. UI::get().remove(UIElement::CHARCREATION); // Readd the updated character selection. if (auto charselect = UI::get().get_element<UICharSelect>()) { charselect->add_character(std::move(character)); charselect->makeactive(); } UI::get().enable(); }
Movement MovementHandler::parsemovement(InPacket& recv) const { Movement fragment; fragment.command = recv.readbyte(); switch (fragment.command) { case 0: case 5: case 17: fragment.type = Movement::_ABSOLUTE; fragment.xpos = recv.readshort(); fragment.ypos = recv.readshort(); fragment.lastx = recv.readshort(); fragment.lasty = recv.readshort(); recv.skip(2); fragment.newstate = recv.readbyte(); fragment.duration = recv.readshort(); break; case 1: case 2: case 6: case 12: case 13: case 16: fragment.type = Movement::_RELATIVE; fragment.xpos = recv.readshort(); fragment.ypos = recv.readshort(); fragment.newstate = recv.readbyte(); fragment.duration = recv.readshort(); break; case 11: fragment.type = Movement::CHAIR; fragment.xpos = recv.readshort(); fragment.ypos = recv.readshort(); recv.skip(2); fragment.newstate = recv.readbyte(); fragment.duration = recv.readshort(); break; case 15: fragment.type = Movement::JUMPDOWN; fragment.xpos = recv.readshort(); fragment.ypos = recv.readshort(); fragment.lastx = recv.readshort(); fragment.lasty = recv.readshort(); recv.skip(2); fragment.fh = recv.readshort(); fragment.newstate = recv.readbyte(); fragment.duration = recv.readshort(); break; case 3: case 4: case 7: case 8: case 9: case 14: fragment.type = Movement::NONE; break; case 10: fragment.type = Movement::NONE; //change equip break; } return fragment; }
void SpawnCharHandler::handle(InPacket& recv) const { int32_t cid = recv.readint(); uint8_t level = recv.readbyte(); string name = recv.readascii(); recv.readascii(); // guildname recv.readshort(); // guildlogobg recv.readbyte(); // guildlogobgcolor recv.readshort(); // guildlogo recv.readbyte(); // guildlogocolor recv.skip(8); bool morphed = recv.readint() == 2; int32_t buffmask1 = recv.readint(); int16_t buffvalue = 0; if (buffmask1 != 0) { buffvalue = morphed ? recv.readshort() : recv.readbyte(); } recv.readint(); // buffmask 2 recv.skip(43); recv.readint(); // 'mount' recv.skip(61); int16_t job = recv.readshort(); LookEntry look = Session::get().getlogin().parselook(recv); recv.readint(); //count of 5110000 recv.readint(); // 'itemeffect' recv.readint(); // 'chair' Point<int16_t> position = recv.readpoint(); int8_t stance = recv.readbyte(); recv.skip(3); for (size_t i = 0; i < 3; i++) { int8_t available = recv.readbyte(); if (available == 1) { recv.readbyte(); // 'byte2' recv.readint(); // petid recv.readascii(); // name recv.readint(); // unique id recv.readint(); recv.readpoint(); // pos recv.readbyte(); // stance recv.readint(); // fhid } else { break; } } recv.readint(); // mountlevel recv.readint(); // mountexp recv.readint(); // mounttiredness //shop stuff, TO DO recv.readbyte(); //shop stuff end bool chalkboard = recv.readbool(); string chalktext = chalkboard ? recv.readascii() : ""; recv.skip(3); recv.readbyte(); // team Stage::get().getchars().addchar(cid, look, level, job, name, stance, position); }