bool IOLoginData::savePlayer(Player* player, bool preSave/* = true*/)
{
if(preSave && player->health <= 0)
{
player->health = player->healthMax;
player->mana = player->manaMax;
}
Database* db = Database::getInstance();
DBResult* result;
DBQuery query;
query << "SELECT `save` FROM `players` WHERE `id` = " << player->getGUID();
if(!(result = db->storeQuery(query.str())))
return false;
const bool save = result->getDataInt("save");
result->free();
DBTransaction trans(db);
if(!trans.begin())
return false;
query.str("");
query << "UPDATE `players` SET `lastlogin` = " << player->lastLoginSaved << ", `lastip` = " << player->lastIP;
if(!player->isSaving())
{
query << " WHERE `id` = " << player->getGUID();
if(!db->executeQuery(query.str()))
return false;
return trans.commit();
}
query << ", ";
if(save)
query << "`level` = " << std::max((uint32_t)1, player->getLevel()) << ", ";
query << "`group_id` = " << player->groupId << ", ";
query << "`health` = " << player->health << ", ";
if(save)
{
query << "`healthmax` = " << player->healthMax << ", ";
query << "`experience` = " << std::max((uint64_t)0, player->getExperience()) << ", ";
}
query << "`lookbody` = " << (uint32_t)player->defaultOutfit.lookBody << ", ";
query << "`lookfeet` = " << (uint32_t)player->defaultOutfit.lookFeet << ", ";
query << "`lookhead` = " << (uint32_t)player->defaultOutfit.lookHead << ", ";
query << "`looklegs` = " << (uint32_t)player->defaultOutfit.lookLegs << ", ";
query << "`looktype` = " << (uint32_t)player->defaultOutfit.lookType << ", ";
query << "`lookaddons` = " << (uint32_t)player->defaultOutfit.lookAddons << ", ";
if(save)
query << "`maglevel` = " << player->magLevel << ", ";
query << "`mana` = " << player->mana << ", ";
if(save)
{
query << "`manamax` = " << player->manaMax << ", ";
query << "`manaspent` = " << player->manaSpent << ", ";
}
query << "`soul` = " << player->soul << ", ";
query << "`town_id` = " << player->town << ", ";
query << "`posx` = " << player->getLoginPosition().x << ", ";
query << "`posy` = " << player->getLoginPosition().y << ", ";
query << "`posz` = " << player->getLoginPosition().z << ", ";
if(save)
query << "`cap` = " << player->getCapacity() << ", ";
query << "`sex` = " << player->sex << ", ";
query << "`balance` = " << player->balance << ", ";
query << "`stamina` = " << player->getStamina() << ", ";
query << "`promotion` = " << player->promotionLevel << ", ";
if(g_config.getBool(ConfigManager::STORE_DIRECTION))
query << "`direction` = " << (uint32_t)player->getDirection() << ", ";
if(!player->isVirtual())
{
std::string name = player->getName(), nameDescription = player->getNameDescription();
if(!player->isAccountManager() && nameDescription.length() > name.length())
query << "`description` = " << db->escapeString(nameDescription.substr(name.length())) << ", ";
}
//serialize conditions
PropWriteStream propWriteStream;
for(ConditionList::const_iterator it = player->conditions.begin(); it != player->conditions.end(); ++it)
{
if((*it)->isPersistent() || (*it)->getType() == CONDITION_GAMEMASTER)
{
if(!(*it)->serialize(propWriteStream))
return false;
propWriteStream.ADD_UCHAR(CONDITIONATTR_END);
}
}
uint32_t conditionsSize = 0;
const char* conditions = propWriteStream.getStream(conditionsSize);
query << "`conditions` = " << db->escapeBlob(conditions, conditionsSize) << ", ";
query << "`loss_experience` = " << (uint32_t)player->getLossPercent(LOSS_EXPERIENCE) << ", ";
query << "`loss_mana` = " << (uint32_t)player->getLossPercent(LOSS_MANA) << ", ";
query << "`loss_skills` = " << (uint32_t)player->getLossPercent(LOSS_SKILLS) << ", ";
query << "`loss_containers` = " << (uint32_t)player->getLossPercent(LOSS_CONTAINERS) << ", ";
query << "`loss_items` = " << (uint32_t)player->getLossPercent(LOSS_ITEMS) << ", ";
if(g_game.getWorldType() != WORLD_TYPE_PVP_ENFORCED)
{
int32_t redSkullTime = 0;
if(player->redSkullTicks > 0)
redSkullTime = (time(NULL) + (player->redSkullTicks / 1000));
query << "`redskulltime` = " << redSkullTime << ", ";
query << "`redskull` = " << (player->skull == SKULL_RED ? 1 : 0) << ", ";
}
query << "`lastlogout` = " << player->getLastLogout() << ", ";
if(player->isPremium() || !g_config.getBool(ConfigManager::BLESSING_ONLY_PREMIUM))
query << "`blessings` = " << player->blessings << ", ";
query << "`marriage` = " << player->marriage << ", ";
if(g_config.getBool(ConfigManager::INGAME_GUILD_MANAGEMENT))
{
query << "`guildnick` = " << db->escapeString(player->guildNick) << ", ";
query << "`rank_id` = " << IOGuild::getInstance()->getRankIdByGuildIdAndLevel(player->getGuildId(), player->getGuildLevel()) << ", ";
}
Vocation* tmpVoc = player->vocation;
for(uint32_t i = 0; i <= player->promotionLevel; i++)
tmpVoc = Vocations::getInstance()->getVocation(tmpVoc->getFromVocation());
query << "`vocation` = " << tmpVoc->getId() << " WHERE `id` = " << player->getGUID();
if(!db->executeQuery(query.str()))
return false;
// skills
if(save)
for(int32_t i = 0; i <= 6; i++)
{
query.str("");
query << "UPDATE `player_skills` SET `value` = " << player->skills[i][SKILL_LEVEL] << ", `count` = " << player->skills[i][SKILL_TRIES] << " WHERE `player_id` = " << player->getGUID() << " AND `skillid` = " << i;
if(!db->executeQuery(query.str()))
return false;
}
// learned spells
query.str("");
query << "DELETE FROM `player_spells` WHERE `player_id` = " << player->getGUID();
if(!db->executeQuery(query.str()))
return false;
char buffer[280];
DBInsert query_insert(db);
query_insert.setQuery("INSERT INTO `player_spells` (`player_id`, `name`) VALUES ");
for(LearnedInstantSpellList::const_iterator it = player->learnedInstantSpellList.begin(); it != player->learnedInstantSpellList.end(); ++it)
{
sprintf(buffer, "%d, %s", player->getGUID(), db->escapeString(*it).c_str());
if(!query_insert.addRow(buffer))
return false;
}
if(!query_insert.execute())
return false;
//item saving
query.str("");
query << "DELETE FROM `player_items` WHERE `player_id` = " << player->getGUID();
if(!db->executeQuery(query.str()))
return false;
ItemBlockList itemList;
if(save)
{
for(int32_t slotId = 1; slotId < 11; ++slotId)
{
if(Item* item = player->inventory[slotId])
itemList.push_back(itemBlock(slotId, item));
}
query_insert.setQuery("INSERT INTO `player_items` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES ");
if(!saveItems(player, itemList, query_insert))
return false;
itemList.clear();
}
//save depot items
//std::stringstream ss;
for(DepotMap::iterator it = player->depots.begin(); it != player->depots.end(); ++it)
{
/*if(it->second.second)
{
it->second.second = false;
ss << it->first << ",";*/
itemList.push_back(itemBlock(it->first, it->second.first));
//}
}
/*std::string s = ss.str();
size_t size = s.length();
if(size > 0)
{*/
query.str("");
query << "DELETE FROM `player_depotitems` WHERE `player_id` = " << player->getGUID();// << " AND `pid` IN (" << s.substr(0, --size) << ")";
if(!db->executeQuery(query.str()))
return false;
query_insert.setQuery("INSERT INTO `player_depotitems` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES ");
if(!saveItems(player, itemList, query_insert))
return false;
itemList.clear();
//}
query.str("");
query << "DELETE FROM `player_storage` WHERE `player_id` = " << player->getGUID();
if(!db->executeQuery(query.str()))
return false;
player->genReservedStorageRange();
query_insert.setQuery("INSERT INTO `player_storage` (`player_id`, `key`, `value`) VALUES ");
for(StorageMap::const_iterator cit = player->getStorageIteratorBegin(); cit != player->getStorageIteratorEnd(); ++cit)
{
sprintf(buffer, "%u, %u, %s", player->getGUID(), cit->first, db->escapeString(cit->second).c_str());
if(!query_insert.addRow(buffer))
return false;
}
if(!query_insert.execute())
return false;
if(g_config.getBool(ConfigManager::INGAME_GUILD_MANAGEMENT))
{
//save guild invites
query.str("");
query << "DELETE FROM `guild_invites` WHERE player_id = " << player->getGUID();
if(!db->executeQuery(query.str()))
return false;
query_insert.setQuery("INSERT INTO `guild_invites` (`player_id`, `guild_id`) VALUES ");
for(InvitedToGuildsList::const_iterator it = player->invitedToGuildsList.begin(); it != player->invitedToGuildsList.end(); ++it)
{
sprintf(buffer, "%d, %d", player->getGUID(), *it);
if(!query_insert.addRow(buffer))
return false;
}
if(!query_insert.execute())
return false;
}
//save vip list
query.str("");
query << "DELETE FROM `player_viplist` WHERE `player_id` = " << player->getGUID() << ";";
if(!db->executeQuery(query.str()))
return false;
query_insert.setQuery("INSERT INTO `player_viplist` (`player_id`, `vip_id`) VALUES ");
for(VIPListSet::iterator it = player->VIPList.begin(); it != player->VIPList.end(); it++)
{
if(playerExists(*it, false, false))
{
sprintf(buffer, "%d, %d", player->getGUID(), *it);
if(!query_insert.addRow(buffer))
return false;
}
}
if(!query_insert.execute())
return false;
//End the transaction
return trans.commit();
}