od kilku dni już się głownie nad tym, lecz moje próby kończą się niepowodzeniem. Problem polega na tym,że chciałbym aby postacie w ogólnie nie były zapisywane. tzn. bez zmian jak się zalogowała i się wyloguje wszystko wraca do stanu przed zalogowania.
Od razu mówię, że nie chcę ustawiać pliku tylko do odczytu, bo chcę aby wyjątkowo zapisywał się tylko i wyłącznie wygląd postaci.
Kod :
bool IOPlayerXML::savePlayer(Player* player)
{
std::string datadir = g_config.getString(ConfigManager::DATA_DIRECTORY);
std::string filename = datadir + "players/" + player->getName() + ".xml";
toLowerCaseString(filename); //store all player files in lowercase
std::stringstream sb;
xmlMutexLock(xmlmutex);
xmlNodePtr nn, sn, pn, root;
xmlDocPtr doc = xmlNewDoc((const xmlChar*)"1.0");
doc->children = xmlNewDocNode(doc, NULL, (const xmlChar*)"player", NULL);
root = doc->children;
player->preSave();
sb << player->getName();
xmlSetProp(root, (const xmlChar*)"name", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->accountNumber;
xmlSetProp(root, (const xmlChar*)"account", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->sex;
xmlSetProp(root, (const xmlChar*)"sex", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->getoldname;
xmlSetProp(root, (const xmlChar*)"oldname", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->gethero;
xmlSetProp(root, (const xmlChar*)"hero", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << (int)player->getDirection();
xmlSetProp(root, (const xmlChar*)"lookdir", (const xmlChar*)sb.str().c_str());
sb.str("");
char buf[128];
_i64toa(player->experience, buf, 10);
sb << buf;
xmlSetProp(root, (const xmlChar*)"exp", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << (int)player->getVocationId();
xmlSetProp(root, (const xmlChar*)"voc", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->level;
xmlSetProp(root, (const xmlChar*)"level", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->accessLevel;
xmlSetProp(root, (const xmlChar*)"access", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->getworldid;
xmlSetProp(root, (const xmlChar*)"world", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->getCapacity();
xmlSetProp(root, (const xmlChar*)"cap", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->magLevel;
xmlSetProp(root, (const xmlChar*)"maglevel", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->soul;
xmlSetProp(root, (const xmlChar*)"soul", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->maxDepotLimit;
xmlSetProp(root, (const xmlChar*)"maxdepotitems", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->lastlogin;
xmlSetProp(root, (const xmlChar*)"lastlogin", (const xmlChar*)sb.str().c_str());
pn = xmlNewNode(NULL,(const xmlChar*)"spawn");
sb.str("");
sb << player->getLoginPosition().x;
xmlSetProp(pn, (const xmlChar*)"x", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->getLoginPosition().y;
xmlSetProp(pn, (const xmlChar*)"y", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->getLoginPosition().z;
xmlSetProp(pn, (const xmlChar*)"z", (const xmlChar*)sb.str().c_str());
xmlAddChild(root, pn);
pn = xmlNewNode(NULL,(const xmlChar*)"temple");
sb.str("");
sb << player->masterPos.x;
xmlSetProp(pn, (const xmlChar*)"x", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->masterPos.y;
xmlSetProp(pn, (const xmlChar*)"y", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->masterPos.z;
xmlSetProp(pn, (const xmlChar*)"z", (const xmlChar*)sb.str().c_str());
xmlAddChild(root, pn);
pn = xmlNewNode(NULL,(const xmlChar*)"health");
sb.str("");
sb << player->health;
xmlSetProp(pn, (const xmlChar*)"now", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->healthMax;
xmlSetProp(pn, (const xmlChar*)"max", (const xmlChar*)sb.str().c_str());
sb.str("");
Condition* condition = player->getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT);
if(condition){
sb << condition->getTicks() / 1000;
}
else{
sb << 0;
}
xmlSetProp(pn, (const xmlChar*)"food", (const xmlChar*)sb.str().c_str());
xmlAddChild(root, pn);
pn = xmlNewNode(NULL,(const xmlChar*)"mana");
sb.str("");
sb << player->mana;
xmlSetProp(pn, (const xmlChar*)"now", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->manaMax;
xmlSetProp(pn, (const xmlChar*)"max", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->manaSpent;
xmlSetProp(pn, (const xmlChar*)"spent", (const xmlChar*)sb.str().c_str());
xmlAddChild(root, pn);
#ifdef __SKULLSYSTEM__
pn = xmlNewNode(NULL,(const xmlChar*)"skull");
long redSkullTime = 0;
if(player->redSkullTicks > 0){
redSkullTime = std::time(NULL) + player->redSkullTicks/1000;
}
sb.str("");
sb << redSkullTime;
xmlSetProp(pn, (const xmlChar*)"redskulltime", (const xmlChar*)sb.str().c_str());
long redSkull = 0;
if(player->skull == SKULL_RED){
redSkull = 1;
}
sb.str("");
sb << redSkull;
xmlSetProp(pn, (const xmlChar*)"redskull", (const xmlChar*)sb.str().c_str());
xmlAddChild(root, pn);
#endif
//upconversion of uchar(uint8_t) to get value not character into the stream
pn = xmlNewNode(NULL,(const xmlChar*)"look");
sb.str("");
sb << (int16_t)player->defaultOutfit.lookType;
xmlSetProp(pn, (const xmlChar*)"type", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << (int16_t)player->defaultOutfit.lookHead;
xmlSetProp(pn, (const xmlChar*)"head", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << (int16_t)player->defaultOutfit.lookBody;
xmlSetProp(pn, (const xmlChar*)"body", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << (int16_t)player->defaultOutfit.lookLegs;
xmlSetProp(pn, (const xmlChar*)"legs", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << (int16_t)player->defaultOutfit.lookFeet;
xmlSetProp(pn, (const xmlChar*)"feet", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << (int16_t)player->defaultOutfit.lookAddons;
xmlSetProp(pn, (const xmlChar*)"addons", (const xmlChar*)sb.str().c_str());
xmlAddChild(root, pn);
sn = xmlNewNode(NULL,(const xmlChar*)"skills");
for(int i = 0; i <= 6; i++){
pn = xmlNewNode(NULL,(const xmlChar*)"skill");
sb.str("");
sb << i;
xmlSetProp(pn, (const xmlChar*)"skillid", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->skills[i][SKILL_LEVEL];
xmlSetProp(pn, (const xmlChar*)"level", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << player->skills[i][SKILL_TRIES];
xmlSetProp(pn, (const xmlChar*)"tries", (const xmlChar*)sb.str().c_str());
xmlAddChild(sn, pn);
}
xmlAddChild(root, sn);
#ifdef __XID_SEPERATE_ADDONS__
sn = xmlNewNode(NULL,(const xmlChar*)"addons");
for(KnowAddonMap::const_iterator it = player->getKnowAddonBegin(); it != player->getKnowAddonEnd(); it++){
pn = xmlNewNode(NULL,(const xmlChar*)"addon");
sb.str("");
sb << it->first;
xmlSetProp(pn, (const xmlChar*) "outfit", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << it->second;
xmlSetProp(pn, (const xmlChar*) "type", (const xmlChar*)sb.str().c_str());
xmlAddChild(sn, pn);
}
xmlAddChild(root, sn);
#endif
#ifdef __JD_DEATH_LIST__
sn = xmlNewNode(NULL,(const xmlChar*)"deaths");
for (std::list<Death>::iterator it = player->deathList.begin(); it != player->deathList.end(); it++){
pn = xmlNewNode(NULL,(const xmlChar*)"death");
sb.str("");
sb << (*it).killer;
xmlSetProp(pn, (const xmlChar*) "name", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << (*it).level;
xmlSetProp(pn, (const xmlChar*) "level", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << long((*it).time);
xmlSetProp(pn, (const xmlChar*) "time", (const xmlChar*)sb.str().c_str());
xmlAddChild(sn, pn);
}
xmlAddChild(root, sn);
#endif
#ifdef __XID_LEARN_SPELLS__
sn = xmlNewNode(NULL,(const xmlChar*)"spells");
for(StringVector::iterator it = player->learnedSpells.begin(); it != player->learnedSpells.end(); ++it){
pn = xmlNewNode(NULL,(const xmlChar*)"spell");
sb.str("");
sb << *it;
xmlSetProp(pn, (const xmlChar*) "words", (const xmlChar*)sb.str().c_str());
xmlAddChild(sn, pn);
}
xmlAddChild(root, sn);
#endif
#ifdef __XID_BLESS_SYSTEM__
sn = xmlNewNode(NULL,(const xmlChar*)"blessings");
for(int i=0; i<6; i++){
if(player->getBlessing(i)){
pn = xmlNewNode(NULL,(const xmlChar*)"blessing");
sb.str("");
sb << i;
xmlSetProp(pn, (const xmlChar*) "id", (const xmlChar*)sb.str().c_str());
xmlAddChild(sn, pn);
}
}
xmlAddChild(root, sn);
#endif
sn = xmlNewNode(NULL,(const xmlChar*)"inventory");
for(int i = 1; i <= 10; i++){
if(player->inventory[i]){
pn = xmlNewNode(NULL,(const xmlChar*)"slot");
sb.str("");
sb << i;
xmlSetProp(pn, (const xmlChar*)"slotid", (const xmlChar*)sb.str().c_str());
nn = player->inventory[i]->serialize();
xmlAddChild(pn, nn);
xmlAddChild(sn, pn);
}
}
xmlAddChild(root, sn);
sn = xmlNewNode(NULL,(const xmlChar*)"depots");
for(DepotMap::reverse_iterator it = player->depots.rbegin(); it !=player->depots.rend() ;++it){
pn = xmlNewNode(NULL,(const xmlChar*)"depot");
sb.str("");
sb << it->first;
xmlSetProp(pn, (const xmlChar*)"depotid", (const xmlChar*)sb.str().c_str());
nn = (it->second)->serialize();
xmlAddChild(pn, nn);
xmlAddChild(sn, pn);
}
xmlAddChild(root, sn);
sn = xmlNewNode(NULL,(const xmlChar*)"storage");
player->genReservedStorageRange();
for(StorageMap::const_iterator cit = player->getStorageIteratorBegin(); cit != player->getStorageIteratorEnd();cit++){
pn = xmlNewNode(NULL,(const xmlChar*)"data");
sb.str("");
sb << cit->first;
xmlSetProp(pn, (const xmlChar*)"key", (const xmlChar*)sb.str().c_str());
sb.str("");
sb << cit->second;
xmlSetProp(pn, (const xmlChar*)"value", (const xmlChar*)sb.str().c_str());
xmlAddChild(sn, pn);
}
xmlAddChild(root, sn);
//Save the character
//if(xmlSaveFile(filename.c_str(), doc)){
bool result = xmlSaveFormatFileEnc(filename.c_str(), doc, "UTF-8", 1);
if(!saveVIP(player)){
result = false;
}
xmlFreeDoc(doc);
xmlMutexUnlock(xmlmutex);
return result;
}
Zakładki