static int char_sql_saveitem(struct item *item, int max, int id, int tableswitch) { int i; const char *tablename; const char *selectoption; char *p, tmp_sql[65536 * 2]; char sep = ' '; switch (tableswitch) { case TABLE_INVENTORY: tablename = "inventory"; selectoption = "char_id"; break; case TABLE_CART: tablename = "cart_inventory"; selectoption = "char_id"; break; case TABLE_STORAGE: tablename = "storage"; selectoption = "account_id"; break; case TABLE_GUILD_STORAGE: tablename = "guild_storage"; selectoption = "guild_id"; break; default: printf("Invalid table name!\n"); return 1; } // delete sqldbs_query(&mysql_handle, "DELETE FROM `%s` WHERE `%s`='%d'", tablename, selectoption, id); p = tmp_sql; p += sprintf( p,"INSERT INTO `%s`(`id`, `%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, " "`attribute`, `card0`, `card1`, `card2`, `card3`, `limit`, `private`) VALUES",tablename,selectoption ); for(i = 0 ; i < max ; i++) { if(item[i].nameid) { p += sprintf( p,"%c('%u','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%u','%d')", sep,item[i].id,id,item[i].nameid,item[i].amount,item[i].equip,item[i].identify, item[i].refine,item[i].attribute,item[i].card[0],item[i].card[1], item[i].card[2],item[i].card[3],item[i].limit,item[i].private_ ); sep = ','; } } if(sep == ',') { sqldbs_simplequery(&mysql_handle, tmp_sql); } return 0; }
/*========================================== * セーブ *------------------------------------------ */ bool mercdb_sql_save(struct mmo_mercstatus *p2) { char sep = ' '; char tmp_sql[65536]; char *p = tmp_sql; const struct mmo_mercstatus *p1; bool result = false; nullpo_retr(false, p2); p1 = mercdb_sql_load(p2->merc_id); if(p1 == NULL) return false; strcpy(p, "UPDATE `" MERC_TABLE "` SET"); p += strlen(p); UPDATE_NUM(class_ ,"class"); UPDATE_NUM(account_id ,"account_id"); UPDATE_NUM(char_id ,"char_id"); UPDATE_NUM(hp ,"hp"); UPDATE_NUM(sp ,"sp"); UPDATE_NUM(kill_count ,"kill_count"); UPDATE_UNUM(limit ,"limit"); if( sqldbs_transaction_start(&mysql_handle) == false ) return false; // try do { if(sep == ',') { sprintf(p, " WHERE `merc_id` = '%d'",p2->merc_id); if( sqldbs_simplequery(&mysql_handle, tmp_sql) == false ) break; } // success result = true; { // cache copy struct mmo_mercstatus *p3 = (struct mmo_mercstatus *)numdb_search(merc_db, p2->merc_id); if(p3) memcpy(p3, p2, sizeof(struct mmo_mercstatus)); } } while(0); sqldbs_transaction_end(&mysql_handle, result); return result; }
/*========================================== * ロールバック *------------------------------------------ */ bool sqldbs_rollback(struct sqldbs_handle *hd) { nullpo_retr(false, hd); if(--hd->transaction_count > 0) { // transaction is nested return true; } if(hd->transaction_count < 0) { hd->transaction_count = 0; } return sqldbs_simplequery(hd, "ROLLBACK"); }
/*========================================== * コミット *------------------------------------------ */ bool sqldbs_commit(struct sqldbs_handle *hd) { nullpo_retr(false, hd); if(--hd->transaction_count > 0) { // transaction is nested return true; } if(hd->transaction_count < 0) { hd->transaction_count = 0; } return sqldbs_simplequery(hd, "COMMIT"); }
/*========================================== * トランザクションの開始 *------------------------------------------ */ bool sqldbs_transaction_start(struct sqldbs_handle *hd) { nullpo_retr(false, hd); if(hd->transaction_count < 0) { hd->transaction_count = 0; } if(hd->transaction_count++ > 0) { // transaction is nested return true; } return sqldbs_simplequery(hd, "START TRANSACTION"); }
/*========================================== * クエリ発行 *------------------------------------------ */ bool sqldbs_query(struct sqldbs_handle *hd, const char *query, ...) { char sql[65536]; int n; va_list ap; nullpo_retr(false, hd); va_start(ap, query); n = vsnprintf(sql, sizeof(sql) - 1, query, ap); va_end(ap); if(n < 0 || n >= sizeof(sql) - 1) { printf("sqldbs_query: too long query!"); return false; } return sqldbs_simplequery(hd, sql); }
// ホムンクルスデータを書き込み static int homun_tosql(int homun_id, struct mmo_homunstatus *h) { int i; char sep, *p, buf[64]; char tmp_sql[65536]; sqldbs_query(&mysql_handle, "DELETE FROM `homunculus` WHERE `homun_id`='%d'", homun_id); sqldbs_query(&mysql_handle, "INSERT INTO `homunculus` SET `homun_id` = '%d', `class` = '%d', `name` = '%s', `account_id` = '%d', `char_id` = '%d', `base_level` = '%d', `base_exp` = '%d'," "`max_hp` = '%d', `hp` = '%d', `max_sp` = '%d', `sp` = '%d', `str` = '%d', `agi` = '%d',`vit` = '%d',`int` = '%d',`dex` = '%d',`luk` = '%d'," "`f_str` = '%d', `f_agi` = '%d',`f_vit` = '%d',`f_int` = '%d',`f_dex` = '%d',`f_luk` = '%d'," "`status_point` = '%d', `skill_point` = '%d', `equip` = '%d', `intimate` = '%d', `hungry` = '%d', `rename_flag` = '%d', `incubate` = '%d'", homun_id, h->class_, strecpy(buf,h->name), h->account_id , h->char_id, h->base_level, h->base_exp, h->max_hp, h->hp, h->max_sp, h->sp, h->str, h->agi, h->vit, h->int_, h->dex, h->luk, h->f_str, h->f_agi, h->f_vit, h->f_int, h->f_dex, h->f_luk, h->status_point, h->skill_point, h->equip, h->intimate, h->hungry, h->rename_flag, h->incubate ); sqldbs_query(&mysql_handle, "DELETE FROM `homunculus_skill` WHERE `homun_id`='%d'", homun_id); p = tmp_sql; p += sprintf(tmp_sql, "INSERT INTO `homunculus_skill` (`homun_id`,`id`,`lv`) VALUES"); sep = ' '; for(i=0;i<MAX_HOMSKILL;i++) { if(h->skill[i].id && h->skill[i].flag!=1){ int lv = (h->skill[i].flag==0)? h->skill[i].lv: h->skill[i].flag-2; p += sprintf(p,"%c('%d','%d','%d')", sep,homun_id,h->skill[i].id,lv); sep = ','; } } if(sep == ',') { sqldbs_simplequery(&mysql_handle, tmp_sql); } return 0; }
/*========================================== * セーブ *------------------------------------------ */ bool homundb_sql_save(struct mmo_homunstatus *p2) { const struct mmo_homunstatus *p1; char buf[64], tmp_sql[65536]; char sep = ' '; char *p = tmp_sql; bool result = false; nullpo_retr(false, p2); p1 = homundb_sql_load(p2->homun_id); if(p1 == NULL) return 0; strcpy(p, "UPDATE `" HOMUN_TABLE "` SET"); p += strlen(p); UPDATE_NUM(class_ ,"class"); UPDATE_STR(name ,"name"); UPDATE_NUM(account_id ,"account_id"); UPDATE_NUM(char_id ,"char_id"); UPDATE_NUM(base_level ,"base_level"); UPDATE_NUM(base_exp ,"base_exp"); UPDATE_NUM(max_hp ,"max_hp"); UPDATE_NUM(hp ,"hp"); UPDATE_NUM(max_sp ,"max_sp"); UPDATE_NUM(sp ,"sp"); UPDATE_NUM(str ,"str"); UPDATE_NUM(agi ,"agi"); UPDATE_NUM(vit ,"vit"); UPDATE_NUM(int_ ,"int"); UPDATE_NUM(dex ,"dex"); UPDATE_NUM(luk ,"luk"); UPDATE_NUM(f_str ,"f_str"); UPDATE_NUM(f_agi ,"f_agi"); UPDATE_NUM(f_vit ,"f_vit"); UPDATE_NUM(f_int ,"f_int"); UPDATE_NUM(f_dex ,"f_dex"); UPDATE_NUM(f_luk ,"f_luk"); UPDATE_NUM(status_point,"status_point"); UPDATE_NUM(skill_point ,"skill_point"); UPDATE_NUM(equip ,"equip"); UPDATE_NUM(intimate ,"intimate"); UPDATE_NUM(hungry ,"hungry"); UPDATE_NUM(rename_flag ,"rename_flag"); UPDATE_NUM(incubate ,"incubate"); if( sqldbs_transaction_start(&mysql_handle) == false ) return false; // try do { if(sep == ',') { sprintf(p, " WHERE `homun_id` = '%d'", p2->homun_id); if( sqldbs_simplequery(&mysql_handle, tmp_sql) == false ) break; } if(memcmp(p1->skill, p2->skill, sizeof(p1->skill)) ) { int i; if( sqldbs_query(&mysql_handle, "DELETE FROM `" HOMUN_SKILL_TABLE "` WHERE `homun_id`='%d'", p2->homun_id) == false ) break; for(i = 0; i < MAX_HOMSKILL; i++) { if(p2->skill[i].id && p2->skill[i].flag != 1) { int lv = (p2->skill[i].flag == 0)? p2->skill[i].lv: p2->skill[i].flag - 2; if( sqldbs_query(&mysql_handle, "INSERT INTO `" HOMUN_SKILL_TABLE "` (`homun_id`,`id`,`lv`) VALUES ('%d','%d','%d')", p2->homun_id, p2->skill[i].id, lv ) == false ) break; } } if(i != MAX_HOMSKILL) break; } // success result = true; { // cache copy struct mmo_homunstatus *p3 = (struct mmo_homunstatus *)numdb_search(homun_db, p2->homun_id); if(p3) memcpy(p3, p2, sizeof(struct mmo_homunstatus)); } } while(0); sqldbs_transaction_end(&mysql_handle, result); return result; }
// ギルドデータを書き込み static int guild_tosql(struct guild* g) { int i; char buf[256],buf2[256],buf3[256],buf4[256]; char tmp_sql[65536]; char *p = tmp_sql; char sep; // 基本データ sqldbs_query(&mysql_handle, "DELETE FROM `guild` WHERE `guild_id`='%d'", g->guild_id); p += sprintf( tmp_sql,"INSERT INTO `guild` " "(`guild_id`, `name`, `master`, `guild_lv`, `connect_member`, `max_member`, `average_lv`, `exp`," "`next_exp`, `skill_point`, `mes1`, `mes2`, `emblem_len`, `emblem_id`, `emblem_data`) " "VALUES ('%d', '%s', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%s', '%d', '%d', '", g->guild_id, strecpy(buf,g->name), strecpy(buf2,g->master), g->guild_lv, g->connect_member, g->max_member, g->average_lv, g->exp, g->next_exp, g->skill_point, strecpy(buf3,g->mes1), strecpy(buf4,g->mes2), g->emblem_len, g->emblem_id ); for(i=0; i<g->emblem_len; i++) { p += sprintf(p,"%02x",(unsigned char)(g->emblem_data[i])); } p += sprintf(p,"')"); sqldbs_simplequery(&mysql_handle, tmp_sql); // メンバー sqldbs_query(&mysql_handle, "DELETE FROM `guild_member` WHERE `guild_id`='%d'", g->guild_id); p = tmp_sql; p += sprintf( tmp_sql, "INSERT INTO `guild_member` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`," "`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name`) VALUES" ); sep = ' '; for(i=0;i < g->max_member;i++) { if (g->member[i].account_id>0){ struct guild_member *m = &g->member[i]; p += sprintf( p, "%c('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%s')", sep,g->guild_id,m->account_id,m->char_id,m->hair,m->hair_color,m->gender, m->class_,m->lv,m->exp,m->exp_payper,(int)m->online,m->position,strecpy(buf,m->name) ); sep = ','; } } if(sep == ',') { sqldbs_simplequery(&mysql_handle, tmp_sql); } // 役職 sqldbs_query(&mysql_handle, "DELETE FROM `guild_position` WHERE `guild_id`='%d'", g->guild_id); p = tmp_sql; p += sprintf( tmp_sql, "INSERT INTO `guild_position` (`guild_id`,`position`,`name`,`mode`,`exp_mode`) VALUES" ); sep = ' '; for(i=0;i<MAX_GUILDPOSITION;i++){ struct guild_position *pos = &g->position[i]; p += sprintf( p,"%c('%d','%d','%s','%d','%d')", sep, g->guild_id,i,strecpy(buf,pos->name),pos->mode,pos->exp_mode ); sep = ','; } if(sep == ',') { sqldbs_simplequery(&mysql_handle, tmp_sql); } // 同盟リスト sqldbs_query(&mysql_handle, "DELETE FROM `guild_alliance` WHERE `guild_id`='%d'", g->guild_id); p = tmp_sql; p += sprintf( tmp_sql, "INSERT INTO `guild_alliance` (`guild_id`,`opposition`,`alliance_id`,`name`) VALUES" ); sep = ' '; for(i=0;i<MAX_GUILDALLIANCE;i++){ struct guild_alliance *a = &g->alliance[i]; if(a->guild_id>0){ p += sprintf( p, "%c('%d','%d','%d','%s')", sep,g->guild_id,a->opposition,a->guild_id,strecpy(buf,a->name) ); sep = ','; } } if(sep == ',') { sqldbs_simplequery(&mysql_handle, tmp_sql); } // 追放リスト sqldbs_query(&mysql_handle, "DELETE FROM `guild_expulsion` WHERE `guild_id`='%d'", g->guild_id); p = tmp_sql; p += sprintf( tmp_sql, "INSERT INTO `guild_expulsion` (`guild_id`,`name`,`mes`,`account_id`) VALUES" ); sep = ' '; for(i=0;i<MAX_GUILDEXPLUSION;i++) { struct guild_explusion *e = &g->explusion[i]; if(e->account_id>0) { p += sprintf( p,"%c('%d','%s','%s','%d')", sep,g->guild_id,strecpy(buf,e->name),strecpy(buf2,e->mes),e->account_id ); sep = ','; } } if(sep == ',') { sqldbs_simplequery(&mysql_handle, tmp_sql); } // ギルドスキル sqldbs_query(&mysql_handle, "DELETE FROM `guild_skill` WHERE `guild_id`='%d'", g->guild_id); p = tmp_sql; p += sprintf( tmp_sql, "INSERT INTO `guild_skill` (`guild_id`,`id`,`lv`) VALUES" ); sep = ' '; for(i=0;i<MAX_GUILDSKILL;i++) { if (g->skill[i].id > 0) { p += sprintf( p,"%c('%d','%d','%d')", sep,g->guild_id,g->skill[i].id,g->skill[i].lv ); sep = ','; } } if(sep == ',') { sqldbs_simplequery(&mysql_handle, tmp_sql); } return 0; }
// キャラクターデータを書き込み static int mmo_char_tosql(int char_id, struct mmo_charstatus *st) { char sep = ' '; char buf[256]; char *p, tmp_sql[65536]; int i; sqldbs_query(&mysql_handle, "DELETE FROM `char_data` WHERE `char_id`='%d'", char_id); sqldbs_query(&mysql_handle, "INSERT INTO `char_data` SET `char_id` = '%d', `account_id` = '%d', `char_num` = '%d', `name` = '%s', `class` = '%d', `base_level` = '%d', `job_level` = '%d'," "`base_exp` = '%d', `job_exp` = '%d', `zeny` = '%d'," "`max_hp` = '%d', `hp` = '%d', `max_sp` = '%d', `sp` = '%d', `status_point` = '%d', `skill_point` = '%d'," "`str` = '%d', `agi` = '%d', `vit` = '%d', `int` = '%d', `dex` = '%d', `luk` = '%d'," "`option` = '%u', `karma` = '%d', `manner` = '%d', `die_counter` = '%d', `party_id` = '%d', `guild_id` = '%d', `pet_id` = '%d', `homun_id` = '%d', `merc_id` = '%d', `elem_id` = '%d'," "`hair` = '%d', `hair_color` = '%d', `clothes_color` = '%d', `weapon` = '%d', `shield` = '%d', `robe` = '%d', `head_top` = '%d', `head_mid` = '%d', `head_bottom` = '%d'," "`last_map` = '%s', `last_x` = '%d', `last_y` = '%d', `save_map` = '%s', `save_x` = '%d', `save_y` = '%d'," "`partner_id` = '%d', `parent_id` = '%d', `parent_id2` = '%d', `baby_id` = '%d', `delete_date` = '%d', `refuse_partyinvite` = '%d', `show_equip` = '%d', `font` = '%d'", char_id, st->account_id, st->char_num, strecpy(buf,st->name), st->class_ , st->base_level, st->job_level, st->base_exp, st->job_exp, st->zeny, st->max_hp, st->hp, st->max_sp, st->sp, st->status_point, st->skill_point, st->str, st->agi, st->vit, st->int_, st->dex, st->luk, st->option, st->karma, st->manner, st->die_counter, st->party_id, st->guild_id, st->pet_id, st->homun_id, st->merc_id, st->elem_id, st->hair, st->hair_color, st->clothes_color, st->weapon, st->shield, st->robe, st->head_top, st->head_mid, st->head_bottom, st->last_point.map, st->last_point.x, st->last_point.y, st->save_point.map, st->save_point.x, st->save_point.y, st->partner_id, st->parent_id[0], st->parent_id[1], st->baby_id, st->delete_date, st->refuse_partyinvite, st->show_equip, st->font ); // memo sqldbs_query(&mysql_handle, "DELETE FROM `memo` WHERE `char_id`='%d'", char_id); for(i = 0; i < MAX_PORTAL_MEMO; i++) { if(st->memo_point[i].map[0]) { sqldbs_query(&mysql_handle, "INSERT INTO `memo`(`char_id`,`index`,`map`,`x`,`y`) VALUES ('%d', '%d', '%s', '%d', '%d')", char_id, i, strecpy(buf,st->memo_point[i].map), st->memo_point[i].x, st->memo_point[i].y ); } } // inventory char_sql_saveitem(st->inventory, MAX_INVENTORY, st->char_id, TABLE_INVENTORY); // cart char_sql_saveitem(st->cart, MAX_CART, st->char_id, TABLE_CART); // skill sqldbs_query(&mysql_handle, "DELETE FROM `skill` WHERE `char_id`='%d'", char_id); p = tmp_sql; p += sprintf(p,"INSERT INTO `skill` (`char_id`, `id`, `lv`) VALUES"); sep = ' '; for(i=0;i<MAX_PCSKILL;i++){ int sk_lv = (st->skill[i].flag==0)? st->skill[i].lv: st->skill[i].flag-2; if(st->skill[i].id && st->skill[i].flag!=1){ p += sprintf(p,"%c('%d','%d','%d')", sep, char_id, st->skill[i].id, sk_lv); sep = ','; } } if(sep == ',') { sqldbs_simplequery(&mysql_handle, tmp_sql); } // feel_info sqldbs_query(&mysql_handle, "DELETE FROM `feel_info` WHERE `char_id`='%d'", char_id); for(i = 0; i < 3; i++) { if(st->feel_map[i][0]) { sqldbs_query(&mysql_handle, "INSERT INTO `feel_info`(`char_id`,`map`,`lv`) VALUES ('%d', '%s', '%d')", char_id, strecpy(buf,st->feel_map[i]), i ); } } // hotkey sqldbs_query(&mysql_handle, "DELETE FROM `hotkey` WHERE `char_id`='%d'", char_id); for(i = 0; i < MAX_HOTKEYS; i++) { if(st->hotkey[i].id > 0) { sqldbs_query(&mysql_handle, "INSERT INTO `hotkey`(`char_id`,`key`,`type`,`id`,`lv`) VALUES ('%d', '%d', '%d', '%d', '%d')", char_id, i, st->hotkey[i].type, st->hotkey[i].id, st->hotkey[i].lv ); } } // mercenary sqldbs_query(&mysql_handle, "DELETE FROM `mercenary` WHERE `char_id`='%d'", char_id); for(i = 0; i < MAX_MERC_TYPE; i++) { if(st->merc_fame[i] > 0 || st->merc_call[i] > 0) { sqldbs_query(&mysql_handle, "INSERT INTO `mercenary`(`char_id`,`type`,`fame`,`call`) VALUES ('%d', '%d', '%d', '%d')", char_id, i, st->merc_fame[i], st->merc_call[i] ); } } return 0; }