/* Rose Online Server Emulator Copyright (C) 2006,2007 OSRose Team http://www.osrose.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. depeloped with Main erose/hrose source server + some change from the original eich source */ #include "player.h" #include "worldserver.h" unsigned char GetCharVal( char mychar ) { switch( mychar ) { case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; case 'a': return 10; case 'b': return 11; case 'c': return 12; case 'd': return 13; case 'e': return 14; case 'f': return 15; case 'A': return 10; case 'B': return 11; case 'C': return 12; case 'D': return 13; case 'E': return 14; case 'F': return 15; default: break; } return 0; } void EncodeBinary( char* encoded, unsigned char* data, unsigned datalen ) { for( unsigned short i = 0, j = 0; i < datalen; i++ ) { encoded[ j++ ] = "0123456789ABCDEF"[ data[ i ] >> 4 ]; encoded[ j++ ] = "0123456789ABCDEF"[ data[ i ] & 0xf ]; } encoded[ datalen * 2 ] = 0; } void DecodeBinary( char* encoded, unsigned char* data ) { unsigned curbit = 0; for( unsigned i = 0; i < (unsigned)strlen(encoded); i+=2 ) { data[curbit] = GetCharVal( encoded[i] ) << 4; data[curbit] += GetCharVal( encoded[i+1] ); curbit++; } } // Load this characters userdata from the database bool CPlayer::loaddata( ) { //Log(MSG_INFO,"Loading character data"); MYSQL_ROW row; MYSQL_RES *result = GServer->DB->QStore("SELECT level,face,hairStyle,sex,classid,zuly,str,dex,_int,con,cha,sen,curHp,curMp,id,statp,skillp,exp,stamina,quickbar,basic_skills,askill,askilllvl,pskill,pskilllvl,respawnid,clanid,clan_rank,townid,isgm,isdev FROM characters WHERE char_name='%s'", CharInfo->charname); if(result==NULL) return false; if(mysql_num_rows(result)!=1) { Log( MSG_WARNING, "Number of user with charname '%s' is %i", CharInfo->charname,mysql_num_rows(result)); return false; } row = mysql_fetch_row(result); Stats->Level = atoi(row[0]); CharInfo->Face = atoi(row[1]); CharInfo->Hair = atoi(row[2]); CharInfo->Sex = atoi(row[3]); CharInfo->Job = atoi(row[4]); CharInfo->Zulies = atol(row[5]); Attr->Str = atoi(row[6]); Attr->Dex = atoi(row[7]); Attr->Int = atoi(row[8]); Attr->Con = atoi(row[9]); Attr->Cha = atoi(row[10]); Attr->Sen = atoi(row[11]); Stats->HP = atoi(row[12]); Stats->MP = atoi(row[13]); CharInfo->charid = atoi(row[14]); CharInfo->StatPoints = atoi(row[15]); CharInfo->SkillPoints = atoi(row[16]); CharInfo->Exp = atoi(row[17]); CharInfo->stamina = atoi(row[18]); Position->respawn = atoi(row[25]); Clan->clanid = atoi(row[26]); Clan->clanrank = atoi(row[27]); Position->saved = atoi(row[28]); Stats->xprate = GetXPRate(); CharInfo->IsGM = atoi(row[29]); CharInfo->IsDev = atoi(row[30]); Log(MSG_DEBUG,"Selected Character %s Class %i GM status: %i DEV status %i", CharInfo->charname, CharInfo->Job, CharInfo->IsGM, CharInfo->IsDev); p_skills = 0; for(char i=0;i<32;i++) { char* tmp=strtok((i==0?row[19]:NULL), ","); if (tmp!=NULL) quickbar[i]=atoi(tmp); else quickbar[i]=0; } for(char i=0;i<30;i++) { char* tmp=strtok((i==0?row[20]:NULL), ","); if (tmp!=NULL) bskills[i]=atoi(tmp); else bskills[i]=0; } for(char i=0;i<30;i++) { char* tmp=strtok((i==0?row[21]:NULL), ","); if (tmp!=NULL) askill[i]=atoi(tmp); else askill[i]=0; } for(char i=0;i<30;i++) { char* tmp=strtok((i==0?row[22]:NULL), ","); if (tmp!=NULL) askilllvl[i]=atoi(tmp); else askilllvl[i]=0; } for(char i=0;i<30;i++) { char* tmp=strtok((i==0?row[23]:NULL), ","); if (tmp!=NULL) pskill[i]=atoi(tmp); else pskill[i]=0; } for(char i=0;i<30;i++) { char* tmp=strtok((i==0?row[24]:NULL), ","); if (tmp!=NULL) pskilllvl[i]=atoi(tmp); else pskilllvl[i]=0; } GServer->DB->QFree( ); CharInfo->Pending_Exp = 0; Log(MSG_INFO,"Loading union data"); result = GServer->DB->QStore("SELECT unionid,union1points,union2points,union3points,union4points,union5points,union6points,union7points,union8points,union9points,union10points FROM characters WHERE char_name='%s'", CharInfo->charname); if(result == NULL) return false; if(mysql_num_rows(result)!=1) { Log( MSG_WARNING, "Number of user with charname '%s' is %i", CharInfo->charname,mysql_num_rows(result)); return false; } row = mysql_fetch_row(result); for (char points=0; points<11;points++) { if(points == 9) { Union_s->unionvar[points] = Session->KTPoints; } else { Union_s->unionvar[points] = atoi(row[points]); } } GServer->DB->QFree( ); // code to reset players back to the correct faction after using the KTRose shop if(Union_s->unionvar[0] == 9) { //Log(MSG_DEBUG, "UnionVar 7 used to reset player Union from %i to %i",Union_s->unionvar[0],Union_s->unionvar[7] ); Union_s->unionvar[0] = Union_s->unionvar[7]; Union_s->unionvar[7] = 0; } // PY loadup code //Log(MSG_INFO,"Loading inventory data"); result = GServer->DB->QStore("SELECT itemid,itemtype,refine,durability,lifespan,count,stats,socketed,appraised,trans_action FROM charitems WHERE owner=%i", CharInfo->charid); if(result == NULL) { Log(MSG_WARNING, "Something a bit wrong with this query"); return false; } const char *tmpid; const char *itmp; int itemid; while( row = mysql_fetch_row(result) ) { tmpid = strtok( row[0] , "|"); for(unsigned int i=1;i<=MAX_INVENTORY; i++) { if((itmp = strtok( NULL , "|"))!= NULL) items[i].itemnum = atoi(itmp); } tmpid = strtok( row[1] , "|"); for(unsigned int i=1;i<=MAX_INVENTORY; i++) { if((itmp = strtok( NULL , "|"))!= NULL) items[i].itemtype = atoi(itmp); } tmpid = strtok( row[2] , "|"); for(unsigned int i=1;i<=MAX_INVENTORY; i++) { if((itmp = strtok( NULL , "|"))!= NULL) items[i].refine = atoi(itmp); } tmpid = strtok( row[3] , "|"); for(unsigned int i=1;i<=MAX_INVENTORY; i++) { if((itmp = strtok( NULL , "|"))!= NULL) items[i].durability = atoi(itmp); } tmpid = strtok( row[4] , "|"); for(unsigned int i=1;i<=MAX_INVENTORY; i++) { if((itmp = strtok( NULL , "|"))!= NULL) items[i].lifespan = atoi(itmp); } tmpid = strtok( row[5] , "|"); for(unsigned int i=1;i<=MAX_INVENTORY; i++) { if((itmp = strtok( NULL , "|"))!= NULL) { items[i].count = atoi(itmp); //Log(MSG_INFO,"slot: %i itemid: %i type: %i count: %i",i, items[i].itemnum,items[i].itemtype,items[i].count); //PAT items seem to load ok here } } tmpid = strtok( row[6] , "|"); for(unsigned int i=1;i<=MAX_INVENTORY; i++) { if((itmp = strtok( NULL , "|"))!= NULL) { items[i].stats = atoi(itmp); if(items[i].stats >300) { items[i].gem = items[i].stats; } else items[i].gem = 0; } } tmpid = strtok( row[7] , "|"); for(unsigned int i=1;i<=MAX_INVENTORY; i++) { if((itmp = strtok( NULL , "|"))!= NULL) items[i].socketed = (atoi(itmp)==1)?true:false; //just in case there is a discrepency in the database this will fix sockets. if(items[i].gem != 0) items[i].socketed = true; } tmpid = strtok( row[8] , "|"); for(unsigned int i=1;i<=MAX_INVENTORY; i++) { if((itmp = strtok( NULL , "|"))!= NULL) items[i].appraised = (atoi(itmp)==1)?true:false; } for(unsigned int i=1;i<=MAX_INVENTORY; i++) { // first delete bad items if(items[i].itemnum > GServer->EquipList[items[i].itemtype].STBMax) { Log(MSG_INFO,"deleting item in slot: %i itemid: %i type: %i count: %i",i, items[i].itemnum,items[i].itemtype,items[i].count); //Item number too high items[i].itemnum = 0; items[i].itemtype = 0; items[i].count = 0; items[i].durability = 0; } // find item type for crafting if(items[i].itemtype > 0 && items[i].itemtype < 10) items[i].type = GServer->EquipList[items[i].itemtype].Index[items[i].itemnum]->type; if(items[i].itemtype == 10) items[i].type = GServer->UseList.Index[items[i].itemnum]->type; if(items[i].itemtype == 11) items[i].type = GServer->JemList.Index[items[i].itemnum]->type; if(items[i].itemtype == 12) items[i].type = GServer->NaturalList.Index[items[i].itemnum]->type; if(items[i].itemtype == 14) items[i].type = GServer->PatList.Index[items[i].itemnum]->type; //Log(MSG_INFO,"slot: %i itemid: %i type: %i count: %i",i, items[i].itemnum,items[i].itemtype,items[i].count); } } //PY end /* result = GServer->DB->QStore("SELECT itemnum,itemtype,refine,durability,lifespan,slotnum,count,stats,socketed,appraised,gem FROM items WHERE owner=%i", CharInfo->charid); if(result==NULL) return false; while(row = mysql_fetch_row(result)) { if(!GServer->IsValidItem( atoi(row[1]), atoi(row[0]) ) || atoi(row[6])==0) { Log(MSG_WARNING, "char %s have a invalid or empty item in inventory: %i-%i [%i], this item will be deleted", CharInfo->charname, atoi(row[1]), atoi(row[0]), atoi(row[6]) ); continue; } UINT itemnum = atoi(row[5]); items[itemnum].itemnum = atoi(row[0]); items[itemnum].itemtype = atoi(row[1]); items[itemnum].refine = atoi(row[2]); items[itemnum].durability = atoi(row[3]); items[itemnum].lifespan = atoi(row[4]); items[itemnum].count = atoi(row[6]); items[itemnum].stats = atoi(row[7]); items[itemnum].socketed = (atoi(row[8])==1)?true:false; items[itemnum].appraised = (atoi(row[9])==1)?true:false; items[itemnum].gem = atoi(row[10])>3999?0:atoi(row[10]); //extra code to fix bugged gem items if(items[itemnum].gem > 0) { items[itemnum].stats = items[itemnum].gem; } // find item type for crafting if(items[itemnum].itemtype < 10) items[itemnum].type = GServer->EquipList[items[itemnum].itemtype].Index[items[itemnum].itemnum]->type; if(items[itemnum].itemtype == 10) items[itemnum].type = GServer->UseList.Index[items[itemnum].itemnum]->type; if(items[itemnum].itemtype == 11) items[itemnum].type = GServer->JemList.Index[items[itemnum].itemnum]->type; if(items[itemnum].itemtype == 12) items[itemnum].type = GServer->NaturalList.Index[items[itemnum].itemnum]->type; if(items[itemnum].itemtype == 14) items[itemnum].type = GServer->PatList.Index[items[itemnum].itemnum]->type; }*/ //Log( MSG_DEBUG, "loaded inventory info"); GServer->DB->QFree( ); // PY loadup code for storage //Log(MSG_INFO,"Loading storage data"); result = GServer->DB->QStore("SELECT itemid,itemtype,refine,durability,lifespan,count,stats,socketed,appraised,trans_action FROM charstorage WHERE owner=%i", Session->userid); if(result == NULL) { Log(MSG_WARNING, "Something a bit wrong with this query"); return false; } tmpid = ""; itmp = 0; while( row = mysql_fetch_row(result) ) { tmpid = strtok( row[0] , "|"); for(unsigned int i=0;i<=MAX_STORAGE; i++) { if((itmp = strtok( NULL , "|"))!= NULL) storageitems[i].itemnum = atoi(itmp); //if (Session->userid == 8) //test code delete later //{ // if(i < 4) // Log(MSG_DEBUG,"Storage item %i loaded. Value = %i",i,atoi(itmp)); //} } tmpid = strtok( row[1] , "|"); for(unsigned int i=0;i<=MAX_STORAGE; i++) { if((itmp = strtok( NULL , "|"))!= NULL) storageitems[i].itemtype = atoi(itmp); } tmpid = strtok( row[2] , "|"); for(unsigned int i=0;i<=MAX_STORAGE; i++) { if((itmp = strtok( NULL , "|"))!= NULL) storageitems[i].refine = atoi(itmp); } tmpid = strtok( row[3] , "|"); for(unsigned int i=0;i<=MAX_STORAGE; i++) { if((itmp = strtok( NULL , "|"))!= NULL) storageitems[i].durability = atoi(itmp); } tmpid = strtok( row[4] , "|"); for(unsigned int i=0;i<=MAX_STORAGE; i++) { if((itmp = strtok( NULL , "|"))!= NULL) storageitems[i].lifespan = atoi(itmp); } tmpid = strtok( row[5] , "|"); for(unsigned int i=0;i<=MAX_STORAGE; i++) { if((itmp = strtok( NULL , "|"))!= NULL) storageitems[i].count = atoi(itmp); } tmpid = strtok( row[6] , "|"); for(unsigned int i=0;i<=MAX_STORAGE; i++) { if((itmp = strtok( NULL , "|"))!= NULL) { storageitems[i].stats = atoi(itmp); if(storageitems[i].stats > 300) { storageitems[i].gem = items[i].stats; } else storageitems[i].gem = 0; } } tmpid = strtok( row[7] , "|"); for(unsigned int i=0;i<=MAX_STORAGE; i++) { if((itmp = strtok( NULL , "|"))!= NULL) storageitems[i].socketed = (atoi(itmp)==1)?true:false; //just in case there is a discrepency in the database this will fix sockets. if(storageitems[i].gem != 0) storageitems[i].socketed = true; } tmpid = strtok( row[8] , "|"); for(unsigned int i=0;i<=MAX_STORAGE; i++) { if((itmp = strtok( NULL , "|"))!= NULL) storageitems[i].appraised = (atoi(itmp)==1)?true:false; } for(unsigned int i=0;i<=MAX_STORAGE; i++) { // find item type for crafting if(storageitems[i].itemtype > 0 && storageitems[i].itemtype < 10) storageitems[i].type = GServer->EquipList[storageitems[i].itemtype].Index[storageitems[i].itemnum]->type; if(storageitems[i].itemtype == 10) storageitems[i].type = GServer->UseList.Index[storageitems[i].itemnum]->type; if(storageitems[i].itemtype == 11) storageitems[i].type = GServer->JemList.Index[storageitems[i].itemnum]->type; if(storageitems[i].itemtype == 12) storageitems[i].type = GServer->NaturalList.Index[storageitems[i].itemnum]->type; if(storageitems[i].itemtype == 14) storageitems[i].type = GServer->PatList.Index[storageitems[i].itemnum]->type; } } //PY end /* //original storage load code GServer->DB->QFree( ); Log(MSG_INFO,"Loading storage data"); result = GServer->DB->QStore("SELECT itemnum,itemtype,refine,durability,lifespan,slotnum,count,stats,socketed,appraised,gem FROM storage WHERE owner=%i", Session->userid); if(result == NULL) return false; nstorageitems = mysql_num_rows(result); while(row = mysql_fetch_row(result)) { if(!GServer->IsValidItem( atoi(row[1]), atoi(row[0]) ) || atoi(row[6])==0) { Log(MSG_WARNING, "char %s have a invalid or empty item in storage: %i%i [%i], this item will be deleted", CharInfo->charname, atoi(row[1]), atoi(row[0]), atoi(row[6]) ); continue; } UINT itemnum = atoi(row[5]); storageitems[itemnum].itemnum = atoi(row[0]); storageitems[itemnum].itemtype = atoi(row[1]); storageitems[itemnum].refine = atoi(row[2]); storageitems[itemnum].durability = atoi(row[3]); storageitems[itemnum].lifespan = atoi(row[4]); storageitems[itemnum].count = atoi(row[6]); storageitems[itemnum].stats = atoi(row[7]); storageitems[itemnum].socketed = (atoi(row[8])==1)?true:false; storageitems[itemnum].appraised = (atoi(row[9])==1)?true:false; storageitems[itemnum].gem = atoi(row[10]); //extra code to fix bugged gem items if(storageitems[itemnum].gem > 0) { storageitems[itemnum].stats = storageitems[itemnum].gem; } // find item type for crafting if(storageitems[itemnum].itemtype < 10) storageitems[itemnum].type = GServer->EquipList[items[itemnum].itemtype].Index[items[itemnum].itemnum]->type; if(storageitems[itemnum].itemtype == 10) storageitems[itemnum].type = GServer->UseList.Index[items[itemnum].itemnum]->type; if(storageitems[itemnum].itemtype == 11) storageitems[itemnum].type = GServer->JemList.Index[items[itemnum].itemnum]->type; if(storageitems[itemnum].itemtype == 12) storageitems[itemnum].type = GServer->NaturalList.Index[items[itemnum].itemnum]->type; if(storageitems[itemnum].itemtype == 14) storageitems[itemnum].type = GServer->PatList.Index[items[itemnum].itemnum]->type; } */ //End of original storage load code. GServer->DB->QFree( ); //Log(MSG_INFO,"saving backup storage data."); SaveBackupStorage(1); // makes a copy of the account's storage at the moment of login //Log( MSG_DEBUG, "Saved backup storage data"); if(Clan->clanid!=0) { result = GServer->DB->QStore("SELECT logo,back,name,cp,grade FROM list_clan where id=%i", Clan->clanid); if(result==NULL) return false; if(mysql_num_rows(result)!=1) { Log(MSG_WARNING, "There are %i clan(s) with id %i", mysql_num_rows(result), Clan->clanid ); Clan->clanid=0; } else { row = mysql_fetch_row(result); Clan->logo = atoi(row[0]); Clan->back = atoi(row[1]); strcpy(Clan->clanname,row[2]); Clan->CP = atoi(row[3]); Clan->grade = atoi(row[4]); } GServer->DB->QFree( ); } memset(&quest, 0, sizeof(SQuestData)); //Log( MSG_DEBUG, "loaded clan info"); UINT QuestToggle = 0; UINT rowcount = 0; /* result = GServer->DB->QStore("SELECT quests from list_quest where owner=%i",CharInfo->charid ); if(result!=NULL) { while(row = mysql_fetch_row(result)) { if( row[0] != NULL ) { memcpy(&quest, row[0], sizeof(SQuestData)); rowcount++; } } if(rowcount == 0) //no data detected { //Log( MSG_DEBUG, "No quest data detected with Exjam method. using PY method instead"); QuestToggle = 1; // set toggle to use PY method GServer->DB->QFree( ); } if(QuestToggle == 0) { //delete the old quest entry after loading it. //GServer->DB->QExecute( "DELETE FROM list_quest WHERE owner=%i",thisclient->CharInfo->charid ); //now convert quest flags to new system for(int flagid=0;flagid<512;flagid++) { dword byteid = flagid / 8; dword bitid = flagid % 8; if (((quest.flags[byteid] >> bitid) & 1) == 1) quest.Qflags[byteid][bitid] = 1; else quest.Qflags[byteid][bitid] = 0; } GServer->DB->QFree( ); Log( MSG_DEBUG, "loaded quests via Exjam method"); savequests(this); Log( MSG_DEBUG, "Converted flags and re-saved quests info"); } } else { GServer->DB->QFree( ); } if(QuestToggle = 1) */ { // PY quest loading. Only performed if no old quests are found. Won't be any since there are no old characters Log( MSG_DEBUG, "starting PY quest load"); result = GServer->DB->QStore("SELECT questid,starttime,vbl,switches,items,count,episodevar,jobvar,planetvar,unionvar from player_quests where owner=%i",CharInfo->charid ); //Log( MSG_DEBUG, "ran the query"); tmpid = ""; itmp = ""; if(result != NULL) { UINT Index = 0; while(row = mysql_fetch_row(result)) { quest.quests[Index].QuestID = atoi(row[0]); quest.quests[Index].StartTime = atoi(row[1]); tmpid = strtok( row[2] , "|"); for(unsigned int j=0;j<=10;j++) //quest variables { if(tmpid != NULL) quest.quests[Index].Variables[j] = atoi(tmpid); else quest.quests[Index].Variables[j] = 0; tmpid = strtok(NULL, ",|"); //Log( MSG_DEBUG, "Quest Var[%i][%i] = %i",Index ,j ,quest.quests[Index].Variables[j]); } tmpid = strtok( row[3] , "|"); //quest switches for(unsigned int j=0;j<=4;j++) { if(tmpid != NULL) quest.quests[Index].Switches[j] = atoi(tmpid); else quest.quests[Index].Switches[j] = 0; tmpid = strtok(NULL, ",|"); //Log( MSG_DEBUG, "Quest Switch[%i][%i] = %i",Index ,j ,quest.quests[Index].Switches[j]); } tmpid = strtok( row[4] , "|"); //quest items for(unsigned int j=0;j<=5;j++) { if(tmpid != NULL) { itemid = atoi(tmpid); quest.quests[Index].Items[j].itemnum = itemid % 1000; quest.quests[Index].Items[j].itemtype = itemid / 1000; } else { quest.quests[Index].Items[j].itemnum = 0; quest.quests[Index].Items[j].itemtype = 0; } tmpid = strtok(NULL, ",|"); //Log( MSG_DEBUG, "Quest Item[%i][%i] = %i",Index , j ,quest.quests[Index].Items[j].itemnum); } tmpid = strtok( row[5] , "|"); //quest item count for(unsigned int j=0;j<=5;j++) { if(tmpid != NULL) quest.quests[Index].Items[j].count = atoi(tmpid); else quest.quests[Index].Items[j].count = 0; tmpid = strtok(NULL, ",|"); //Log( MSG_DEBUG, "Quest Item Count[%i][%i] = %i",Index ,j ,quest.quests[Index].Items[j].count); } tmpid = strtok( row[6] , "|"); for(unsigned int j=0;j<=5;j++) //episode variables { if(tmpid != NULL) quest.EpisodeVar[j] = atoi(tmpid); else quest.EpisodeVar[j] = 0; tmpid = strtok(NULL, ",|"); //Log( MSG_DEBUG, "Quest EpisodeVar[%i][%i] = %i",Index ,j ,quest.EpisodeVar[j]); } tmpid = strtok( row[7] , "|"); //job variables for(unsigned int j=0;j<=3;j++) { if(tmpid != NULL) quest.JobVar[j] = atoi(tmpid); else quest.JobVar[j] = 0; tmpid = strtok(NULL, ",|"); //Log( MSG_DEBUG, "Quest JobVar[%i][%i] = %i",Index ,j ,quest.JobVar[j]); } tmpid = strtok( row[8] , "|"); //Planet variables for(unsigned int j=0;j<=7;j++) { if(tmpid != NULL) quest.PlanetVar[j] = atoi(tmpid); else quest.PlanetVar[j] = 0; tmpid = strtok(NULL, ",|"); } tmpid = strtok( row[9] , "|"); //Planet variables for(unsigned int j=0;j<=10;j++) { if(tmpid != NULL) quest.UnionVar[j] = atoi(tmpid); else quest.UnionVar[j] = 0; tmpid = strtok(NULL, ",|"); } Index ++; } } //Log( MSG_DEBUG, "loaded the regular quest variables"); GServer->DB->QFree( ); // PY method load quest flags //Log( MSG_DEBUG, "starting PY flag load"); result = GServer->DB->QStore("SELECT flags from questflags where owner=%i",CharInfo->charid ); //Log( MSG_DEBUG, "ran the query"); if(result != NULL) { tmpid = ""; itmp = 0; UINT Index = 0; UINT flagCount = 0; //first set all quest flags to zero for(int i=0;i<64;i++) { for(int j=0;j<8;j++) quest.Qflags[i][j] = 0; } while(row = mysql_fetch_row(result)) { int flagid = atoi(row[0]); dword byteid = flagid / 8; dword bitid = flagid % 8; quest.Qflags[byteid][bitid] = 1; flagCount++; } //Log( MSG_DEBUG, "Flag count = %i",flagCount); } GServer->DB->QFree( ); //Log( MSG_DEBUG, "loaded quests info via PY method"); } Session->isLoggedIn = true; // Timestamp for last login time_t rtime; time(&rtime); char *timestamp = ctime(&rtime); timestamp[ strlen(timestamp)-1 ] = ' '; //Log(MSG_DEBUG,"setting time stamp fo login: %s for userid: %u",timestamp,Session->userid ); GServer->DB->QExecute("UPDATE accounts SET online=1, lastlogin='%s' where id=%u", timestamp,Session->userid ); Session->LogTime = clock(); //Log(MSG_INFO,"set datestamp"); // Calculate how many fairies are available online, according to amount of players int oldFairyMax = GServer->Config.FairyMax; GServer->Config.FairyMax = (int)ceil((float)GServer->ClientList.size() / 50.0) + GServer->Config.ScrollFairy; //1 fairy for every 50 player + the number of fairies summoned by scrolls if( oldFairyMax < GServer->Config.FairyMax ){ CFairy* thisfairy = new (nothrow) CFairy; thisfairy->LastTime = clock(); thisfairy->assigned = 0; thisfairy->ListIndex = 0; thisfairy->WaitTime = GServer->Config.FairyWait; GServer->FairyList.push_back( thisfairy ); } //die_quest = 0; return true; } // Trying a new save method PY (nothing changed yet. just made a copy of savedata for safety void CPlayer::savedata( ) { lastSaveTime = clock(); if(Session->userid!=0) { CMap* map = GServer->MapList.Index[Position->Map]; CRespawnPoint* thisrespawn = map->GetNearRespawn( this ); CPlayer* thisclient = GServer->GetClientByID( clientid ); if(thisrespawn == NULL) Position->respawn = 4; else Position->respawn = thisrespawn->id; char quick[1024]; char basic[1024]; //char sclass[1024]; //char slevel[1024]; char active[1024]; char activelvl[1024]; char pasive[1024]; char pasivelvl[1024]; for(UINT i=0;i<30;i++) { if(i==0) sprintf(&basic[i], "%i",bskills[i]); else sprintf(&basic[strlen(basic)], ",%i",bskills[i]); } for(UINT i=0;i<30;i++) { if(i==0) sprintf(&active[i], "%i",askill[i]); else sprintf(&active[strlen(active)], ",%i",askill[i]); } for(UINT i=0;i<30;i++) { if(i==0) sprintf(&activelvl[i], "%i",askilllvl[i]); else sprintf(&activelvl[strlen(activelvl)], ",%i",askilllvl[i]); } for(UINT i=0;i<30;i++) { if(i==0) sprintf(&pasive[i], "%i",pskill[i]); else sprintf(&pasive[strlen(pasive)], ",%i",pskill[i]); } for(UINT i=0;i<30;i++) { if(i==0) sprintf(&pasivelvl[i], "%i",pskilllvl[i]); else sprintf(&pasivelvl[strlen(pasivelvl)], ",%i",pskilllvl[i]); } for(UINT i=0;i<32;i++) { if(i==0) sprintf(&quick[i], "%i",quickbar[i]); else sprintf(&quick[strlen(quick)], ",%i",quickbar[i]); } long int hp = Stats->HP; if(hp<=0) hp=Stats->MaxHP * 10 / 100; if(Stats->MP<0) Stats->MP=0; GServer->DB->QExecute("UPDATE characters SET level=%i,face=%i,hairStyle=%i,sex=%i,classid=%i,zuly=%i,str=%i,dex=%i,_int=%i, con=%i,cha=%i,sen=%i,curHp=%i,curMp=%i,id=%i,statp=%i,skillp=%i,exp=%i,stamina=%i,quickbar='%s',basic_skills='%s',askill='%s',askilllvl='%s',pskill='%s',pskilllvl='%s',respawnid=%i,clanid=%i,clan_rank=%i,townid=%i WHERE char_name='%s'", Stats->Level, CharInfo->Face, CharInfo->Hair, CharInfo->Sex, CharInfo->Job, CharInfo->Zulies, Attr->Str, Attr->Dex, Attr->Int, Attr->Con, Attr->Cha, Attr->Sen, hp, Stats->MP, CharInfo->charid, CharInfo->StatPoints, CharInfo->SkillPoints, CharInfo->Exp, CharInfo->stamina, quick, basic, active, activelvl, pasive, pasivelvl, Position->respawn, Clan->clanid, Clan->clanrank, Position->saved, CharInfo->charname ); GServer->DB->QExecute("UPDATE characters SET unionid=%i,union1points=%i,union2points=%i,union3points=%i,union4points=%i,union5points=%i,union6points=%i,union7points=%i,union8points=%i,union9points=%i,union10points=%i WHERE char_name='%s'", Union_s->unionvar[0], Union_s->unionvar[1],Union_s->unionvar[2], Union_s->unionvar[3], Union_s->unionvar[4], Union_s->unionvar[5], Union_s->unionvar[6], Union_s->unionvar[7], Union_s->unionvar[8], Union_s->unionvar[9], Union_s->unionvar[10], CharInfo->charname ); //save the inventory saveinventory(); //save the storage items savestorage(); //this lot to be removed later //if(!GServer->DB->QExecute("DELETE FROM items WHERE owner=%i", CharInfo->charid)) return; //for(UINT i=0;i 0) // { // GServer->DB->QExecute("INSERT INTO items (owner,itemnum,itemtype,refine,durability,lifespan,slotnum,count,stats,socketed,appraised,gem) VALUES(%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i)", // CharInfo->charid, items[i].itemnum, items[i].itemtype,items[i].refine, items[i].durability, // items[i].lifespan, i, items[i].count, items[i].stats, (items[i].socketed?1:0), // (items[i].appraised?1:0),items[i].gem ); // } //} //Why is this still here and active? //if savestorage is live and functional then this antiquated crap needs to be removed if(!GServer->DB->QExecute("DELETE FROM storage WHERE owner=%i", Session->userid)) return; for(UINT i=0;i<160;i++) { if (storageitems[i].count > 0) { GServer->DB->QExecute("INSERT INTO storage (owner,itemnum,itemtype,refine,durability,lifespan,slotnum,count,stats,socketed,appraised,gem) VALUES(%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i)", Session->userid, storageitems[i].itemnum, storageitems[i].itemtype,storageitems[i].refine, storageitems[i].durability, storageitems[i].lifespan, i, storageitems[i].count, storageitems[i].stats, (storageitems[i].socketed?1:0), (storageitems[i].appraised?1:0), storageitems[i].gem ); } } savequests( this ); GServer->DB->QExecute("UPDATE accounts SET zulystorage = %i, logtime = %i,ktpoints=%i WHERE id = %i", CharInfo->Storage_Zulies, Session->logtime,Session->KTPoints, Session->userid); Log(MSG_INFO, "Data Saved for char '%s' ", CharInfo->charname ); } } //PY Character save void CPlayer::quicksave( ) { GServer->DB->QExecute("UPDATE characters SET level=%i,face=%i,hairStyle=%i,sex=%i,classid=%i,zuly=%i,str=%i,dex=%i,_int=%i, con=%i,cha=%i,sen=%i,curHp=%i,curMp=%i,id=%i,statp=%i,skillp=%i,exp=%i,stamina=%i,respawnid=%i,clanid=%i,clan_rank=%i,townid=%i WHERE char_name='%s'", Stats->Level, CharInfo->Face, CharInfo->Hair, CharInfo->Sex, CharInfo->Job, CharInfo->Zulies, Attr->Str, Attr->Dex, Attr->Int, Attr->Con, Attr->Cha, Attr->Sen, Stats->HP, Stats->MP, CharInfo->charid, CharInfo->StatPoints, CharInfo->SkillPoints, CharInfo->Exp, CharInfo->stamina, Position->respawn, Clan->clanid, Clan->clanrank, Position->saved, CharInfo->charname ); Log(MSG_INFO, "Data Quick Saved for char '%s' ", CharInfo->charname ); } //PY Inventory save void CPlayer::saveinventory( ) { //build the strings char tmp1[1024] = ""; char tmp2[1024] = ""; char tmp3[1024] = ""; char tmp4[1024] = ""; char tmp5[1024] = ""; char tmp6[1024] = ""; char tmp7[1024] = ""; char tmp8[1024] = ""; char tmp9[1024] = ""; char slot[1024] = ""; long tran = 0; for(unsigned int i=0;i<=MAX_INVENTORY; i++) //inventory holds 140 { int socketed = 0; int appraised = 0; tran += items[i].itemnum + items[i].itemtype + items[i].refine; //tran += items[i].durability + items[i].lifespan + items[i].count + items[i].stats; //Log(MSG_INFO,"slot: %i itemid: %i type: %i count: %i",i, items[i].itemnum,items[i].itemtype,items[i].count); if(i == 0) { if(items[i].count == 0) { sprintf(&tmp1[strlen(tmp1)], "0"); sprintf(&tmp2[strlen(tmp2)], "0"); sprintf(&tmp3[strlen(tmp3)], "0"); sprintf(&tmp4[strlen(tmp4)], "0"); sprintf(&tmp5[strlen(tmp5)], "0"); sprintf(&tmp6[strlen(tmp6)], "0"); sprintf(&tmp7[strlen(tmp7)], "0"); sprintf(&tmp8[strlen(tmp8)], "0"); sprintf(&tmp9[strlen(tmp9)], "0"); sprintf(&slot[strlen(slot)], "%i",i); } else { if(items[i].socketed == true) socketed = 1; if(items[i].appraised == true) appraised = 1; sprintf(&tmp1[strlen(tmp1)], "%i",items[i].itemnum); sprintf(&tmp2[strlen(tmp2)], "%i",items[i].itemtype); sprintf(&tmp3[strlen(tmp3)], "%i",items[i].refine); sprintf(&tmp4[strlen(tmp4)], "%i",items[i].durability); sprintf(&tmp5[strlen(tmp5)], "%i",items[i].lifespan); sprintf(&tmp6[strlen(tmp6)], "%i",items[i].count); sprintf(&tmp7[strlen(tmp7)], "%i",items[i].stats); sprintf(&tmp8[strlen(tmp8)], "%i",socketed); sprintf(&tmp9[strlen(tmp9)], "%i",appraised); sprintf(&slot[strlen(slot)], "%i",i); } } else { if(items[i].count == 0) { sprintf(&tmp1[strlen(tmp1)], "|0"); sprintf(&tmp2[strlen(tmp2)], "|0"); sprintf(&tmp3[strlen(tmp3)], "|0"); sprintf(&tmp4[strlen(tmp4)], "|0"); sprintf(&tmp5[strlen(tmp5)], "|0"); sprintf(&tmp6[strlen(tmp6)], "|0"); sprintf(&tmp7[strlen(tmp7)], "|0"); sprintf(&tmp8[strlen(tmp8)], "|0"); sprintf(&tmp9[strlen(tmp9)], "|0"); sprintf(&slot[strlen(slot)], "|%i",i); } else { if(items[i].socketed == true) socketed = 1; if(items[i].appraised == true) appraised = 1; if(items[i].gem != 0 && items[i].gem != items[i].stats) items[i].stats = items[i].gem; sprintf(&tmp1[strlen(tmp1)], "|%i",items[i].itemnum); sprintf(&tmp2[strlen(tmp2)], "|%i",items[i].itemtype); sprintf(&tmp3[strlen(tmp3)], "|%i",items[i].refine); sprintf(&tmp4[strlen(tmp4)], "|%i",items[i].durability); sprintf(&tmp5[strlen(tmp5)], "|%i",items[i].lifespan); sprintf(&tmp6[strlen(tmp6)], "|%i",items[i].count); sprintf(&tmp7[strlen(tmp7)], "|%i",items[i].stats); sprintf(&tmp8[strlen(tmp8)], "|%i",socketed); sprintf(&tmp9[strlen(tmp9)], "|%i",appraised); sprintf(&slot[strlen(slot)], "|%i",i); } } } //Log(MSG_INFO,"Save string1 = %s ", tmp1); //Log(MSG_INFO,"Save string2 = %s ", tmp2); //Log(MSG_INFO,"Save string3 = %s ", tmp3); //Log(MSG_INFO,"Save string4 = %s ", tmp4); //Log(MSG_INFO,"Save string5 = %s ", tmp5); //Log(MSG_INFO,"Save string6 = %s ", tmp6); //Log(MSG_INFO,"Save string7 = %s ", tmp7); //Log(MSG_INFO,"Save string8 = %s ", tmp8); //Log(MSG_INFO,"Save string9 = %s ", tmp9); //check if a record exists for this player MYSQL_RES *result = GServer->DB->QStore("SELECT itemid,itemtype,refine,durability,lifespan,count,stats,socketed,appraised,slot,trans_action FROM charitems WHERE owner=%i", CharInfo->charid); MYSQL_ROW row; bool doesexist = false; while(row = mysql_fetch_row(result)) { doesexist = true; } GServer->DB->QFree( ); if(doesexist == true) { //record exists so update it //Log(MSG_INFO,"record exists.... updating"); GServer->DB->QExecute("UPDATE charitems SET itemid='%s',itemtype='%s',refine='%s',durability='%s',lifespan='%s',count='%s',stats='%s',socketed='%s',appraised='%s',slot='%s',trans_action=%i WHERE owner='%i'", tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,tmp9,slot,tran,CharInfo->charid); } else { //record does not exist so make a new one //Log(MSG_INFO,"record does not exist.... creating new record"); //GServer->DB->QExecute("INSERT INTO charitems (owner,trans_action) VALUES ('%i','%i')",CharInfo->charid,tran); GServer->DB->QExecute("INSERT INTO charitems (owner,itemid,itemtype,refine,durability,lifespan,count,stats,socketed,appraised,trans_action) VALUES('%i','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%i')", CharInfo->charid,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,tmp9,slot,tran); } //save zuly GServer->DB->QExecute("UPDATE characters SET zuly=%i WHERE char_name='%s'", CharInfo->Zulies, CharInfo->charname ); //Log(MSG_INFO,"Inventory saved"); return; } //PY Storage save void CPlayer::savestorage( ) { //build the strings. As we need a slot zero for storage we are going to have to add a buffer entry first //for some bizarre reason when we load teh storage it ignores the leading zero so stuff gets shifted left without this char tmp1[1024] = "0"; char tmp2[1024] = "0"; char tmp3[1024] = "0"; char tmp4[1024] = "0"; char tmp5[1024] = "0"; char tmp6[1024] = "0"; char tmp7[1024] = "0"; char tmp8[1024] = "0"; char tmp9[1024] = "0"; char slot[1024] = "0"; long tran = 0; for(unsigned int i=0;i<=MAX_STORAGE; i++) //Storage holds 160 { int socketed = 0; int appraised = 0; tran += storageitems[i].itemnum + storageitems[i].itemtype + storageitems[i].refine; tran += storageitems[i].durability + storageitems[i].lifespan + storageitems[i].count + storageitems[i].stats; if(storageitems[i].count == 0) { sprintf(&tmp1[strlen(tmp1)], "|0"); sprintf(&tmp2[strlen(tmp2)], "|0"); sprintf(&tmp3[strlen(tmp3)], "|0"); sprintf(&tmp4[strlen(tmp4)], "|0"); sprintf(&tmp5[strlen(tmp5)], "|0"); sprintf(&tmp6[strlen(tmp6)], "|0"); sprintf(&tmp7[strlen(tmp7)], "|0"); sprintf(&tmp8[strlen(tmp8)], "|0"); sprintf(&tmp9[strlen(tmp9)], "|0"); if(i != 0) //don't write the zero value for slot since we already started the string with a leading zero sprintf(&slot[strlen(slot)], "|%i",i); } else { if(storageitems[i].socketed == true) socketed = 1; if(storageitems[i].appraised == true) appraised = 1; sprintf(&tmp1[strlen(tmp1)], "|%i",storageitems[i].itemnum); sprintf(&tmp2[strlen(tmp2)], "|%i",storageitems[i].itemtype); sprintf(&tmp3[strlen(tmp3)], "|%i",storageitems[i].refine); sprintf(&tmp4[strlen(tmp4)], "|%i",storageitems[i].durability); sprintf(&tmp5[strlen(tmp5)], "|%i",storageitems[i].lifespan); sprintf(&tmp6[strlen(tmp6)], "|%i",storageitems[i].count); sprintf(&tmp7[strlen(tmp7)], "|%i",storageitems[i].stats); sprintf(&tmp8[strlen(tmp8)], "|%i",socketed); sprintf(&tmp9[strlen(tmp9)], "|%i",appraised); if(i != 0) //don't write the zero value for slot since we already started the string with a leading zero sprintf(&slot[strlen(slot)], "|%i",i); } } //check if a record exists for this player MYSQL_RES *result = GServer->DB->QStore("SELECT itemid,itemtype,refine,durability,lifespan,count,stats,socketed,appraised,slot,trans_action FROM charstorage WHERE owner=%i", Session->userid); MYSQL_ROW row; bool doesexist = false; while(row = mysql_fetch_row(result)) { doesexist = true; } GServer->DB->QFree( ); if(doesexist == true) { //record exists so update it //Log(MSG_INFO,"record exists.... updating"); GServer->DB->QExecute("UPDATE charstorage SET itemid='%s',itemtype='%s',refine='%s',durability='%s',lifespan='%s',count='%s',stats='%s',socketed='%s',appraised='%s',slot='%s',trans_action=%i WHERE owner='%i'", tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,tmp9,slot,tran,Session->userid); } else { //record does not exist so make a new one //Log(MSG_INFO,"record does not exist.... creating new record"); //GServer->DB->QExecute("INSERT INTO charitems (owner,trans_action) VALUES ('%i','%i')",CharInfo->charid,tran); GServer->DB->QExecute("INSERT INTO charstorage (owner,itemid,itemtype,refine,durability,lifespan,count,stats,socketed,appraised,slot,trans_action) VALUES('%i','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%i')", Session->userid,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,tmp9,slot,tran); } //save zuly storage GServer->DB->QExecute("UPDATE accounts SET zulystorage = %i WHERE id = %i", CharInfo->Storage_Zulies, Session->userid); //Log(MSG_INFO,"Storage saved"); return; } //PY Storage save void CPlayer::SaveBackupStorage( int logstate ) { //build the strings. As we need a slot zero for storage we are going to have to add a buffer entry first //for some bizarre reason when we load the storage it ignores the leading zero so stuff gets shifted left without this char tmp1[1024] = "0"; char tmp2[1024] = "0"; char tmp3[1024] = "0"; char tmp4[1024] = "0"; char tmp5[1024] = "0"; char tmp6[1024] = "0"; char tmp7[1024] = "0"; char tmp8[1024] = "0"; char tmp9[1024] = "0"; char slot[1034] = "0"; long tran = 0; for(unsigned int i=0;i<=MAX_STORAGE; i++) //Storage holds 160 { int socketed = 0; int appraised = 0; if(storageitems[i].count == 0) { sprintf(&tmp1[strlen(tmp1)], "|0"); sprintf(&tmp2[strlen(tmp2)], "|0"); sprintf(&tmp3[strlen(tmp3)], "|0"); sprintf(&tmp4[strlen(tmp4)], "|0"); sprintf(&tmp5[strlen(tmp5)], "|0"); sprintf(&tmp6[strlen(tmp6)], "|0"); sprintf(&tmp7[strlen(tmp7)], "|0"); sprintf(&tmp8[strlen(tmp8)], "|0"); sprintf(&tmp9[strlen(tmp9)], "|0"); if(i != 0) //don't write the zero value for slot since we already started the string with a leading zero sprintf(&slot[strlen(slot)], "|%i",i); } else { if(storageitems[i].socketed == true) socketed = 1; if(storageitems[i].appraised == true) appraised = 1; sprintf(&tmp1[strlen(tmp1)], "|%i",storageitems[i].itemnum); sprintf(&tmp2[strlen(tmp2)], "|%i",storageitems[i].itemtype); sprintf(&tmp3[strlen(tmp3)], "|%i",storageitems[i].refine); sprintf(&tmp4[strlen(tmp4)], "|%i",storageitems[i].durability); sprintf(&tmp5[strlen(tmp5)], "|%i",storageitems[i].lifespan); sprintf(&tmp6[strlen(tmp6)], "|%i",storageitems[i].count); sprintf(&tmp7[strlen(tmp7)], "|%i",storageitems[i].stats); sprintf(&tmp8[strlen(tmp8)], "|%i",socketed); sprintf(&tmp9[strlen(tmp9)], "|%i",appraised); if(i != 0) //don't write the zero value for slot since we already started the string with a leading zero sprintf(&slot[strlen(slot)], "|%i",i); } } MYSQL_RES *result = GServer->DB->QStore("SELECT thisrev FROM backupstorage WHERE owner=%i", Session->userid); MYSQL_ROW row; int thisrev = 0; int tmprev = 0; while(row = mysql_fetch_row(result)) { tmprev = atoi(row[0]); if(tmprev > thisrev)thisrev = tmprev; } thisrev ++; // add 1 to the highest existing rev number for this user GServer->DB->QFree( ); // Timestamp time_t rtime; time(&rtime); char *timestamp = ctime(&rtime); timestamp[ strlen(timestamp)-1 ] = ' '; GServer->DB->QExecute("INSERT INTO backupstorage (owner,itemid,itemtype,refine,durability,lifespan,count,stats,socketed,appraised,slot,trans_action,datestamp,thisrev) VALUES('%i','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%i','%s','%i')", Session->userid,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,tmp9,slot,logstate,timestamp,thisrev); //Log(MSG_INFO,"backup Storage saved for User %i revision number %i logstate %i",Session->userid, thisrev, logstate); return; } // This is a REALLY bad way of saving the character data, but it works ^^ /*void CPlayer::savedata( ) { lastSaveTime = clock(); if(Session->userid!=0) { CMap* map = GServer->MapList.Index[Position->Map]; CRespawnPoint* thisrespawn = map->GetNearRespawn( this ); CPlayer* thisclient = GServer->GetClientByID( clientid ); if(thisrespawn == NULL) Position->respawn = 4; else Position->respawn = thisrespawn->id; char quick[1024]; char basic[1024]; //char sclass[1024]; //char slevel[1024]; char active[1024]; char activelvl[1024]; char pasive[1024]; char pasivelvl[1024]; for(UINT i=0;i<30;i++) { if(i==0) sprintf(&basic[i], "%i",bskills[i]); else sprintf(&basic[strlen(basic)], ",%i",bskills[i]); } for(UINT i=0;i<30;i++) { if(i==0) sprintf(&active[i], "%i",askill[i]); else sprintf(&active[strlen(active)], ",%i",askill[i]); } for(UINT i=0;i<30;i++) { if(i==0) sprintf(&activelvl[i], "%i",askilllvl[i]); else sprintf(&activelvl[strlen(activelvl)], ",%i",askilllvl[i]); } for(UINT i=0;i<30;i++) { if(i==0) sprintf(&pasive[i], "%i",pskill[i]); else sprintf(&pasive[strlen(pasive)], ",%i",pskill[i]); } for(UINT i=0;i<30;i++) { if(i==0) sprintf(&pasivelvl[i], "%i",pskilllvl[i]); else sprintf(&pasivelvl[strlen(pasivelvl)], ",%i",pskilllvl[i]); } for(UINT i=0;i<32;i++) { if(i==0) sprintf(&quick[i], "%i",quickbar[i]); else sprintf(&quick[strlen(quick)], ",%i",quickbar[i]); } long int hp = Stats->HP; if(hp<=0) hp=Stats->MaxHP * 10 / 100; if(Stats->MP<0) Stats->MP=0; //Save data complete now?? (Pepu) GServer->DB->QExecute("UPDATE characters SET level=%i,face=%i,hairStyle=%i,sex=%i,classid=%i,zuly=%i,str=%i,dex=%i,_int=%i, con=%i,cha=%i,sen=%i,curHp=%i,curMp=%i,id=%i,statp=%i,skillp=%i,exp=%i,stamina=%i,quickbar='%s',basic_skills='%s',askill='%s',askilllvl='%s',pskill='%s',pskilllvl='%s',respawnid=%i,clanid=%i,clan_rank=%i,townid=%i WHERE char_name='%s'", Stats->Level, CharInfo->Face, CharInfo->Hair, CharInfo->Sex, CharInfo->Job, CharInfo->Zulies, Attr->Str, Attr->Dex, Attr->Int, Attr->Con, Attr->Cha, Attr->Sen, hp, Stats->MP, CharInfo->charid, CharInfo->StatPoints, CharInfo->SkillPoints, CharInfo->Exp, CharInfo->stamina, quick, basic, active, activelvl, pasive, pasivelvl, Position->respawn, Clan->clanid, Clan->clanrank, Position->saved, CharInfo->charname ); GServer->DB->QExecute("UPDATE characters SET unionid=%i,union1points=%i,union2points=%i,union3points=%i,union4points=%i,union5points=%i,union6points=%i,union7points=%i,union8points=%i,union9points=%i,union10points=%i WHERE char_name='%s'", Union_s->unionvar[0], Union_s->unionvar[1],Union_s->unionvar[2], Union_s->unionvar[3], Union_s->unionvar[4], Union_s->unionvar[5], Union_s->unionvar[6], Union_s->unionvar[7], Union_s->unionvar[8], Union_s->unionvar[9], Union_s->unionvar[10], CharInfo->charname ); if(!GServer->DB->QExecute("DELETE FROM items WHERE owner=%i", CharInfo->charid)) return; for(UINT i=0;i 0) { GServer->DB->QExecute("INSERT INTO items (owner,itemnum,itemtype,refine,durability,lifespan,slotnum,count,stats,socketed,appraised,gem) VALUES(%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i)", CharInfo->charid, items[i].itemnum, items[i].itemtype,items[i].refine, items[i].durability, items[i].lifespan, i, items[i].count, items[i].stats, (items[i].socketed?1:0), (items[i].appraised?1:0),items[i].gem ); } } if(!GServer->DB->QExecute("DELETE FROM storage WHERE owner=%i", Session->userid)) return; for(UINT i=0;i<160;i++) { if (storageitems[i].count > 0) { GServer->DB->QExecute("INSERT INTO storage (owner,itemnum,itemtype,refine,durability,lifespan,slotnum,count,stats,socketed,appraised,gem) VALUES(%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i)", Session->userid, storageitems[i].itemnum, storageitems[i].itemtype,storageitems[i].refine, storageitems[i].durability, storageitems[i].lifespan, i, storageitems[i].count, storageitems[i].stats, (storageitems[i].socketed?1:0), (storageitems[i].appraised?1:0), storageitems[i].gem ); } } savequests( this ); GServer->DB->QExecute("UPDATE accounts SET zulystorage = %i WHERE id = %i", CharInfo->Storage_Zulies, Session->userid); Log(MSG_INFO, "Data Saved for char '%s' ", CharInfo->charname ); } }*/ void CPlayer::savequests( CPlayer* thisclient ) { //char* questBuffer = new char[sizeof(SQuestData)*3 +1]; //mysql_real_escape_string(GServer->DB->Mysql, questBuffer, (const char*)&quest, sizeof(SQuestData)); //GServer->DB->QExecute( "DELETE FROM list_quest WHERE owner=%i",thisclient->CharInfo->charid ); //GServer->DB->QExecute("INSERT INTO list_quest (owner, quests) VALUES(%i,'%s')", // thisclient->CharInfo->charid, questBuffer); //delete questBuffer; //PY retro method //GServer->DB->QFree( ); //Log(MSG_DEBUG,"Started SaveQuests"); GServer->DB->QExecute( "DELETE FROM player_quests WHERE owner=%i",thisclient->CharInfo->charid ); //Log(MSG_DEBUG,"Ran the player_quests deletion query"); for(int i=0;i<10;i++) { if (thisclient->quest.quests[i].QuestID == 0) continue; char vbl[100] = ""; //make the variables list for(int j=0;j<10;j++) { sprintf(&vbl[strlen(vbl)], "%u",thisclient->quest.quests[i].Variables[j]); if(j < 9) sprintf(&vbl[strlen(vbl)],"|"); } char switches[10] = ""; //make the switches list for(int j=0;j<4;j++) { sprintf(&switches[strlen(switches)], "%u",thisclient->quest.quests[i].Switches[j]); if(j < 3) sprintf(&switches[strlen(switches)],"|"); } char itemslist[100] = ""; //make the items list. Changed items to itemslist due to warning. char itemcount[100] = ""; //item counts for(int j=0;j<5;j++) { int ItemID = thisclient->quest.quests[i].Items[j].itemtype * 1000 + thisclient->quest.quests[i].Items[j].itemnum; //sprintf(&items[strlen(items)], "%i",thisclient->quest.quests[i].Items[j].itemnum); sprintf(&itemslist[strlen(itemslist)], "%i",ItemID); sprintf(&itemcount[strlen(itemcount)], "%i",thisclient->quest.quests[i].Items[j].count); if(j < 4) { sprintf(&itemslist[strlen(itemslist)],"|"); sprintf(&itemcount[strlen(itemcount)],"|"); } } char episode[50] = ""; //make the episode variable list for(int j=0;j<5;j++) { sprintf(&episode[strlen(episode)], "%u",thisclient->quest.EpisodeVar[j]); if(j < 4) sprintf(&episode[strlen(episode)],"|"); } char jobvar[30] = ""; //make the job variable list for(int j=0;j<3;j++) { sprintf(&jobvar[strlen(jobvar)], "%u",thisclient->quest.JobVar[j]); if(j < 2) sprintf(&jobvar[strlen(jobvar)],"|"); } char planetvar[70] = ""; //make the planet variable list for(int j=0;j<7;j++) { sprintf(&planetvar[strlen(planetvar)], "%u",thisclient->quest.PlanetVar[j]); if(j < 6) sprintf(&planetvar[strlen(planetvar)],"|"); } char unionvar[100] = ""; //make the union variable list for(int j=0;j<10;j++) { sprintf(&unionvar[strlen(unionvar)], "%u",thisclient->quest.UnionVar[j]); if(j < 9) sprintf(&unionvar[strlen(unionvar)],"|"); } GServer->DB->QExecute("INSERT INTO player_quests (owner, questid, starttime, vbl, switches, items, count, episodevar, jobvar, planetvar, unionvar) VALUES(%i,%i,%i,'%s','%s','%s','%s','%s','%s','%s','%s')", thisclient->CharInfo->charid, thisclient->quest.quests[i].QuestID, thisclient->quest.quests[i].StartTime, vbl, switches, itemslist, itemcount, episode, jobvar, planetvar, unionvar); //Log(MSG_DEBUG,"Ran the player_quests insertion query"); } //GServer->DB->QFree( ); //now the quest flags GServer->DB->QExecute( "DELETE FROM questflags WHERE owner=%i",thisclient->CharInfo->charid ); //Log(MSG_DEBUG,"Ran the questflag deletion query"); char qflags[10000] = ""; int flagCount = 0; /* for(int i=0;i<1000;i++) { if(thisclient->quest.Qflags[i] == 1) { if(sizeof(&qflags) > 995) { Log(MSG_WARNING,"Quest flag list too big for player %s",thisclient->CharInfo->charname); i = 999; continue; } if(flagCount == 0) { sprintf(&qflags[strlen(qflags)], "%i",i); flagCount++; } else { sprintf(&qflags[strlen(qflags)],"|"); sprintf(&qflags[strlen(qflags)], "%i",i); flagCount++; } } } */ for(int i=0;i<0x40;i++) { for(int j=0;j<8;j++) { if(thisclient->quest.Qflags[i][j] != 0) { int flagid = (i*8)+j; GServer->DB->QExecute("INSERT INTO questflags (owner, flags) VALUES(%i,%i)", thisclient->CharInfo->charid, flagid); //Log(MSG_DEBUG,"Ran the questflag deletion query"); flagCount++; } } } //Log(MSG_DEBUG,"%i Quest flags detected during save process",flagCount); }