bool IOMapSerialize::loadHouseInfo() { Database& db = Database::getInstance(); DBResult_ptr result = db.storeQuery("SELECT `id`, `owner`, `paid`, `warnings` FROM `houses`"); if (!result) { return false; } do { House* house = g_game.map.houses.getHouse(result->getNumber<uint32_t>("id")); if (house) { house->setOwner(result->getNumber<uint32_t>("owner"), false); house->setPaidUntil(result->getNumber<time_t>("paid")); house->setPayRentWarnings(result->getNumber<uint32_t>("warnings")); } } while (result->next()); result = db.storeQuery("SELECT `house_id`, `listid`, `list` FROM `house_lists`"); if (result) { do { House* house = g_game.map.houses.getHouse(result->getNumber<uint32_t>("house_id")); if (house) { house->setAccessList(result->getNumber<uint32_t>("listid"), result->getString("list")); } } while (result->next()); } return true; }
HistoryMarketOfferList IOMarket::getOwnHistory(MarketAction_t action, uint32_t playerId) { HistoryMarketOfferList offerList; std::ostringstream query; query << "SELECT `itemtype`, `amount`, `price`, `expires_at`, `state` FROM `market_history` WHERE `player_id` = " << playerId << " AND `sale` = " << action; DBResult_ptr result = Database::getInstance().storeQuery(query.str()); if (!result) { return offerList; } do { HistoryMarketOffer offer; offer.itemId = result->getNumber<uint16_t>("itemtype"); offer.amount = result->getNumber<uint16_t>("amount"); offer.price = result->getNumber<uint32_t>("price"); offer.timestamp = result->getNumber<uint32_t>("expires_at"); MarketOfferState_t offerState = static_cast<MarketOfferState_t>(result->getNumber<uint16_t>("state")); if (offerState == OFFERSTATE_ACCEPTEDEX) { offerState = OFFERSTATE_ACCEPTED; } offer.state = offerState; offerList.push_back(offer); } while (result->next()); return offerList; }
MarketOfferList IOMarket::getOwnOffers(MarketAction_t action, uint32_t playerId) { MarketOfferList offerList; const int32_t marketOfferDuration = g_config.getNumber(ConfigManager::MARKET_OFFER_DURATION); std::ostringstream query; query << "SELECT `id`, `amount`, `price`, `created`, `itemtype` FROM `market_offers` WHERE `player_id` = " << playerId << " AND `sale` = " << action; DBResult_ptr result = Database::getInstance().storeQuery(query.str()); if (!result) { return offerList; } do { MarketOffer offer; offer.amount = result->getNumber<uint16_t>("amount"); offer.price = result->getNumber<uint32_t>("price"); offer.timestamp = result->getNumber<uint32_t>("created") + marketOfferDuration; offer.counter = result->getNumber<uint32_t>("id") & 0xFFFF; offer.itemId = result->getNumber<uint16_t>("itemtype"); offerList.push_back(offer); } while (result->next()); return offerList; }
MarketOfferList IOMarket::getActiveOffers(MarketAction_t action, uint16_t itemId) { MarketOfferList offerList; std::ostringstream query; query << "SELECT `id`, `amount`, `price`, `created`, `anonymous`, (SELECT `name` FROM `players` WHERE `id` = `player_id`) AS `player_name` FROM `market_offers` WHERE `sale` = " << action << " AND `itemtype` = " << itemId; DBResult_ptr result = Database::getInstance().storeQuery(query.str()); if (!result) { return offerList; } const int32_t marketOfferDuration = g_config.getNumber(ConfigManager::MARKET_OFFER_DURATION); do { MarketOffer offer; offer.amount = result->getNumber<uint16_t>("amount"); offer.price = result->getNumber<uint32_t>("price"); offer.timestamp = result->getNumber<uint32_t>("created") + marketOfferDuration; offer.counter = result->getNumber<uint32_t>("id") & 0xFFFF; if (result->getNumber<uint16_t>("anonymous") == 0) { offer.playerName = result->getString("player_name"); } else { offer.playerName = "Anonymous"; } offerList.push_back(offer); } while (result->next()); return offerList; }
DBResult_ptr Database::verifyResult(DBResult_ptr result) { if (!result->next()) { return nullptr; } return result; }
void IOLoginData::loadItems(ItemMap& itemMap, DBResult_ptr result) { do { int32_t sid = result->getDataInt("sid"); int32_t pid = result->getDataInt("pid"); int32_t type = result->getDataInt("itemtype"); int32_t count = result->getDataInt("count"); unsigned long attrSize; const char* attr = result->getDataStream("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*, int32_t> pair(item, pid); itemMap[sid] = pair; } } while (result->next()); }
bool IOLoginData::loginserverAuthentication(const std::string& name, const std::string& password, Account& account) { Database* db = Database::getInstance(); std::ostringstream query; query << "SELECT `id`, `name`, `password`, `type`, `premdays`, `lastday` FROM `accounts` WHERE `name` = " << db->escapeString(name); DBResult_ptr result = db->storeQuery(query.str()); if (!result) { return false; } if (transformToSHA1(password) != result->getDataString("password")) { return false; } account.id = result->getDataInt("id"); account.name = result->getDataString("name"); account.accountType = static_cast<AccountType_t>(result->getDataInt("type")); account.premiumDays = result->getDataInt("premdays"); account.lastDay = result->getDataInt("lastday"); query.str(""); query << "SELECT `name`, `deletion` FROM `players` WHERE `account_id` = " << account.id; result = db->storeQuery(query.str()); if (result) { do { if (result->getDataInt("deletion") == 0) { account.charList.push_back(result->getDataString("name")); } } while (result->next()); account.charList.sort(); } return true; }
int LuaBinder::luaResultNext(lua_State* L) { DBResult_ptr res = LuaBinder::getDBResult(L); if (!res) { pushBoolean(L, false); return 1; } pushBoolean(L, res->next()); return 1; }
void Store::getTransactionHistory(uint32_t accountId, uint16_t page, uint32_t entriesPerPage, std::vector<StoreTransaction>& out) const { Database* db = Database::getInstance(); std::ostringstream query; query << "SELECT `id`, `coins`, `description`, `timestamp` FROM `store_history` WHERE `account_id` = " << accountId << " ORDER BY `timestamp` DESC LIMIT " << entriesPerPage + 1 << " OFFSET " << (page * entriesPerPage); DBResult_ptr result = db->storeQuery(query.str()); if (result) { do { out.emplace_back(result->getNumber<uint32_t>("id"), result->getNumber<int32_t>("coins"), result->getString("description"), result->getNumber<time_t>("timestamp")); } while (result->next()); } }
void IOGuild::getWarList(uint32_t guildId, GuildWarList& guildWarList) { std::ostringstream query; query << "SELECT `guild1`, `guild2` FROM `guild_wars` WHERE (`guild1` = " << guildId << " OR `guild2` = " << guildId << ") AND `ended` = 0 AND `status` = 1"; DBResult_ptr result = Database::getInstance()->storeQuery(query.str()); if (!result) { return; } do { uint32_t guild1 = result->getDataInt("guild1"); if (guildId != guild1) { guildWarList.push_back(guild1); } else { guildWarList.push_back(result->getDataInt("guild2")); } } while (result->next()); }
std::forward_list<VIPEntry> IOLoginData::getVIPEntries(uint32_t accountId) { std::forward_list<VIPEntry> entries; std::ostringstream query; query << "SELECT `player_id`, (SELECT `name` FROM `players` WHERE `id` = `player_id`) AS `name`, `description`, `icon`, `notify` FROM `account_viplist` WHERE `account_id` = " << accountId; DBResult_ptr result = Database::getInstance()->storeQuery(query.str()); if (result) { do { entries.emplace_front( result->getDataInt("player_id"), result->getDataString("name"), result->getDataString("description"), result->getDataInt("icon"), result->getDataInt("notify") != 0 ); } while (result->next()); } return entries; }
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; }
void IOMarket::updateStatistics() { std::ostringstream query; query << "SELECT `sale` AS `sale`, `itemtype` AS `itemtype`, COUNT(`price`) AS `num`, MIN(`price`) AS `min`, MAX(`price`) AS `max`, SUM(`price`) AS `sum` FROM `market_history` WHERE `state` = " << OFFERSTATE_ACCEPTED << " GROUP BY `itemtype`, `sale`"; DBResult_ptr result = Database::getInstance().storeQuery(query.str()); if (!result) { return; } do { MarketStatistics* statistics; if (result->getNumber<uint16_t>("sale") == MARKETACTION_BUY) { statistics = &purchaseStatistics[result->getNumber<uint16_t>("itemtype")]; } else { statistics = &saleStatistics[result->getNumber<uint16_t>("itemtype")]; } statistics->numTransactions = result->getNumber<uint32_t>("num"); statistics->lowestPrice = result->getNumber<uint32_t>("min"); statistics->totalPrice = result->getNumber<uint64_t>("sum"); statistics->highestPrice = result->getNumber<uint32_t>("max"); } while (result->next()); }
bool IOLoginData::loginserverAuthentication(const std::string& name, const std::string& password, Account& account) { Database* db = Database::getInstance(); std::ostringstream query; query << "SELECT `id`, `name`, `password`, `type`, `premdays`, `lastday` FROM `accounts` WHERE `name` = " << db->escapeString(name); DBResult_ptr result = db->storeQuery(query.str()); if (!result) { return false; } if (transformToSHA1(password) != result->getString("password")) { return false; } account.id = result->getNumber<uint32_t>("id"); account.name = result->getString("name"); account.accountType = static_cast<AccountType_t>(result->getNumber<int32_t>("type")); account.premiumDays = result->getNumber<uint16_t>("premdays"); account.lastDay = result->getNumber<time_t>("lastday"); query.str(std::string()); query << "SELECT `name`, `deletion`, `world` FROM `players` WHERE `account_id` = " << account.id << " ORDER BY name ASC"; result = db->storeQuery(query.str()); if (result) { do { if (result->getNumber<uint64_t>("deletion") == 0) { Character character; character.name = result->getString("name"); character.worldid = result->getNumber<uint16_t>("world"); account.characters.push_back(character); } } while (result->next()); //std::sort(account.characters.begin(), account.characters.end()); } return true; }
void IOMarket::processExpiredOffers(DBResult_ptr result, bool) { if (!result) { return; } do { if (!IOMarket::moveOfferToHistory(result->getNumber<uint32_t>("id"), OFFERSTATE_EXPIRED)) { continue; } const uint32_t playerId = result->getNumber<uint32_t>("player_id"); const uint16_t amount = result->getNumber<uint16_t>("amount"); if (result->getNumber<uint16_t>("sale") == 1) { const ItemType& itemType = Item::items[result->getNumber<uint16_t>("itemtype")]; if (itemType.id == 0) { continue; } Player* player = g_game.getPlayerByGUID(playerId); if (!player) { player = new Player(nullptr); if (!IOLoginData::loadPlayerById(player, playerId)) { delete player; continue; } } if (itemType.stackable) { uint16_t tmpAmount = amount; while (tmpAmount > 0) { uint16_t stackCount = std::min<uint16_t>(100, tmpAmount); Item* item = Item::CreateItem(itemType.id, stackCount); if (g_game.internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { delete item; break; } tmpAmount -= stackCount; } } else { int32_t subType; if (itemType.charges != 0) { subType = itemType.charges; } else { subType = -1; } for (uint16_t i = 0; i < amount; ++i) { Item* item = Item::CreateItem(itemType.id, subType); if (g_game.internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { delete item; break; } } } if (player->isOffline()) { IOLoginData::savePlayer(player); delete player; } } else { uint64_t totalPrice = result->getNumber<uint64_t>("price") * amount; Player* player = g_game.getPlayerByGUID(playerId); if (player) { player->setBankBalance(player->getBankBalance() + totalPrice); } else { IOLoginData::increaseBankBalance(playerId, totalPrice); } } } while (result->next()); }
bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) { if (!result) { return false; } Database* db = Database::getInstance(); uint32_t accno = result->getDataInt("account_id"); Account acc = loadAccount(accno); player->setGUID(result->getDataInt("id")); player->name = result->getDataString("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.getGroup(result->getDataInt("group_id")); if (!group) { std::cout << "[Error - IOLoginData::loadPlayer] " << player->name << " has Group ID " << result->getDataInt("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->getDataInt("sex"))); player->level = std::max<uint32_t>(1, result->getDataInt("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->getDataInt("soul"); player->capacity = result->getDataInt("cap") * 100; player->blessings = result->getDataInt("blessings"); unsigned long conditionsSize; const char* conditions = result->getDataStream("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->getDataInt("vocation"))) { std::cout << "[Error - IOLoginData::loadPlayer] " << player->name << " has Vocation ID " << result->getDataInt("vocation") << " which doesn't exist." << std::endl; return false; } player->mana = result->getDataInt("mana"); player->manaMax = result->getDataInt("manamax"); player->magLevel = result->getDataInt("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->getDataInt("health"); player->healthMax = result->getDataInt("healthmax"); player->defaultOutfit.lookType = result->getDataInt("looktype"); player->defaultOutfit.lookHead = result->getDataInt("lookhead"); player->defaultOutfit.lookBody = result->getDataInt("lookbody"); player->defaultOutfit.lookLegs = result->getDataInt("looklegs"); player->defaultOutfit.lookFeet = result->getDataInt("lookfeet"); player->defaultOutfit.lookAddons = result->getDataInt("lookaddons"); player->currentOutfit = player->defaultOutfit; if (g_game.getWorldType() != WORLD_TYPE_PVP_ENFORCED) { const int32_t skullSeconds = result->getDataInt("skulltime") - time(nullptr); if (skullSeconds > 0) { //ensure that we round up the number of ticks player->skullTicks = (skullSeconds + 2) * 1000; int32_t skull = result->getDataInt("skull"); if (skull == SKULL_RED) { player->skull = SKULL_RED; } else if (skull == SKULL_BLACK) { player->skull = SKULL_BLACK; } } } player->loginPosition.x = result->getDataInt("posx"); player->loginPosition.y = result->getDataInt("posy"); player->loginPosition.z = result->getDataInt("posz"); player->lastLoginSaved = result->getNumber<uint64_t>("lastlogin"); player->lastLogout = result->getNumber<uint64_t>("lastlogout"); player->offlineTrainingTime = result->getDataInt("offlinetraining_time") * 1000; player->offlineTrainingSkill = result->getDataInt("offlinetraining_skill"); Town* town = Towns::getInstance().getTown(result->getDataInt("town_id")); if (!town) { std::cout << "[Error - IOLoginData::loadPlayer] " << player->name << " has Town ID " << result->getDataInt("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->getDataInt("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->getDataInt("guild_id"); uint32_t playerRankId = result->getDataInt("rank_id"); player->guildNick = result->getDataString("nick"); Guild* guild = g_game.getGuild(guildId); if (!guild) { query.str(""); query << "SELECT `name` FROM `guilds` WHERE `id` = " << guildId; if ((result = db->storeQuery(query.str()))) { guild = new Guild(guildId, result->getDataString("name")); g_game.addGuild(guild); query.str(""); query << "SELECT `id`, `name`, `level` FROM `guild_ranks` WHERE `guild_id` = " << guildId << " LIMIT 3"; if ((result = db->storeQuery(query.str()))) { do { guild->addRank(result->getDataInt("id"), result->getDataString("name"), result->getDataInt("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(""); query << "SELECT COUNT(*) AS `members` FROM `guild_membership` WHERE `guild_id` = " << guildId; if ((result = db->storeQuery(query.str()))) { guild->setMemberCount(result->getDataInt("members")); } } } query.str(""); 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->getDataString("name")); } while (result->next()); } //load inventory items ItemMap itemMap; query.str(""); 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::reverse_iterator it = itemMap.rbegin(); it != itemMap.rend(); ++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(""); 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::reverse_iterator it = itemMap.rbegin(); it != itemMap.rend(); ++it) { const std::pair<Item*, int32_t>& pair = it->second; Item* item = pair.first; int32_t pid = pair.second; if (pid >= 0 && pid < 100) { if (pid == 98) { DepotChest* depotChest = player->getPokeStorage(pid, true); if (depotChest) { depotChest->__internalAddThing(item); } } else { 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(""); 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::reverse_iterator it = itemMap.rbegin(); it != itemMap.rend(); ++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(""); query << "SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = " << player->getGUID(); if ((result = db->storeQuery(query.str()))) { do { player->addStorageValue(result->getDataInt("key"), result->getDataInt("value"), true); } while (result->next()); } //load vip query.str(""); query << "SELECT `player_id` FROM `account_viplist` WHERE `account_id` = " << player->getAccount(); if ((result = db->storeQuery(query.str()))) { do { player->addVIPInternal(result->getDataInt("player_id")); } while (result->next()); } player->updateBaseSpeed(); player->updateInventoryWeight(); player->updateItemsLight(true); return true; }