void IOLoginData::loadItems(ItemMap& itemMap, DBResult_ptr result) { do { uint32_t sid = result->getNumber<uint32_t>("sid"); uint32_t pid = result->getNumber<uint32_t>("pid"); uint16_t type = result->getNumber<uint16_t>("itemtype"); uint16_t count = result->getNumber<uint16_t>("count"); unsigned long attrSize; const char* attr = result->getStream("attributes", attrSize); PropStream propStream; propStream.init(attr, attrSize); Item* item = Item::CreateItem(type, count); if (item) { if (!item->unserializeAttr(propStream)) { std::cout << "WARNING: Serialize error in IOLoginData::loadItems" << std::endl; } std::pair<Item*, uint32_t> pair(item, pid); itemMap[sid] = pair; } } while (result->next()); }
int LuaBinder::luaResultGetStream(lua_State* L) { DBResult_ptr res = LuaBinder::getDBResult(L); if (!res) { pushBoolean(L, false); return 1; } unsigned long length; const char* stream = res->getStream(getString(L, 2), length); lua_pushlstring(L, stream, length); lua_pushnumber(L, length); return 2; }
void IOMapSerialize::loadHouseItems(Map* map) { int64_t start = OTSYS_TIME(); DBResult_ptr result = Database::getInstance().storeQuery("SELECT `data` FROM `tile_store`"); if (!result) { return; } do { unsigned long attrSize; const char* attr = result->getStream("data", attrSize); PropStream propStream; propStream.init(attr, attrSize); uint16_t x, y; uint8_t z; if (!propStream.read<uint16_t>(x) || !propStream.read<uint16_t>(y) || !propStream.read<uint8_t>(z)) { continue; } Tile* tile = map->getTile(x, y, z); if (!tile) { continue; } uint32_t item_count; if (!propStream.read<uint32_t>(item_count)) { continue; } while (item_count--) { loadItem(propStream, tile); } } while (result->next()); std::cout << "> Loaded house items in: " << (OTSYS_TIME() - start) / (1000.) << " s" << std::endl; }
bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) { if (!result) { return false; } Database* db = Database::getInstance(); uint32_t accno = result->getNumber<uint32_t>("account_id"); Account acc = loadAccount(accno); player->setGUID(result->getNumber<uint32_t>("id")); player->name = result->getString("name"); player->accountNumber = accno; player->accountType = acc.accountType; if (g_config.getBoolean(ConfigManager::FREE_PREMIUM)) { player->premiumDays = std::numeric_limits<uint16_t>::max(); } else { player->premiumDays = acc.premiumDays; } Group* group = g_game.groups.getGroup(result->getNumber<uint16_t>("group_id")); if (!group) { std::cout << "[Error - IOLoginData::loadPlayer] " << player->name << " has Group ID " << result->getNumber<uint16_t>("group_id") << " which doesn't exist" << std::endl; return false; } player->setGroup(group); player->bankBalance = result->getNumber<uint64_t>("balance"); player->setSex(static_cast<PlayerSex_t>(result->getNumber<uint16_t>("sex"))); player->level = std::max<uint32_t>(1, result->getNumber<uint32_t>("level")); uint64_t experience = result->getNumber<uint64_t>("experience"); uint64_t currExpCount = Player::getExpForLevel(player->level); uint64_t nextExpCount = Player::getExpForLevel(player->level + 1); if (experience < currExpCount || experience > nextExpCount) { experience = currExpCount; } player->experience = experience; if (currExpCount < nextExpCount) { player->levelPercent = Player::getPercentLevel(player->experience - currExpCount, nextExpCount - currExpCount); } else { player->levelPercent = 0; } player->soul = result->getNumber<uint16_t>("soul"); player->capacity = result->getNumber<uint32_t>("cap") * 100; player->blessings = result->getNumber<uint16_t>("blessings"); unsigned long conditionsSize; const char* conditions = result->getStream("conditions", conditionsSize); PropStream propStream; propStream.init(conditions, conditionsSize); Condition* condition = Condition::createCondition(propStream); while (condition) { if (condition->unserialize(propStream)) { player->storedConditionList.push_front(condition); } else { delete condition; } condition = Condition::createCondition(propStream); } if (!player->setVocation(result->getNumber<uint16_t>("vocation"))) { std::cout << "[Error - IOLoginData::loadPlayer] " << player->name << " has Vocation ID " << result->getNumber<uint16_t>("vocation") << " which doesn't exist" << std::endl; return false; } player->mana = result->getNumber<uint32_t>("mana"); player->manaMax = result->getNumber<uint32_t>("manamax"); player->magLevel = result->getNumber<uint32_t>("maglevel"); uint64_t nextManaCount = player->vocation->getReqMana(player->magLevel + 1); uint64_t manaSpent = result->getNumber<uint64_t>("manaspent"); if (manaSpent > nextManaCount) { manaSpent = 0; } player->manaSpent = manaSpent; player->magLevelPercent = Player::getPercentLevel(player->manaSpent, nextManaCount); player->health = result->getNumber<int32_t>("health"); player->healthMax = result->getNumber<int32_t>("healthmax"); player->defaultOutfit.lookType = result->getNumber<uint16_t>("looktype"); player->defaultOutfit.lookHead = result->getNumber<uint16_t>("lookhead"); player->defaultOutfit.lookBody = result->getNumber<uint16_t>("lookbody"); player->defaultOutfit.lookLegs = result->getNumber<uint16_t>("looklegs"); player->defaultOutfit.lookFeet = result->getNumber<uint16_t>("lookfeet"); player->defaultOutfit.lookAddons = result->getNumber<uint16_t>("lookaddons"); player->currentOutfit = player->defaultOutfit; if (g_game.getWorldType() != WORLD_TYPE_PVP_ENFORCED) { const time_t skullSeconds = result->getNumber<time_t>("skulltime") - time(nullptr); if (skullSeconds > 0) { //ensure that we round up the number of ticks player->skullTicks = (skullSeconds + 2) * 1000; uint16_t skull = result->getNumber<uint16_t>("skull"); if (skull == SKULL_RED) { player->skull = SKULL_RED; } else if (skull == SKULL_BLACK) { player->skull = SKULL_BLACK; } } } player->loginPosition.x = result->getNumber<uint16_t>("posx"); player->loginPosition.y = result->getNumber<uint16_t>("posy"); player->loginPosition.z = result->getNumber<uint16_t>("posz"); player->lastLoginSaved = result->getNumber<time_t>("lastlogin"); player->lastLogout = result->getNumber<time_t>("lastlogout"); player->offlineTrainingTime = result->getNumber<int32_t>("offlinetraining_time") * 1000; player->offlineTrainingSkill = result->getNumber<int32_t>("offlinetraining_skill"); Town* town = g_game.map.towns.getTown(result->getNumber<uint32_t>("town_id")); if (!town) { std::cout << "[Error - IOLoginData::loadPlayer] " << player->name << " has Town ID " << result->getNumber<uint32_t>("town_id") << " which doesn't exist" << std::endl; return false; } player->town = town; const Position& loginPos = player->loginPosition; if (loginPos.x == 0 && loginPos.y == 0 && loginPos.z == 0) { player->loginPosition = player->getTemplePosition(); } player->staminaMinutes = result->getNumber<uint16_t>("stamina"); static const std::string skillNames[] = {"skill_fist", "skill_club", "skill_sword", "skill_axe", "skill_dist", "skill_shielding", "skill_fishing"}; static const std::string skillNameTries[] = {"skill_fist_tries", "skill_club_tries", "skill_sword_tries", "skill_axe_tries", "skill_dist_tries", "skill_shielding_tries", "skill_fishing_tries"}; static const size_t size = sizeof(skillNames) / sizeof(std::string); for (uint8_t i = 0; i < size; ++i) { uint16_t skillLevel = result->getNumber<uint16_t>(skillNames[i]); uint64_t skillTries = result->getNumber<uint64_t>(skillNameTries[i]); uint64_t nextSkillTries = player->vocation->getReqSkillTries(i, skillLevel + 1); if (skillTries > nextSkillTries) { skillTries = 0; } player->skills[i].level = skillLevel; player->skills[i].tries = skillTries; player->skills[i].percent = Player::getPercentLevel(skillTries, nextSkillTries); } std::ostringstream query; query << "SELECT `guild_id`, `rank_id`, `nick` FROM `guild_membership` WHERE `player_id` = " << player->getGUID(); if ((result = db->storeQuery(query.str()))) { uint32_t guildId = result->getNumber<uint32_t>("guild_id"); uint32_t playerRankId = result->getNumber<uint32_t>("rank_id"); player->guildNick = result->getString("nick"); Guild* guild = g_game.getGuild(guildId); if (!guild) { query.str(std::string()); query << "SELECT `name` FROM `guilds` WHERE `id` = " << guildId; if ((result = db->storeQuery(query.str()))) { guild = new Guild(guildId, result->getString("name")); g_game.addGuild(guild); query.str(std::string()); query << "SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `guild_id` = " << guildId << " LIMIT 3"; if ((result = db->storeQuery(query.str()))) { do { guild->addRank(result->getNumber<uint32_t>("id"), result->getString("name"), result->getNumber<uint16_t>("level")); } while (result->next()); } } } if (guild) { player->guild = guild; GuildRank* rank = guild->getRankById(playerRankId); if (rank) { player->guildLevel = rank->level; } else { player->guildLevel = 1; } IOGuild::getWarList(guildId, player->guildWarList); query.str(std::string()); query << "SELECT COUNT(*) AS `members` FROM `guild_membership` WHERE `guild_id` = " << guildId; if ((result = db->storeQuery(query.str()))) { guild->setMemberCount(result->getNumber<uint32_t>("members")); } } } query.str(std::string()); query << "SELECT `player_id`, `name` FROM `player_spells` WHERE `player_id` = " << player->getGUID(); if ((result = db->storeQuery(query.str()))) { do { player->learnedInstantSpellList.emplace_front(result->getString("name")); } while (result->next()); } //load inventory items ItemMap itemMap; query.str(std::string()); query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; if ((result = db->storeQuery(query.str()))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { const std::pair<Item*, int32_t>& pair = it->second; Item* item = pair.first; int32_t pid = pair.second; if (pid >= 1 && pid <= 10) { player->internalAddThing(pid, item); } else { ItemMap::const_iterator it2 = itemMap.find(pid); if (it2 == itemMap.end()) { continue; } Container* container = it2->second.first->getContainer(); if (container) { container->internalAddThing(item); } } } } //load depot items itemMap.clear(); query.str(std::string()); query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; if ((result = db->storeQuery(query.str()))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { const std::pair<Item*, int32_t>& pair = it->second; Item* item = pair.first; int32_t pid = pair.second; if (pid >= 0 && pid < 100) { DepotChest* depotChest = player->getDepotChest(pid, true); if (depotChest) { depotChest->internalAddThing(item); } } else { ItemMap::const_iterator it2 = itemMap.find(pid); if (it2 == itemMap.end()) { continue; } Container* container = it2->second.first->getContainer(); if (container) { container->internalAddThing(item); } } } } //load inbox items itemMap.clear(); query.str(std::string()); query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_inboxitems` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; if ((result = db->storeQuery(query.str()))) { loadItems(itemMap, result); for (ItemMap::const_reverse_iterator it = itemMap.rbegin(), end = itemMap.rend(); it != end; ++it) { const std::pair<Item*, int32_t>& pair = it->second; Item* item = pair.first; int32_t pid = pair.second; if (pid >= 0 && pid < 100) { player->getInbox()->internalAddThing(item); } else { ItemMap::const_iterator it2 = itemMap.find(pid); if (it2 == itemMap.end()) { continue; } Container* container = it2->second.first->getContainer(); if (container) { container->internalAddThing(item); } } } } //load storage map query.str(std::string()); query << "SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = " << player->getGUID(); if ((result = db->storeQuery(query.str()))) { do { player->addStorageValue(result->getNumber<uint32_t>("key"), result->getNumber<int32_t>("value"), true); } while (result->next()); } //load vip query.str(std::string()); query << "SELECT `player_id` FROM `account_viplist` WHERE `account_id` = " << player->getAccount(); if ((result = db->storeQuery(query.str()))) { do { player->addVIPInternal(result->getNumber<uint32_t>("player_id")); } while (result->next()); } player->updateBaseSpeed(); player->updateInventoryWeight(); player->updateItemsLight(true); return true; }