diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 08844be8b3..a1295482be 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,22 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +2006/09/30 + * Rewrote the txt->sql converter. It now links directly to the char server + files so that it should get auto-updated with any code changes in the + later. [Skotlex] + * The converter will now also convert: account-wide variables, parties, + guilds, guild storage and guild castles. At this point the only two things + not converted are login-server-wide account variables (##, they belong to + the login converter) and homunculus (the SQL save function is messy and + doesn't lends itself to be integrated with the converter the way all the + other functions are). [Skotlex] + * misceffect2 will no longer cause the effect on top of the source object + when it is the fake npc. [Skotlex] + * Added check so that Frost Nova doesn't hides hitting animation on + targets. [Skotlex] + * Added the missing brackets around the trade logs condition check, thanks + to Coltaro. [Skotlex] 2006/09/29 * Spurt state will now trigger on Soul Linkers as well. [Skotlex] * Added a check un unit_run when unit_walktoxy fails. Should fix running diff --git a/Makefile b/Makefile index 1b4f6b19ba..14f564e464 100644 --- a/Makefile +++ b/Makefile @@ -192,7 +192,7 @@ depend: src/common/GNUmakefile src/login/GNUmakefile src/login_sql/GNUmakefile \ cd src/map; makedepend -DTXT_ONLY -fGNUmakefile -ptxtobj/ -Y. -Y../common *.c; cd ../..; cd src/map; makedepend -fGNUmakefile -a -psqlobj/ -Y. -Y../common *.c; cd ../..; cd src/ladmin; makedepend -fGNUmakefile -Y. -Y../common *.c; cd ../..; - cd src/txt-converter; makedepend -fGNUmakefile -Y. -Y../common *.c; cd ../..; + cd src/txt-converter; makedepend -DTXT_SQL_CONVERT -fGNUmakefile -Y. -Y../common *.c; cd ../..; $(MAKE) -C src/plugins $@ Makefile.cache: diff --git a/src/char/char.c b/src/char/char.c index 2d7e5af571..691dcf2a41 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -42,7 +42,13 @@ #include "int_status.h" #endif -struct mmo_map_server server[MAX_MAP_SERVERS]; +#ifndef TXT_SQL_CONVERT +struct mmo_map_server{ + long ip; + short port; + int users; + unsigned short map[MAX_MAP_PER_SERVER]; +} server[MAX_MAP_SERVERS]; int server_fd[MAX_MAP_SERVERS]; int login_fd, char_fd; @@ -62,9 +68,11 @@ int char_maintenance; int char_new; int char_new_display; int email_creation = 0; // disabled by default +#endif char char_txt[1024]="save/athena.txt"; char backup_txt[1024]="save/backup.txt"; //By zanetheinsane char friends_txt[1024]="save/friends.txt"; // davidsiaw +#ifndef TXT_SQL_CONVERT char backup_txt_flag = 0; // The backup_txt file was created because char deletion bug existed. Now it's finish and that take a lot of time to create a second file when there are a lot of characters. => option By [Yor] char unknown_char_name[1024] = "Unknown"; char char_log_filename[1024] = "log/char.log"; @@ -107,11 +115,7 @@ int check_ip_flag = 1; // It's to check IP of a player between char-server and o static int online_check = 1; //If one, it won't let players connect when their account is already registered online and will send the relevant map server a kick user request. [Skotlex] int char_id_count = START_CHAR_NUM; -struct character_data { - struct mmo_charstatus status; - int global_num; - struct global_reg global[GLOBAL_REG_NUM]; -} *char_dat; +struct character_data *char_dat; int char_num, char_max; int max_connect_user = 0; @@ -487,7 +491,7 @@ int mmo_char_tostr(char *str, struct mmo_charstatus *p, struct global_reg *reg, *str_p = '\0'; return 0; } - +#endif //TXT_SQL_CONVERT //------------------------------------------------------------------------- // Function to set the character from the line (at read of characters file) //------------------------------------------------------------------------- @@ -701,6 +705,7 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct global_reg *reg p->last_point.map = tmp_int[45]; p->save_point.map = tmp_int[46]; +#ifndef TXT_SQL_CONVERT // Some checks for(i = 0; i < char_num; i++) { if (char_dat[i].status.char_id == p->char_id) { @@ -723,7 +728,7 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct global_reg *reg char_log("mmo_auth_init: ******WARNING: character name has wisp server name: Character name '%s' = wisp server name '%s'." RETCODE, p->name, wisp_server_name); } - +#endif //TXT_SQL_CONVERT if (str[next] == '\n' || str[next] == '\r') return 1; // 新規データ @@ -887,7 +892,7 @@ int parse_friend_txt(struct mmo_charstatus *p) fclose(fp); return count; } - +#ifndef TXT_SQL_CONVERT //--------------------------------- // Function to read characters file //--------------------------------- @@ -1680,7 +1685,7 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) { for(i = found_num; i < 9; i++) sd->found_char[i] = -1; - WFIFOHEAD(fd, offset + found_num * 106); + WFIFOHEAD(fd, offset + found_num * 106); memset(WFIFOP(fd,0), 0, offset + found_num * 106); WFIFOW(fd,0) = 0x6b; WFIFOW(fd,2) = offset + found_num * 106; @@ -4076,6 +4081,7 @@ int char_lan_config_read(const char *lancfgName) { fclose(fp); return 0; } +#endif //TXT_SQL_CONVERT int char_config_read(const char *cfgName) { char line[1024], w1[1024], w2[1024]; @@ -4103,6 +4109,7 @@ int char_config_read(const char *cfgName) { msg_silent = 0; //To always allow the next line to show up. ShowInfo("Console Silent Setting: %d\n", atoi(w2)); msg_silent = atoi(w2); +#ifndef TXT_SQL_CONVERT } else if (strcmpi(w1, "userid") == 0) { strncpy(userid, w2, 24); } else if (strcmpi(w1, "passwd") == 0) { @@ -4149,14 +4156,16 @@ int char_config_read(const char *cfgName) { char_new_display = atoi(w2); } else if (strcmpi(w1, "email_creation") == 0) { email_creation = config_switch(w2); - } else if (strcmpi(w1, "char_txt") == 0) { - strcpy(char_txt, w2); } else if (strcmpi(w1, "scdata_txt") == 0) { //By Skotlex strcpy(scdata_txt, w2); +#endif + } else if (strcmpi(w1, "char_txt") == 0) { + strcpy(char_txt, w2); } else if (strcmpi(w1, "backup_txt") == 0) { //By zanetheinsane strcpy(backup_txt, w2); } else if (strcmpi(w1, "friends_txt") == 0) { //By davidsiaw strcpy(friends_txt, w2); +#ifndef TXT_SQL_CONVERT } else if (strcmpi(w1, "backup_txt_flag") == 0) { // The backup_txt file was created because char deletion bug existed. Now it's finish and that take a lot of time to create a second file when there are a lot of characters. By [Yor] backup_txt_flag = config_switch(w2); } else if (strcmpi(w1, "max_connect_user") == 0) { @@ -4258,6 +4267,7 @@ int char_config_read(const char *cfgName) { } } else if (strcmpi(w1, "guild_exp_rate") == 0) { guild_exp_rate = atoi(w2); +#endif //TXT_SQL_CONVERT } else if (strcmpi(w1, "import") == 0) { char_config_read(w2); } @@ -4268,6 +4278,7 @@ int char_config_read(const char *cfgName) { return 0; } +#ifndef TXT_SQL_CONVERT int chardb_final(int key, void* data, va_list va) { aFree(data); @@ -4379,7 +4390,7 @@ int do_init(int argc, char **argv) { update_online = time(NULL); create_online_files(); // update online players files at start of the server - inter_init((argc > 2) ? argv[2] : inter_cfgName); // inter server 初期化 + inter_init_txt((argc > 2) ? argv[2] : inter_cfgName); // inter server 初期化 set_defaultparse(parse_char); @@ -4411,3 +4422,4 @@ int do_init(int argc, char **argv) { return 0; } +#endif //TXT_SQL_CONVERT diff --git a/src/char/char.h b/src/char/char.h index b6849f80f1..d6ec8e5cbb 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -16,11 +16,10 @@ #define DEFAULT_AUTOSAVE_INTERVAL 300*1000 -struct mmo_map_server{ - long ip; - short port; - int users; - unsigned short map[MAX_MAP_PER_SERVER]; +struct character_data { + struct mmo_charstatus status; + int global_num; + struct global_reg global[GLOBAL_REG_NUM]; }; struct mmo_charstatus* search_character(int aid, int cid); @@ -50,4 +49,10 @@ extern char char_name_letters[]; extern int autosave_interval; extern char db_path[]; extern int guild_exp_rate; +extern int log_inter; +//Exported for use in the TXT-SQL converter. +extern char char_txt[]; +int char_config_read(const char *cfgName); +int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct global_reg *reg, int *reg_num); +int parse_friend_txt(struct mmo_charstatus *p); #endif diff --git a/src/char/int_guild.c b/src/char/int_guild.c index dcb576d860..cb7fa232c5 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -19,6 +19,7 @@ char guild_txt[1024] = "save/guild.txt"; char castle_txt[1024] = "save/castle.txt"; +#ifndef TXT_SQL_CONVERT static struct dbt *guild_db; static struct dbt *castle_db; @@ -95,7 +96,7 @@ int inter_guild_tostr(char *str, struct guild *g) { return 0; } - +#endif //TXT_SQL_CONVERT // ギルドデータの文字列からの変換 int inter_guild_fromstr(char *str, struct guild *g) { int i, j, c; @@ -118,7 +119,9 @@ int inter_guild_fromstr(char *str, struct guild *g) { g->max_member = tmp_int[2]; g->exp = exp; g->skill_point = tmp_int[4]; +#ifndef TXT_SQL_CONVERT g->castle_id = tmp_int[5]; +#endif memcpy(g->name, tmp_str[0], NAME_LENGTH-1); memcpy(g->master, tmp_str[1], NAME_LENGTH-1); memcpy(g->mes1, tmp_str[2], 60); @@ -242,7 +245,7 @@ int inter_guild_fromstr(char *str, struct guild *g) { return 0; } - +#ifndef TXT_SQL_CONVERT // ギルド城データの文字列への変換 int inter_guildcastle_tostr(char *str, struct guild_castle *gc) { int len; @@ -257,7 +260,7 @@ int inter_guildcastle_tostr(char *str, struct guild_castle *gc) { return 0; } - +#endif ///TXT_SQL_CONVERT // ギルド城データの文字列からの変換 int inter_guildcastle_fromstr(char *str, struct guild_castle *gc) { int tmp_int[26]; @@ -334,7 +337,7 @@ int inter_guildcastle_fromstr(char *str, struct guild_castle *gc) { return 0; } - +#ifndef TXT_SQL_CONVERT // ギルド関連データベース読み込み int inter_guild_readdb(void) { int i; @@ -1560,3 +1563,4 @@ int inter_guild_mapif_init(int fd) { int inter_guild_leave(int guild_id, int account_id, int char_id) { return mapif_parse_GuildLeave(-1, guild_id, account_id, char_id, 0, "** Character Deleted **"); } +#endif //TXT_SQL_CONVERT diff --git a/src/char/int_guild.h b/src/char/int_guild.h index 0b0105af31..2cd26a516e 100644 --- a/src/char/int_guild.h +++ b/src/char/int_guild.h @@ -16,4 +16,7 @@ int inter_guild_sex_changed(int guild_id,int account_id,int char_id, int gender) extern char guild_txt[1024]; extern char castle_txt[1024]; +//For the TXT->SQL converter +int inter_guild_fromstr(char *str, struct guild *g); +int inter_guildcastle_fromstr(char *str, struct guild_castle *gc); #endif diff --git a/src/char/int_party.c b/src/char/int_party.c index e80a5de630..cae69193f1 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -16,7 +16,7 @@ #include "int_party.h" char party_txt[1024] = "save/party.txt"; - +#ifndef TXT_SQL_CONVERT struct party_data { struct party party; unsigned int min_lv, max_lv; @@ -107,13 +107,15 @@ int inter_party_tostr(char *str, struct party *p) { return 0; } - +#endif //TXT_SQL_CONVERT // パ?ティデ?タの文字列からの?換 int inter_party_fromstr(char *str, struct party *p) { int i, j; int tmp_int[16]; char tmp_str[256]; +#ifndef TXT_SQL_CONVERT struct mmo_charstatus* status; +#endif memset(p, 0, sizeof(struct party)); @@ -144,7 +146,7 @@ int inter_party_fromstr(char *str, struct party *p) { m->leader = tmp_int[2]?1:0; str = strchr(str + 1, '\t'); - +#ifndef TXT_SQL_CONVERT if (!m->account_id) continue; //Lookup player for rest of data. status = search_character(m->account_id, m->char_id); @@ -154,11 +156,12 @@ int inter_party_fromstr(char *str, struct party *p) { m->class_ = status->class_; m->map = status->last_point.map; m->lv = status->base_level; +#endif //TXT_SQL_CONVERT } return 0; } - +#ifndef TXT_SQL_CONVERT // パ?ティデ?タのロ?ド int inter_party_init() { char line[8192]; @@ -736,4 +739,4 @@ int inter_party_parse_frommap(int fd) { int inter_party_leave(int party_id, int account_id, int char_id) { return mapif_parse_PartyLeave(-1, party_id, account_id, char_id); } - +#endif //TXT_SQL_CONVERT diff --git a/src/char/int_party.h b/src/char/int_party.h index 8b54948b06..5c2fbefb18 100644 --- a/src/char/int_party.h +++ b/src/char/int_party.h @@ -15,4 +15,6 @@ int inter_party_logged(int party_id, int account_id, int char_id); extern char party_txt[1024]; +//For the TXT->SQL converter +int inter_party_fromstr(char *str, struct party *p); #endif diff --git a/src/char/int_pet.c b/src/char/int_pet.c index 53a2223936..6e1b8ad831 100644 --- a/src/char/int_pet.c +++ b/src/char/int_pet.c @@ -16,6 +16,7 @@ char pet_txt[1024]="save/pet.txt"; +#ifndef TXT_SQL_CONVERT static struct dbt *pet_db; static int pet_newid = 100; @@ -38,7 +39,7 @@ int inter_pet_tostr(char *str,struct s_pet *p) return 0; } - +#endif //TXT_SQL_CONVERT int inter_pet_fromstr(char *str,struct s_pet *p) { int s; @@ -78,7 +79,7 @@ int inter_pet_fromstr(char *str,struct s_pet *p) return 0; } - +#ifndef TXT_SQL_CONVERT int inter_pet_init() { char line[8192]; @@ -416,4 +417,4 @@ int inter_pet_parse_frommap(int fd) } return 1; } - +#endif //TXT_SQL_CONVERT diff --git a/src/char/int_pet.h b/src/char/int_pet.h index 0495994fe9..31489579f8 100644 --- a/src/char/int_pet.h +++ b/src/char/int_pet.h @@ -13,4 +13,6 @@ int inter_pet_parse_frommap(int fd); extern char pet_txt[1024]; +//Exported for use in the TXT-SQL converter. +int inter_pet_fromstr(char *str,struct s_pet *p); #endif diff --git a/src/char/int_storage.c b/src/char/int_storage.c index f8ae42c0ff..89e9a540a3 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -20,6 +20,7 @@ char storage_txt[1024]="save/storage.txt"; char guild_storage_txt[1024]="save/g_storage.txt"; +#ifndef TXT_SQL_CONVERT static struct dbt *storage_db; static struct dbt *guild_storage_db; @@ -48,7 +49,7 @@ int storage_tostr(char *str,struct storage *p) str[0]=0; return 0; } - +#endif //TXT_SQL_CONVERT // 文字列を倉庫データに変換 int storage_fromstr(char *str,struct storage *p) { @@ -89,7 +90,7 @@ int storage_fromstr(char *str,struct storage *p) ShowWarning("storage_fromstr: Found a storage line with more items than MAX_STORAGE (%d), remaining items have been discarded!\n", MAX_STORAGE); return 0; } - +#ifndef TXT_SQL_CONVERT int guild_storage_tostr(char *str,struct guild_storage *p) { int i,j,f=0; @@ -114,7 +115,7 @@ int guild_storage_tostr(char *str,struct guild_storage *p) str[0]=0; return 0; } - +#endif //TXT_SQL_CONVERT int guild_storage_fromstr(char *str,struct guild_storage *p) { int tmp_int[256]; @@ -153,7 +154,7 @@ int guild_storage_fromstr(char *str,struct guild_storage *p) ShowWarning("guild_storage_fromstr: Found a storage line with more items than MAX_GUILD_STORAGE (%d), remaining items have been discarded!\n", MAX_GUILD_STORAGE); return 0; } - +#ifndef TXT_SQL_CONVERT static void* create_storage(DBKey key, va_list args) { struct storage *s; s = (struct storage *) aCalloc(sizeof(struct storage), 1); @@ -474,3 +475,4 @@ int inter_storage_parse_frommap(int fd) } return 1; } +#endif //TXT_SQL_CONVERT diff --git a/src/char/int_storage.h b/src/char/int_storage.h index 678312b1dd..c15af003ed 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -16,4 +16,7 @@ int inter_storage_parse_frommap(int fd); extern char storage_txt[1024]; extern char guild_storage_txt[1024]; +//Exported for use in the TXT-SQL converter. +int storage_fromstr(char *str,struct storage *p); +int guild_storage_fromstr(char *str,struct guild_storage *p); #endif diff --git a/src/char/inter.c b/src/char/inter.c index 8127a60a47..17b8ddc567 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -25,18 +25,13 @@ // that is the waiting time of answers of all map-servers #define WISDELLIST_MAX 256 // Number of elements of Wisp/page data deletion list +char accreg_txt[1024] = "save/accreg.txt"; +#ifndef TXT_SQL_CONVERT char inter_log_filename[1024] = "log/inter.log"; char main_chat_nick[16] = "Main"; -char accreg_txt[1024] = "save/accreg.txt"; static struct dbt *accreg_db = NULL; -struct accreg { - int account_id, char_id; - int reg_num; - struct global_reg reg[ACCOUNT_REG_NUM]; -}; - unsigned int party_share_level = 10; // sending packet list @@ -89,7 +84,7 @@ int inter_accreg_tostr(char *str, struct accreg *reg) { return 0; } - +#endif //TXT_SQL_CONVERT // アカウント変数を文字列から変換 int inter_accreg_fromstr(const char *str, struct accreg *reg) { int j, n; @@ -106,7 +101,7 @@ int inter_accreg_fromstr(const char *str, struct accreg *reg) { return 0; } - +#ifndef TXT_SQL_CONVERT // アカウント変数の読み込み int inter_accreg_init(void) { char line[8192]; @@ -172,12 +167,12 @@ int inter_accreg_save(void) { } //-------------------------------------------------------- - +#endif //TXT_SQL_CONVERT /*========================================== * 設定ファイルを読み込む *------------------------------------------ */ -int inter_config_read(const char *cfgName) { +static int inter_config_read(const char *cfgName) { char line[1024], w1[1024], w2[1024]; FILE *fp; @@ -198,18 +193,19 @@ int inter_config_read(const char *cfgName) { strncpy(storage_txt, w2, sizeof(storage_txt)); } else if (strcmpi(w1, "party_txt") == 0) { strncpy(party_txt, w2, sizeof(party_txt)); - } else if (strcmpi(w1, "guild_txt") == 0) { - strncpy(guild_txt, w2, sizeof(guild_txt)); } else if (strcmpi(w1, "pet_txt") == 0) { strncpy(pet_txt, w2, sizeof(pet_txt)); - } else if (strcmpi(w1, "homun_txt") == 0) { - strncpy(homun_txt, w2, sizeof(homun_txt)); - } else if (strcmpi(w1, "castle_txt") == 0) { - strncpy(castle_txt, w2, sizeof(castle_txt)); } else if (strcmpi(w1, "accreg_txt") == 0) { strncpy(accreg_txt, w2, sizeof(accreg_txt)); + } else if (strcmpi(w1, "guild_txt") == 0) { + strncpy(guild_txt, w2, sizeof(guild_txt)); + } else if (strcmpi(w1, "castle_txt") == 0) { + strncpy(castle_txt, w2, sizeof(castle_txt)); } else if (strcmpi(w1, "guild_storage_txt") == 0) { strncpy(guild_storage_txt, w2, sizeof(guild_storage_txt)); +#ifndef TXT_SQL_CONVERT + } else if (strcmpi(w1, "homun_txt") == 0) { + strncpy(homun_txt, w2, sizeof(homun_txt)); } else if (strcmpi(w1, "party_share_level") == 0) { party_share_level = (unsigned int)atof(w2); } else if (strcmpi(w1, "inter_log_filename") == 0) { @@ -217,7 +213,8 @@ int inter_config_read(const char *cfgName) { } else if(strcmpi(w1,"log_inter")==0) { log_inter = atoi(w2); } else if(strcmpi(w1, "main_chat_nick")==0){ // Main chat nick [LuzZza] - strcpy(main_chat_nick, w2); // + strcpy(main_chat_nick, w2); +#endif //TXT_SQL_CONVERT } else if (strcmpi(w1, "import") == 0) { inter_config_read(w2); } @@ -226,7 +223,7 @@ int inter_config_read(const char *cfgName) { return 0; } - +#ifndef TXT_SQL_CONVERT // ログ書き出し int inter_log(char *fmt,...) { FILE *logfp; @@ -258,11 +255,12 @@ int inter_save(void) { return 0; } - +#endif //TXT_SQL_CONVERT // 初期化 -int inter_init(const char *file) { +int inter_init_txt(const char *file) { inter_config_read(file); +#ifndef TXT_SQL_CONVERT wis_db = db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int)); inter_party_init(); @@ -271,10 +269,10 @@ int inter_init(const char *file) { inter_pet_init(); inter_homun_init(); inter_accreg_init(); - +#endif //TXT_SQL_CONVERT return 0; } - +#ifndef TXT_SQL_CONVERT // finalize void inter_final(void) { accreg_db->destroy(accreg_db, NULL); @@ -690,4 +688,4 @@ int inter_check_length(int fd, int length) { return length; } - +#endif //TXT_SQL_CONVERT diff --git a/src/char/inter.h b/src/char/inter.h index 7f9ed0a641..75489c3877 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -4,7 +4,7 @@ #ifndef _INTER_H_ #define _INTER_H_ -int inter_init(const char *file); +int inter_init_txt(const char *file); void inter_final(void); int inter_save(void); int inter_parse_frommap(int fd); @@ -20,8 +20,9 @@ int inter_log(char *fmt,...); extern unsigned int party_share_level; extern char inter_log_filename[1024]; -extern int log_inter; - extern char main_chat_nick[16]; +//For TXT->SQL conversion +extern char accreg_txt[]; +int inter_accreg_fromstr(const char *str, struct accreg *reg); #endif diff --git a/src/char_sql/char.c b/src/char_sql/char.c index df1ed6b2e8..affdd3a62a 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -33,8 +33,9 @@ #include "malloc.h" #include "int_guild.h" +#ifndef TXT_SQL_CONVERT static struct dbt *char_db_; - +#endif char char_db[256] = "char"; char scdata_db[256] = "sc_data"; char cart_db[256] = "cart_inventory"; @@ -57,6 +58,10 @@ char party_db[256] = "party"; char pet_db[256] = "pet"; char gm_db[256] = "gm_accounts"; char friend_db[256] = "friends"; +#ifdef TXT_SQL_CONVERT +int save_log = 0; //Have the logs be off by default when converting +#else +int save_log = 1; int db_use_sqldbs; int connection_ping_interval = 0; @@ -67,7 +72,13 @@ int lowest_gm_level = 1; char *SQL_CONF_NAME = "conf/inter_athena.conf"; -struct mmo_map_server server[MAX_MAP_SERVERS]; +struct mmo_map_server{ + long ip; + short port; + int users; + unsigned short map[MAX_MAP_PER_SERVER]; +} server[MAX_MAP_SERVERS]; + int server_fd[MAX_MAP_SERVERS]; int login_fd, char_fd; @@ -135,7 +146,6 @@ int char_num,char_max; int max_connect_user = 0; int gm_allow_level = 99; int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; -int save_log = 1; int start_zeny = 0; int start_weapon = 1201; int start_armor = 2301; @@ -385,7 +395,7 @@ void read_gm_account(void) { mysql_free_result(lsql_res); mapif_send_gmaccounts(); } - +#endif //TXT_SQL_CONVERT int compare_item(struct item *a, struct item *b) { if(a->id == b->id && @@ -403,13 +413,14 @@ int compare_item(struct item *a, struct item *b) { return 0; } +#ifndef TXT_SQL_CONVERT static void* create_charstatus(DBKey key, va_list args) { struct mmo_charstatus *cp; cp = (struct mmo_charstatus *) aCalloc(1,sizeof(struct mmo_charstatus)); cp->char_id = key.i; return cp; } - +#endif //TXT_SQL_CONVERT int mmo_char_tosql(int char_id, struct mmo_charstatus *p){ int i=0,j; int count = 0; @@ -422,7 +433,11 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){ if (char_id!=p->char_id) return 0; +#ifndef TXT_SQL_CONVERT cp = idb_ensure(char_db_, char_id, create_charstatus); +#else + cp = aCalloc(1, sizeof(struct mmo_charstatus)); +#endif memset(save_status, 0, sizeof(save_status)); diff = 0; @@ -474,6 +489,17 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){ if (diff) if (!memitemdata_to_sql(mapitem, count, p->char_id,TABLE_CART)) strcat(save_status, " cart"); +#ifdef TXT_SQL_CONVERT + //Insert the barebones to then update the rest. + sprintf(tmp_sql, "REPLACE INTO `%s` (`account_id`, `char_num`, `name`) VALUES ('%d', '%d', '%s')", + char_db, p->account_id, p->char_num, p->name); + if(mysql_query(&mysql_handle, tmp_sql)) + { + ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); + ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); + } else + strcat(save_status, " creation"); +#endif if ( (p->base_exp != cp->base_exp) || (p->base_level != cp->base_level) || @@ -640,71 +666,6 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){ } else //Skills removed (reset?) strcat(save_status, " skills"); } -/* Saving of global registry values is now handled by the inter-server. [Skotlex] - diff = 0; - for(i=0;iglobal_reg_num;i++) { - if ((p->global_reg[i].str == NULL) && (cp->global_reg[i].str == NULL)) - continue; - if (((p->global_reg[i].str == NULL) != (cp->global_reg[i].str == NULL)) || - strcmp(p->global_reg[i].value, cp->global_reg[i].value) != 0 || - strcmp(p->global_reg[i].str, cp->global_reg[i].str) != 0 - ) { - diff = 1; - break; - } - } - - if (diff) - { //Save global registry. - //`global_reg_value` (`char_id`, `str`, `value`) - - sprintf(tmp_sql,"DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'",reg_db, p->char_id); - if (mysql_query(&mysql_handle, tmp_sql)) - { - ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); - ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); - } - - //insert here. - tmp_ptr = tmp_sql; - tmp_ptr += sprintf(tmp_ptr,"INSERT INTO `%s` (`type`, `char_id`, `str`, `value`) VALUES", reg_db); - count = 0; - for(i=0;iglobal_reg_num;i++) - { - if (p->global_reg[i].str && p->global_reg[i].value) - { - tmp_ptr += sprintf(tmp_ptr,"('3','%d','%s','%s'),", - char_id, jstrescapecpy(temp_str,p->global_reg[i].str), jstrescapecpy(temp_str2,p->global_reg[i].value)); - if (++count%100 == 0) - { //Save every X registers to avoid overflowing tmp_sql [Skotlex] - tmp_ptr[-1] = '\0'; - if(mysql_query(&mysql_handle, tmp_sql)) - { - ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); - ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); - } else - strcat(save_status, " global_reg"); - - tmp_ptr = tmp_sql; - tmp_ptr += sprintf(tmp_ptr,"INSERT INTO `%s` (`type`, `char_id`, `str`, `value`) VALUES", reg_db); - count = 0; - } - } - } - - if (count) - { - tmp_ptr[-1] = '\0'; - if(mysql_query(&mysql_handle, tmp_sql)) - { - ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); - ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); - } else - strcat(save_status, " global_reg"); - } else //Values cleared. - strcat(save_status, " global_reg"); - } -*/ diff = 0; for(i = 0; i < MAX_FRIENDS; i++){ if(p->friends[i].char_id != cp->friends[i].char_id || @@ -748,8 +709,11 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){ if (save_status[0]!='\0' && save_log) ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status); +#ifndef TXT_SQL_CONVERT memcpy(cp, p, sizeof(struct mmo_charstatus)); - +#else + aFree(cp); +#endif return 0; } @@ -820,6 +784,7 @@ int memitemdata_to_sql(struct itemtmp mapitem[], int count, int char_id, int tab { //Do nothing. } else //==============================================Memory data > SQL =============================== +#ifndef TXT_SQL_CONVERT if(!itemdb_isequip(mapitem[i].nameid)) { //Quick update of stackable items. Update Qty and Equip should be enough, but in case we are also updating identify sprintf(tmp_sql,"UPDATE `%s` SET `equip`='%d', `identify`='%d', `amount`='%d' WHERE `id`='%d' LIMIT 1", @@ -830,6 +795,7 @@ int memitemdata_to_sql(struct itemtmp mapitem[], int count, int char_id, int tab ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); } } else +#endif //TXT_SQL_CONVERT { //Equipment or Misc item, just update all fields. str_p = tmp_sql; str_p += sprintf(str_p,"UPDATE `%s` SET `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d'", @@ -888,7 +854,7 @@ int memitemdata_to_sql(struct itemtmp mapitem[], int count, int char_id, int tab } return 0; } - +#ifndef TXT_SQL_CONVERT //===================================================================================================== int mmo_char_fromsql(int char_id, struct mmo_charstatus *p){ int i,j, n; @@ -1690,19 +1656,6 @@ int delete_char_sql(int char_id, int partner_id) //========================================================================================================== -void mmo_char_sync(void) -{ - ShowWarning("mmo_char_sync() - nothing to do\n"); -} - -// to do -/////////////////////////// - -int mmo_char_sync_timer(int tid, unsigned int tick, int id, int data) { - ShowWarning("mmo_char_sync_timer() tic - no works to do\n"); - return 0; -} - int count_users(void) { int i, users; @@ -3918,7 +3871,6 @@ int char_lan_config_read(const char *lancfgName) { void do_final(void) { ShowInfo("Doing final stage...\n"); - //mmo_char_sync(); //inter_save(); do_final_itemdb(); //check SQL save progress. @@ -3956,7 +3908,7 @@ void do_final(void) { ShowInfo("ok! all done...\n"); } - +#endif //TXT_SQL_CONVERT void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */ char line[1024], w1[1024], w2[1024]; FILE *fp; @@ -3975,15 +3927,17 @@ void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */ if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2) continue; - if(strcmpi(w1, "gm_read_method") == 0) { + if(strcmpi(w1,"char_db")==0){ + strcpy(char_db,w2); +#ifndef TXT_SQL_CONVERT + } else if(strcmpi(w1, "gm_read_method") == 0) { if(atoi(w2) != 0) char_gm_read = true; else char_gm_read = false; } else if(strcmpi(w1, "gm_db") == 0) { strcpy(gm_db, w2); - } else if(strcmpi(w1,"char_db")==0){ - strcpy(char_db,w2); +#endif }else if(strcmpi(w1,"scdata_db")==0){ strcpy(scdata_db,w2); }else if(strcmpi(w1,"cart_db")==0){ @@ -4024,6 +3978,7 @@ void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */ strcpy(pet_db,w2); }else if(strcmpi(w1,"friend_db")==0){ strcpy(friend_db,w2); +#ifndef TXT_SQL_CONVERT }else if(strcmpi(w1,"db_path")==0){ strcpy(db_path,w2); //Map server option to use SQL db or not @@ -4045,6 +4000,7 @@ void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */ lowest_gm_level = atoi(w2); ShowStatus("set lowest_gm_level : %s\n",w2); //support the import command, just like any other config +#endif }else if(strcmpi(w1,"import")==0){ sql_config_read(w2); } @@ -4053,6 +4009,7 @@ void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */ fclose(fp); ShowInfo("done reading %s.\n", cfgName); } +#ifndef TXT_SQL_CONVERT int char_config_read(const char *cfgName) { char line[1024], w1[1024], w2[1024]; @@ -4263,7 +4220,7 @@ int do_init(int argc, char **argv){ ShowInfo("Finished reading the char-server configuration.\n"); - inter_init((argc > 2) ? argv[2] : inter_cfgName); // inter server テハア篳ュ + inter_init_sql((argc > 2) ? argv[2] : inter_cfgName); // inter server テハア篳ュ ShowInfo("Finished reading the inter-server configuration.\n"); //Read ItemDB @@ -4453,3 +4410,4 @@ int char_family(int pl1,int pl2,int pl3) { mysql_free_result (sql_res); return 0; } +#endif //TXT_SQL_CONVERT diff --git a/src/char_sql/char.h b/src/char_sql/char.h index 343d04b4e4..70d8e3b134 100644 --- a/src/char_sql/char.h +++ b/src/char_sql/char.h @@ -1,5 +1,7 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder +#ifndef _CHARSQL_H_ +#define _CHARSQL_H_ #include "../common/core.h" #include "../common/socket.h" @@ -9,8 +11,12 @@ #include "../common/db.h" #include "../common/mapindex.h" -#ifndef _CHAR_H_ -#define _CHAR_H_ +#include "inter.h" +#include "int_pet.h" +#include "int_guild.h" +#include "int_party.h" +#include "int_storage.h" +#include "itemdb.h" #define START_CHAR_NUM 150000 #define MAX_MAP_SERVERS 30 @@ -19,12 +25,6 @@ #define DEFAULT_AUTOSAVE_INTERVAL 300*1000 -struct mmo_map_server{ - long ip; - short port; - int users; - unsigned short map[MAX_MAP_PER_SERVER]; -}; struct itemtmp { int flag;//checked = 1 else 0 int id; @@ -100,13 +100,11 @@ extern int GM_num; extern struct gm_account *gm_account; extern int guild_exp_rate; +extern int log_inter; extern int debug_mysql_query(char *file, int line, void *mysql, const char *q); +//Exported for use in the TXT-SQL converter. +int mmo_char_tosql(int char_id, struct mmo_charstatus *p); +void sql_config_read(const char *cfgName); #endif - -#include "inter.h" -#include "int_pet.h" -#include "int_guild.h" -#include "int_party.h" -#include "int_storage.h" diff --git a/src/char_sql/int_guild.c b/src/char_sql/int_guild.c index af302346bb..8f9e50acf9 100644 --- a/src/char_sql/int_guild.c +++ b/src/char_sql/int_guild.c @@ -20,27 +20,6 @@ #include "db.h" #include "malloc.h" -//Guild cache -static struct dbt *guild_db_; - -struct guild_castle castles[MAX_GUILDCASTLE]; - -static unsigned int guild_exp[100]; - -#define GS_BASIC 0x0001 -#define GS_MEMBER 0x0002 -#define GS_POSITION 0x0004 -#define GS_ALLIANCE 0x0008 -#define GS_EXPULSION 0x0010 -#define GS_SKILL 0x0020 -#define GS_EMBLEM 0x0040 -#define GS_CONNECT 0x0080 -#define GS_LEVEL 0x0100 -#define GS_MES 0x0200 -#define GS_MASK 0x03FF -#define GS_BASIC_MASK (GS_BASIC | GS_EMBLEM | GS_CONNECT | GS_LEVEL | GS_MES) -#define GS_REMOVE 0x8000 - #define GS_MEMBER_UNMODIFIED 0x00 #define GS_MEMBER_MODIFIED 0x01 #define GS_MEMBER_NEW 0x02 @@ -52,6 +31,16 @@ static unsigned int guild_exp[100]; #define GUILD_ALLIANCE_TYPE_MASK 0x01 #define GUILD_ALLIANCE_REMOVE 0x08 +static char dataToHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + +#ifndef TXT_SQL_CONVERT +//Guild cache +static struct dbt *guild_db_; + +struct guild_castle castles[MAX_GUILDCASTLE]; + +static unsigned int guild_exp[100]; + int mapif_parse_GuildLeave(int fd,int guild_id,int account_id,int char_id,int flag,const char *mes); int mapif_guild_broken(int guild_id,int flag); int guild_check_empty(struct guild *g); @@ -60,7 +49,6 @@ int mapif_guild_basicinfochanged(int guild_id,int type,const void *data,int len) int mapif_guild_info(int fd,struct guild *g); int guild_break_sub(int key,void *data,va_list ap); int inter_guild_tosql(struct guild *g,int flag); -static char dataToHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; #define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y) @@ -119,7 +107,7 @@ int inter_guild_removemember_tosql(int account_id, int char_id) } return 0; } - +#endif //TXT_SQL_CONVERT // Save guild into sql int inter_guild_tosql(struct guild *g,int flag) { @@ -162,6 +150,7 @@ int inter_guild_tosql(struct guild *g,int flag) t_info[0]='\0'; +#ifndef TXT_SQL_CONVERT // Insert a new guild the guild if (flag&GS_BASIC && g->guild_id == -1) { @@ -191,7 +180,31 @@ int inter_guild_tosql(struct guild *g,int flag) return 0; //Failed to get ID?? } } - +#else + // Insert a new guild the guild + if (flag&GS_BASIC) + { + strcat(t_info, " guild_create"); + // Since the PK is guild id + master id, a replace will not be enough if we are overwriting data, we need to wipe the previous guild. + sprintf(tmp_sql,"DELETE FROM `%s` where `guild_id` = '%d'", guild_db,g->guild_id); + if(mysql_query(&mysql_handle, tmp_sql) ) + { + ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); + ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); + } + // Create a new guild + sprintf(tmp_sql,"REPLACE INTO `%s` " + "(`guild_id`,`name`,`master`,`guild_lv`,`max_member`,`average_lv`,`char_id`) " + "VALUES ('%d', '%s', '%s', '%d', '%d', '%d', '%d')", + guild_db,g->guild_id,t_name,jstrescapecpy(t_master,g->master),g->guild_lv,g->max_member,g->average_lv,g->member[0].char_id); + if(mysql_query(&mysql_handle, tmp_sql) ) + { + ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); + ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); + return 0; //Failed to create guild. + } + } +#endif //TXT_SQL_CONVERT // If we need an update on an existing guild or more update on the new guild if (((flag & GS_BASIC_MASK) && !new_guild) || ((flag & (GS_BASIC_MASK & ~GS_BASIC)) && new_guild)) { @@ -244,8 +257,10 @@ int inter_guild_tosql(struct guild *g,int flag) // Update only needed players for(i=0;imax_member;i++){ m = &g->member[i]; +#ifndef TXT_SQL_CONVERT if (!m->modified) continue; +#endif if(m->account_id) { //Since nothing references guild member table as foreign keys, it's safe to use REPLACE INTO sprintf(tmp_sql,"REPLACE INTO `%s` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name`) " @@ -279,8 +294,10 @@ int inter_guild_tosql(struct guild *g,int flag) //printf("- Insert guild %d to guild_position\n",g->guild_id); for(i=0;iposition[i]; +#ifndef TXT_SQL_CONVERT if (!p->modified) continue; +#endif sprintf(tmp_sql,"REPLACE INTO `%s` (`guild_id`,`position`,`name`,`mode`,`exp_mode`) VALUES ('%d','%d', '%s','%d','%d')", guild_position_db, g->guild_id, i, jstrescapecpy(t_position,p->name),p->mode,p->exp_mode); //printf(" %s\n",tmp_sql); @@ -366,7 +383,7 @@ int inter_guild_tosql(struct guild *g,int flag) ShowInfo("Saved guild (%d - %s):%s\n",g->guild_id,g->name,t_info); return 1; } - +#ifndef TXT_SQL_CONVERT // Read guild from sql struct guild * inter_guild_fromsql(int guild_id) { @@ -582,6 +599,7 @@ struct guild * inter_guild_fromsql(int guild_id) return g; } +#endif //TXT_SQL_CONVERT int inter_guildcastle_tosql(struct guild_castle *gc){ // `guild_castle` (`castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`) @@ -607,12 +625,12 @@ ShowDebug("Save guild_castle (%d)\n", gc->castle_id); ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); } - +#ifndef TXT_SQL_CONVERT memcpy(&castles[gc->castle_id],gc,sizeof(struct guild_castle)); - +#endif //TXT_SQL_CONVERT return 0; } - +#ifndef TXT_SQL_CONVERT // Read guild_castle from sql int inter_guildcastle_fromsql(int castle_id,struct guild_castle *gc) @@ -2083,3 +2101,4 @@ int inter_guild_broken(int guild_id) { return mapif_guild_broken(guild_id, 0); } +#endif //TXT_SQL_CONVERT diff --git a/src/char_sql/int_guild.h b/src/char_sql/int_guild.h index 6faf4e2b1d..88836a2a19 100644 --- a/src/char_sql/int_guild.h +++ b/src/char_sql/int_guild.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_GUILD_H_ -#define _INT_GUILD_H_ +#ifndef _INT_GUILD_SQL_H_ +#define _INT_GUILD_SQL_H_ int inter_guild_parse_frommap(int fd); int inter_guild_sql_init(void); @@ -15,4 +15,21 @@ int inter_guild_sex_changed(int guild_id,int account_id,int char_id, int gender) int inter_guild_CharOnline(int char_id, int guild_id); int inter_guild_CharOffline(int char_id, int guild_id); +#define GS_BASIC 0x0001 +#define GS_MEMBER 0x0002 +#define GS_POSITION 0x0004 +#define GS_ALLIANCE 0x0008 +#define GS_EXPULSION 0x0010 +#define GS_SKILL 0x0020 +#define GS_EMBLEM 0x0040 +#define GS_CONNECT 0x0080 +#define GS_LEVEL 0x0100 +#define GS_MES 0x0200 +#define GS_MASK 0x03FF +#define GS_BASIC_MASK (GS_BASIC | GS_EMBLEM | GS_CONNECT | GS_LEVEL | GS_MES) +#define GS_REMOVE 0x8000 + +//For the TXT->SQL converter. +int inter_guild_tosql(struct guild *g,int flag); +int inter_guildcastle_tosql(struct guild_castle *gc); #endif diff --git a/src/char_sql/int_party.c b/src/char_sql/int_party.c index 897a110d6d..fe46ac9c6c 100644 --- a/src/char_sql/int_party.c +++ b/src/char_sql/int_party.c @@ -14,6 +14,7 @@ #include "../common/socket.h" #include "../common/showmsg.h" +#ifndef TXT_SQL_CONVERT struct party_data { struct party party; unsigned int min_lv, max_lv; @@ -40,20 +41,6 @@ int mapif_party_optionchanged(int fd,struct party *p, int account_id, int flag); #endif -//Party Flags on what to save/delete. -//Create a new party entry (index holds leader's info) -#define PS_CREATE 0x01 -//Update basic party info. -#define PS_BASIC 0x02 -//Update party's leader -#define PS_LEADER 0x04 -//Specify new party member (index specifies which party member) -#define PS_ADDMEMBER 0x08 -//Specify member that left (index specifies which party member) -#define PS_DELMEMBER 0x10 -//Specify that this party must be deleted. -#define PS_BREAK 0x20 - //Updates party's level range and unsets even share if broken. static int int_party_check_lv(struct party_data *p) { int i; @@ -114,17 +101,15 @@ static void int_party_calc_state(struct party_data *p) } return; } - +#endif //TXT_SQL_CONVERT // Save party to mysql -int inter_party_tosql(struct party_data *party, int flag, int index) +int inter_party_tosql(struct party *p, int flag, int index) { // 'party' ('party_id','name','exp','item','leader_id','leader_char') char t_name[NAME_LENGTH*2]; //Required for jstrescapecpy [Skotlex] - struct party *p; int party_id; - if (party == NULL || party->party.party_id == 0) + if (p == NULL || p->party_id == 0) return 0; - p = &party->party; party_id = p->party_id; #ifdef NOISY @@ -132,6 +117,7 @@ int inter_party_tosql(struct party_data *party, int flag, int index) #endif jstrescapecpy(t_name, p->name); +#ifndef TXT_SQL_CONVERT if (flag&PS_BREAK) { //Break the party // we'll skip name-checking and just reset everyone with the same party id [celest] sprintf (tmp_sql, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id); @@ -148,8 +134,9 @@ int inter_party_tosql(struct party_data *party, int flag, int index) idb_remove(party_db_, party_id); return 1; } - +#endif //TXT_SQL_CONVERT if(flag&PS_CREATE) { //Create party +#ifndef TXT_SQL_CONVERT sprintf(tmp_sql, "INSERT INTO `%s` " "(`name`, `exp`, `item`, `leader_id`, `leader_char`) " "VALUES ('%s', '%d', '%d', '%d', '%d')", @@ -157,21 +144,29 @@ int inter_party_tosql(struct party_data *party, int flag, int index) if (mysql_query(&mysql_handle, tmp_sql)) { ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); - aFree(party); //Free party, couldn't create it. return 0; } if(mysql_field_count(&mysql_handle) == 0 && mysql_insert_id(&mysql_handle) != 0) party_id = p->party_id = (int)mysql_insert_id(&mysql_handle); - else { //Failed to retrieve ID?? - aFree(party); //Free party, couldn't create it. + else //Failed to retrieve ID?? + return 0; +#else + //During conversion, you want to specify the id, and allow overwriting + //(in case someone is re-running the process. + sprintf(tmp_sql, "REPLACE INTO `%s` " + "(`party_id`, `name`, `exp`, `item`, `leader_id`, `leader_char`) " + "VALUES ('%d', '%s', '%d', '%d', '%d', '%d')", + party_db, p->party_id, t_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id); + if (mysql_query(&mysql_handle, tmp_sql)) { + ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); + ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); return 0; } - //Add party to db - int_party_calc_state(party); - idb_put(party_db_, party_id, party); +#endif } +#ifndef TXT_SQL_CONVERT if (flag&PS_BASIC) { //Update party info. sprintf(tmp_sql, "UPDATE `%s` SET `name`='%s', `exp`='%d', `item`='%d' WHERE `party_id`='%d'", @@ -211,12 +206,12 @@ int inter_party_tosql(struct party_data *party, int flag, int index) ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); } } - +#endif //TXT_SQL_CONVERT if (save_log) ShowInfo("Party Saved (%d - %s)\n", party_id, p->name); return 1; } - +#ifndef TXT_SQL_CONVERT // Read party from mysql struct party_data *inter_party_fromsql(int party_id) { @@ -365,7 +360,7 @@ int party_check_empty(struct party_data *p) if (i < MAX_PARTY) return 0; // If there is no member, then break the party mapif_party_broken(p->party.party_id,0); - inter_party_tosql(p, PS_BREAK, 0); + inter_party_tosql(&p->party, PS_BREAK, 0); return 1; } @@ -577,11 +572,16 @@ int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct part p->party.member[0].online=1; p->party.party_id=-1;//New party. - if (inter_party_tosql(p,PS_CREATE|PS_ADDMEMBER,0)) { + if (inter_party_tosql(&p->party,PS_CREATE|PS_ADDMEMBER,0)) { + //Add party to db + int_party_calc_state(p); + idb_put(party_db_, p->party.party_id, p); mapif_party_created(fd,leader->account_id,leader->char_id,&p->party); mapif_party_info(fd,&p->party); - } else //Failed to create party. + } else { //Failed to create party. + aFree(p); mapif_party_created(fd,leader->account_id,leader->char_id,NULL); + } return 0; } @@ -627,7 +627,7 @@ int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member mapif_party_memberadded(fd,party_id,member->account_id,member->char_id,0); mapif_party_info(-1,&p->party); - inter_party_tosql(p, PS_ADDMEMBER, i); + inter_party_tosql(&p->party, PS_ADDMEMBER, i); return 0; } //Party full @@ -651,7 +651,7 @@ int mapif_parse_PartyChangeOption(int fd,int party_id,int account_id,int exp,int } p->party.item = item&0x3; //Filter out invalid values. mapif_party_optionchanged(fd,&p->party,account_id,flag); - inter_party_tosql(p, PS_BASIC, 0); + inter_party_tosql(&p->party, PS_BASIC, 0); return 0; } // パーティ脱退要求 @@ -691,7 +691,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) } //Party gets deleted on the check_empty call below. } else { - inter_party_tosql(p,PS_DELMEMBER,i); + inter_party_tosql(&p->party,PS_DELMEMBER,i); j = p->party.member[i].lv; if(p->party.member[i].online) p->party.count--; memset(&p->party.member[i], 0, sizeof(struct party_member)); @@ -765,7 +765,7 @@ int mapif_parse_BreakParty(int fd,int party_id) if(!p) return 0; - inter_party_tosql(p,PS_BREAK,0); + inter_party_tosql(&p->party,PS_BREAK,0); mapif_party_broken(fd,party_id); return 0; } @@ -798,7 +798,7 @@ int mapif_parse_PartyLeaderChange(int fd,int party_id,int account_id,int char_id p->party.member[i].char_id == char_id) { p->party.member[i].leader = 1; - inter_party_tosql(p,PS_LEADER, i); + inter_party_tosql(&p->party,PS_LEADER, i); } } return 1; @@ -927,3 +927,4 @@ int inter_party_CharOffline(int char_id, int party_id) { idb_remove(party_db_, party_id); return 1; } +#endif //TXT_SQL_CONVERT diff --git a/src/char_sql/int_party.h b/src/char_sql/int_party.h index 9027392328..7e6219f9cc 100644 --- a/src/char_sql/int_party.h +++ b/src/char_sql/int_party.h @@ -1,8 +1,22 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_PARTY_H_ -#define _INT_PARTY_H_ +#ifndef _INT_PARTY_SQL_H_ +#define _INT_PARTY_SQL_H_ + +//Party Flags on what to save/delete. +//Create a new party entry (index holds leader's info) +#define PS_CREATE 0x01 +//Update basic party info. +#define PS_BASIC 0x02 +//Update party's leader +#define PS_LEADER 0x04 +//Specify new party member (index specifies which party member) +#define PS_ADDMEMBER 0x08 +//Specify member that left (index specifies which party member) +#define PS_DELMEMBER 0x10 +//Specify that this party must be deleted. +#define PS_BREAK 0x20 int inter_party_parse_frommap(int fd); int inter_party_sql_init(void); @@ -11,4 +25,6 @@ int inter_party_leave(int party_id,int account_id, int char_id); int inter_party_logged(int party_id, int account_id, int char_id); int inter_party_CharOnline(int char_id, int party_id); int inter_party_CharOffline(int char_id, int party_id); +//Required for the TXT->SQL converter +int inter_party_tosql(struct party *p, int flag, int index); #endif diff --git a/src/char_sql/int_pet.c b/src/char_sql/int_pet.c index c036a60192..5d5dc06156 100644 --- a/src/char_sql/int_pet.c +++ b/src/char_sql/int_pet.c @@ -68,7 +68,7 @@ int inter_pet_tosql(int pet_id, struct s_pet *p) { ShowInfo("Pet saved %d - %s.\n", pet_id, p->name); return 1; } - +#ifndef TXT_SQL_CONVERT int inter_pet_fromsql(int pet_id, struct s_pet *p){ #ifdef NOISY @@ -355,4 +355,4 @@ int inter_pet_parse_frommap(int fd){ } return 1; } - +#endif //TXT_SQL_CONVERT diff --git a/src/char_sql/int_pet.h b/src/char_sql/int_pet.h index 543dfe2961..fa5cbac0dc 100644 --- a/src/char_sql/int_pet.h +++ b/src/char_sql/int_pet.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_PET_H_ -#define _INT_PET_H_ +#ifndef _INT_PET_SQL_H_ +#define _INT_PET_SQL_H_ int inter_pet_init(void); void inter_pet_sql_final(void); @@ -13,4 +13,6 @@ int inter_pet_parse_frommap(int fd); int inter_pet_sql_init(void); //extern char pet_txt[256]; +//Exported for use in the TXT-SQL converter. +int inter_pet_tosql(int pet_id, struct s_pet *p); #endif diff --git a/src/char_sql/int_storage.c b/src/char_sql/int_storage.c index f91276e755..3ed0c2aa93 100644 --- a/src/char_sql/int_storage.c +++ b/src/char_sql/int_storage.c @@ -13,6 +13,7 @@ #define STORAGE_MEMINC 16 +#ifndef TXT_SQL_CONVERT // reset by inter_config_read() struct storage *storage_pt=NULL; struct guild_storage *guild_storage_pt=NULL; @@ -27,6 +28,7 @@ struct guild_storage *guild_storage_pt=NULL; #endif +#endif //TXT_SQL_CONVERT // storage data -> DB conversion int storage_tosql(int account_id,struct storage *p){ int i,j; @@ -55,6 +57,7 @@ int storage_tosql(int account_id,struct storage *p){ //printf ("storage dump to DB - id: %d (total: %d)\n", account_id, j); return 0; } +#ifndef TXT_SQL_CONVERT // DB -> storage data conversion int storage_fromsql(int account_id, struct storage *p){ @@ -99,7 +102,7 @@ int storage_fromsql(int account_id, struct storage *p){ ShowInfo ("storage load complete from DB - id: %d (total: %d)\n", account_id, p->storage_amount); return 1; } - +#endif //TXT_SQL_CONVERT // Save guild_storage data to sql int guild_storage_tosql(int guild_id, struct guild_storage *p){ int i,j; @@ -128,7 +131,7 @@ int guild_storage_tosql(int guild_id, struct guild_storage *p){ ShowInfo ("guild storage save to DB - id: %d (total: %d)\n", guild_id,i); return 0; } - +#ifndef TXT_SQL_CONVERT // Load guild_storage data to mem int guild_storage_fromsql(int guild_id, struct guild_storage *p){ int i=0,j; @@ -361,4 +364,4 @@ int inter_storage_parse_frommap(int fd){ } return 1; } - +#endif //TXT_SQL_CONVERT diff --git a/src/char_sql/int_storage.h b/src/char_sql/int_storage.h index 8cbf78fea0..c886a45e2e 100644 --- a/src/char_sql/int_storage.h +++ b/src/char_sql/int_storage.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_STORAGE_H_ -#define _INT_STORAGE_H_ +#ifndef _INT_STORAGE_SQL_H_ +#define _INT_STORAGE_SQL_H_ int inter_storage_sql_init(void); void inter_storage_sql_final(void); @@ -11,7 +11,7 @@ int inter_guild_storage_delete(int guild_id); int inter_storage_parse_frommap(int fd); - -//extern char storage_txt[256]; - +//Exported for use in the TXT-SQL converter. +int storage_tosql(int account_id,struct storage *p); +int guild_storage_tosql(int guild_id, struct guild_storage *p); #endif diff --git a/src/char_sql/inter.c b/src/char_sql/inter.c index ba05073136..f02296f588 100644 --- a/src/char_sql/inter.c +++ b/src/char_sql/inter.c @@ -21,16 +21,6 @@ #define WISDELLIST_MAX 256 // Wisデータ削除リストの要素数 -struct accreg { - int account_id, char_id; - int reg_num; - struct global_reg reg[MAX_REG_NUM]; -}; - -static struct accreg *accreg_pt; - - -unsigned int party_share_level = 10; MYSQL mysql_handle; MYSQL_RES* sql_res ; MYSQL_ROW sql_row ; @@ -54,6 +44,10 @@ char login_server_id[32] = "ragnarok"; char login_server_pw[32] = "ragnarok"; char login_server_db[32] = "ragnarok"; +#ifndef TXT_SQL_CONVERT + +static struct accreg *accreg_pt; +unsigned int party_share_level = 10; char main_chat_nick[16] = "Main"; // sending packet list @@ -93,6 +87,7 @@ static int wis_dellist[WISDELLIST_MAX], wis_delnum; int inter_sql_test (void); +#endif //TXT_SQL_CONVERT //-------------------------------------------------------- // Save registry to sql int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type){ @@ -141,6 +136,7 @@ int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type } return 1; } +#ifndef TXT_SQL_CONVERT // Load account_reg from sql (type=2) int inter_accreg_fromsql(int account_id,int char_id, struct accreg *reg, int type) @@ -187,12 +183,13 @@ int inter_accreg_sql_init(void) return 0; } +#endif //TXT_SQL_CONVERT /*========================================== * read config file *------------------------------------------ */ -int inter_config_read(const char *cfgName) { +static int inter_config_read(const char *cfgName) { int i; char line[1024], w1[1024], w2[1024]; FILE *fp; @@ -236,7 +233,6 @@ int inter_config_read(const char *cfgName) { } //Logins information to be read from the inter_athena.conf //for character deletion (checks email in the loginDB) - else if(strcmpi(w1,"login_server_ip")==0){ strcpy(login_server_ip, w2); ShowStatus ("set login_server_ip : %s\n",w2); @@ -257,19 +253,17 @@ int inter_config_read(const char *cfgName) { strcpy(login_server_db, w2); ShowStatus ("set login_server_db : %s\n",w2); } +#ifndef TXT_SQL_CONVERT else if(strcmpi(w1,"party_share_level")==0){ party_share_level=(unsigned int)atof(w2); } else if(strcmpi(w1,"log_inter")==0){ log_inter = atoi(w2); } - else if(strcmpi(w1,"login_server_db")==0){ - strcpy(login_server_db, w2); - ShowStatus ("set login_server_db : %s\n",w2); - } else if(strcmpi(w1, "main_chat_nick")==0){ // Main chat nick [LuzZza] strcpy(main_chat_nick, w2); // } +#endif //TXT_SQL_CONVERT else if(strcmpi(w1,"import")==0){ inter_config_read(w2); } @@ -280,6 +274,7 @@ int inter_config_read(const char *cfgName) { return 0; } +#ifndef TXT_SQL_CONVERT // Save interlog into sql int inter_log(char *fmt,...) @@ -312,9 +307,10 @@ int inter_sql_ping(int tid, unsigned int tick, int id, int data) mysql_ping(&lmysql_handle); return 0; } +#endif //TXT_SQL_CONVERT // initialize -int inter_init(const char *file) +int inter_init_sql(const char *file) { //int i; @@ -330,6 +326,7 @@ int inter_init(const char *file) ShowFatalError("%s\n",mysql_error(&mysql_handle)); exit(1); } +#ifndef TXT_SQL_CONVERT else if (inter_sql_test()) { ShowStatus("Connect Success! (Character Server)\n"); } @@ -346,37 +343,40 @@ int inter_init(const char *file) ShowStatus ("Connect Success! (Login Server)\n"); } } +#endif //TXT_SQL_CONVERT if(strlen(default_codepage) > 0 ) { sprintf( tmp_sql, "SET NAMES %s", default_codepage ); if (mysql_query(&mysql_handle, tmp_sql)) { ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); } +#ifndef TXT_SQL_CONVERT if(char_gm_read) if (mysql_query(&lmysql_handle, tmp_sql)) { ShowSQL("DB error - %s\n",mysql_error(&lmysql_handle)); ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); } +#endif //TXT_SQL_CONVERT } + +#ifndef TXT_SQL_CONVERT wis_db = db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int)); inter_guild_sql_init(); inter_storage_sql_init(); inter_party_sql_init(); - inter_pet_sql_init(); inter_homunculus_sql_init(); // albator inter_accreg_sql_init(); - //printf ("interserver timer initializing : %d sec...\n",autosave_interval); - //i=add_timer_interval(gettick()+autosave_interval,inter_save_timer,0,0,autosave_interval); - if (connection_ping_interval) { add_timer_func_list(inter_sql_ping, "inter_sql_ping"); add_timer_interval(gettick()+connection_ping_interval*60*60*1000, inter_sql_ping, 0, 0, connection_ping_interval*60*60*1000); } +#endif //TXT_SQL_CONVERT return 0; } +#ifndef TXT_SQL_CONVERT int inter_sql_test (void) { @@ -808,3 +808,4 @@ int inter_check_length(int fd, int length) return length; } +#endif //TXT_SQL_CONVERT diff --git a/src/char_sql/inter.h b/src/char_sql/inter.h index d840856516..8dc6f3668a 100644 --- a/src/char_sql/inter.h +++ b/src/char_sql/inter.h @@ -1,10 +1,10 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INTER_H_ -#define _INTER_H_ +#ifndef _INTER_SQL_H_ +#define _INTER_SQL_H_ -int inter_init(const char *file); +int inter_init_sql(const char *file); void inter_final(void); int inter_parse_frommap(int fd); int inter_mapif_init(int fd); @@ -50,8 +50,7 @@ extern char login_db_server_id[32]; extern char login_db_server_pw[32]; extern char login_db_server_db[32]; -extern int log_inter; - extern char main_chat_nick[16]; +int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type); #endif diff --git a/src/common/mmo.h b/src/common/mmo.h index 77d6c1dd67..842159d59b 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -149,6 +149,13 @@ struct global_reg { char value[256]; // [zBuffer] }; +//Holds array of global registries, used by the char server and converter. +struct accreg { + int account_id, char_id; + int reg_num; + struct global_reg reg[MAX_REG_NUM]; +}; + //For saving status changes across sessions. [Skotlex] struct status_change_data { unsigned short type; //SC_type diff --git a/src/map/script.c b/src/map/script.c index 1210507d65..72d771e880 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -9677,7 +9677,7 @@ int buildin_misceffect(struct script_state *st) int type; type=conv_num(st,& (st->stack->stack_data[st->start+2])); - if(st->oid) { + if(st->oid && st->oid != fake_nd->bl.id) { struct block_list *bl = map_id2bl(st->oid); if (bl) clif_misceffect2(bl,type); diff --git a/src/map/skill.c b/src/map/skill.c index 6e36973ce1..f6632c36fb 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6400,13 +6400,10 @@ static int skill_dance_overlap_sub(struct block_list *bl, va_list ap) return 0; if (!(target->val2 & src->val2 & ~UF_ENSEMBLE)) //They don't match (song + dance) is valid. return 0; - if (flag) { //Set dissonance - target->val1 = src->val1 = target->val2&UF_SONG?BA_DISSONANCE:DC_UGLYDANCE; + if (flag) //Set dissonance target->val2 |= UF_ENSEMBLE; //Add ensemble to signal this unit is overlapping. - } else { //Remove dissonance - target->val1 = target->group->skill_id; //Restore skill id + else //Remove dissonance target->val2 &= ~UF_ENSEMBLE; - } clif_skill_setunit(target); //Update look of affected cell. return 1; } @@ -9158,6 +9155,9 @@ int skill_attack_area (struct block_list *bl, va_list ap) !status_check_skilluse(NULL, bl, skillid, 2)) return 0; + if (skillid == WZ_FROSTNOVA) //Only skill that doesn't requires the animation to be removed :X + return skill_attack(atk_type,src,dsrc,bl,skillid,skilllv,tick,flag); + //Area-splash, disable skill animation. return skill_attack(atk_type,src,dsrc,bl,skillid,skilllv,tick,flag|SD_ANIMATION); } diff --git a/src/map/trade.c b/src/map/trade.c index ef49a4e2b2..23be27700c 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -485,9 +485,10 @@ void trade_tradecommit(struct map_session_data *sd) { flag = pc_additem(tsd, &sd->status.inventory[n], sd->deal.item[trade_i].amount); if (flag == 0) { //Logs (T)rade [Lupus] - if(log_config.enable_logs&0x2) + if(log_config.enable_logs&0x2) { log_pick(sd, "T", 0, sd->status.inventory[n].nameid, -(sd->deal.item[trade_i].amount), &sd->status.inventory[n]); log_pick(tsd, "T", 0, sd->status.inventory[n].nameid, sd->deal.item[trade_i].amount, &sd->status.inventory[n]); + } //Logs pc_delitem(sd, n, sd->deal.item[trade_i].amount, 1); } else @@ -501,9 +502,10 @@ void trade_tradecommit(struct map_session_data *sd) { flag = pc_additem(sd, &tsd->status.inventory[n], tsd->deal.item[trade_i].amount); if (flag == 0) { //Logs (T)rade [Lupus] - if(log_config.enable_logs&0x2) + if(log_config.enable_logs&0x2) { log_pick(tsd, "T", 0, tsd->status.inventory[n].nameid, -(tsd->deal.item[trade_i].amount), &tsd->status.inventory[n]); log_pick(sd, "T", 0, tsd->status.inventory[n].nameid, tsd->deal.item[trade_i].amount, &tsd->status.inventory[n]); + } //Logs pc_delitem(tsd, n, tsd->deal.item[trade_i].amount, 1); } else diff --git a/src/txt-converter/Makefile b/src/txt-converter/Makefile index 376a585612..284f8dc817 100644 --- a/src/txt-converter/Makefile +++ b/src/txt-converter/Makefile @@ -1,6 +1,12 @@ all sql: char-converter login-converter -char-converter: char-converter.o ../common/obj/minicore.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/strlib.o ../common/obj/mapindex.o ../common/obj/ers.o +char-converter: char-converter.o ../common/obj/minicore.o \ + ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/strlib.o \ + ../common/obj/mapindex.o ../common/obj/ers.o \ + ../char/char.o ../char/int_pet.o ../char/int_storage.o ../char/inter.o \ + ../char/int_party.o ../char/int_guild.o \ + ../char_sql/char.o ../char_sql/int_pet.o ../char_sql/int_storage.o \ + ../char_sql/inter.o ../char_sql/int_party.o ../char_sql/int_guild.o $(CC) -o ../../tools/$@ $^ $(LIB_S) login-converter: login-converter.o ../common/obj/minicore.o ../common/obj/db.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/ers.o @@ -11,5 +17,8 @@ clean: # DO NOT DELETE +%.o: %.c + $(COMPILE.c) -DTXT_SQL_CONVERT $(OUTPUT_OPTION) $< + char-converter.o: char-converter.c login-converter.o: login-converter.c diff --git a/src/txt-converter/char-converter.c b/src/txt-converter/char-converter.c index f9bec0a4f4..56f8cdbcdb 100644 --- a/src/txt-converter/char-converter.c +++ b/src/txt-converter/char-converter.c @@ -11,1152 +11,88 @@ #include "../common/showmsg.h" #include "../common/mapindex.h" -#include +#include "../char/char.h" +#include "../char/int_storage.h" +#include "../char/int_pet.h" +#include "../char/int_party.h" +#include "../char/int_guild.h" +#include "../char/inter.h" -//Txt Files used. -char char_txt[1024]="save/athena.txt"; -char friends_txt[1024]="save/friends.txt"; // davidsiaw -char pet_txt[256]="save/pet.txt"; -char storage_txt[256]="save/storage.txt"; - -//Databases used. -char char_db[256] = "char"; -char cart_db[256] = "cart_inventory"; -char inventory_db[256] = "inventory"; -char storage_db[256] = "storage"; -char reg_db[256] = "global_reg_value"; -char skill_db[256] = "skill"; -char memo_db[256] = "memo"; -char pet_db[256] = "pet"; -char friend_db[256] = "friends"; -char guild_storage_db[256] = "guild_storage"; - -MYSQL mysql_handle; -MYSQL_RES* sql_res ; -MYSQL_ROW sql_row ; -char tmp_sql[65535]; - -int sql_fields, sql_cnt; - -int db_server_port = 3306; -char db_server_ip[16] = "127.0.0.1"; -char db_server_id[32] = "ragnarok"; -char db_server_pw[32] = "ragnarok"; -char db_server_logindb[32] = "ragnarok"; +#include "../char_sql/char.h" +#include "../char_sql/int_storage.h" +#include "../char_sql/int_pet.h" +#include "../char_sql/int_party.h" +#include "../char_sql/int_guild.h" +#include "../char_sql/inter.h" char t_name[256]; -int char_id_count=100000; - -struct accreg { - int reg_num; - struct global_reg reg[ACCOUNT_REG_NUM]; -}; - -struct character_data { - struct mmo_charstatus status; - struct accreg global; -} *char_dat; -int char_num, char_max; - -//Required for sql saving, taken from src/char_sql/char.h -struct itemtmp { - int flag;//checked = 1 else 0 - int id; - short nameid; - short amount; - unsigned short equip; - char identify; - char refine; - char attribute; - short card[4]; -}; -enum { - TABLE_INVENTORY, - TABLE_CART, - TABLE_STORAGE, - TABLE_GUILD_STORAGE, -}; - #define CHAR_CONF_NAME "conf/char_athena.conf" +#define SQL_CONF_NAME "conf/inter_athena.conf" #define INTER_CONF_NAME "conf/inter_athena.conf" -//========================================================================================================== -//NOTE: Update this function from the one in src/char/char.c as needed. [Skotlex] -int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct accreg *reg) { - char tmp_str[3][128]; //To avoid deleting chars with too long names. - int tmp_int[256]; - int set, next, len, i; - - // initilialise character - memset(p, '\0', sizeof(struct mmo_charstatus)); - - // If it's not char structure of version 1488 and after - if ((set = sscanf(str, "%d\t%d,%d\t%127[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d" - "\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d" - "\t%127[^,],%d,%d\t%127[^,],%d,%d,%d,%d,%d,%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], tmp_str[0], - &tmp_int[3], &tmp_int[4], &tmp_int[5], - &tmp_int[6], &tmp_int[7], &tmp_int[8], - &tmp_int[9], &tmp_int[10], &tmp_int[11], &tmp_int[12], - &tmp_int[13], &tmp_int[14], &tmp_int[15], &tmp_int[16], &tmp_int[17], &tmp_int[18], - &tmp_int[19], &tmp_int[20], - &tmp_int[21], &tmp_int[22], &tmp_int[23], // - &tmp_int[24], &tmp_int[25], &tmp_int[26], - &tmp_int[27], &tmp_int[28], &tmp_int[29], - &tmp_int[30], &tmp_int[31], &tmp_int[32], &tmp_int[33], &tmp_int[34], - tmp_str[1], &tmp_int[35], &tmp_int[36], - tmp_str[2], &tmp_int[37], &tmp_int[38], &tmp_int[39], - &tmp_int[40], &tmp_int[41], &tmp_int[42], &tmp_int[43], &next)) != 47) - { - tmp_int[43] = 0; - // If it's not char structure of version 1363 and after - if ((set = sscanf(str, "%d\t%d,%d\t%127[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d" - "\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d" - "\t%127[^,],%d,%d\t%127[^,],%d,%d,%d,%d,%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], tmp_str[0], // - &tmp_int[3], &tmp_int[4], &tmp_int[5], - &tmp_int[6], &tmp_int[7], &tmp_int[8], - &tmp_int[9], &tmp_int[10], &tmp_int[11], &tmp_int[12], - &tmp_int[13], &tmp_int[14], &tmp_int[15], &tmp_int[16], &tmp_int[17], &tmp_int[18], - &tmp_int[19], &tmp_int[20], - &tmp_int[21], &tmp_int[22], &tmp_int[23], // - &tmp_int[24], &tmp_int[25], &tmp_int[26], - &tmp_int[27], &tmp_int[28], &tmp_int[29], - &tmp_int[30], &tmp_int[31], &tmp_int[32], &tmp_int[33], &tmp_int[34], - tmp_str[1], &tmp_int[35], &tmp_int[36], // - tmp_str[2], &tmp_int[37], &tmp_int[38], &tmp_int[39], - &tmp_int[40], &tmp_int[41], &tmp_int[42], &next)) != 46) - { - tmp_int[40] = 0; // father - tmp_int[41] = 0; // mother - tmp_int[42] = 0; // child - // If it's not char structure of version 1008 and before 1363 - if ((set = sscanf(str, "%d\t%d,%d\t%127[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d" - "\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d" - "\t%127[^,],%d,%d\t%127[^,],%d,%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], tmp_str[0], // - &tmp_int[3], &tmp_int[4], &tmp_int[5], - &tmp_int[6], &tmp_int[7], &tmp_int[8], - &tmp_int[9], &tmp_int[10], &tmp_int[11], &tmp_int[12], - &tmp_int[13], &tmp_int[14], &tmp_int[15], &tmp_int[16], &tmp_int[17], &tmp_int[18], - &tmp_int[19], &tmp_int[20], - &tmp_int[21], &tmp_int[22], &tmp_int[23], // - &tmp_int[24], &tmp_int[25], &tmp_int[26], - &tmp_int[27], &tmp_int[28], &tmp_int[29], - &tmp_int[30], &tmp_int[31], &tmp_int[32], &tmp_int[33], &tmp_int[34], - tmp_str[1], &tmp_int[35], &tmp_int[36], // - tmp_str[2], &tmp_int[37], &tmp_int[38], &tmp_int[39], &next)) != 43) - { - tmp_int[39] = 0; // partner id - // If not char structure from version 384 to 1007 - if ((set = sscanf(str, "%d\t%d,%d\t%127[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d" - "\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d" - "\t%127[^,],%d,%d\t%127[^,],%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], tmp_str[0], // - &tmp_int[3], &tmp_int[4], &tmp_int[5], - &tmp_int[6], &tmp_int[7], &tmp_int[8], - &tmp_int[9], &tmp_int[10], &tmp_int[11], &tmp_int[12], - &tmp_int[13], &tmp_int[14], &tmp_int[15], &tmp_int[16], &tmp_int[17], &tmp_int[18], - &tmp_int[19], &tmp_int[20], - &tmp_int[21], &tmp_int[22], &tmp_int[23], // - &tmp_int[24], &tmp_int[25], &tmp_int[26], - &tmp_int[27], &tmp_int[28], &tmp_int[29], - &tmp_int[30], &tmp_int[31], &tmp_int[32], &tmp_int[33], &tmp_int[34], - tmp_str[1], &tmp_int[35], &tmp_int[36], // - tmp_str[2], &tmp_int[37], &tmp_int[38], &next)) != 42) - { - // It's char structure of a version before 384 - tmp_int[26] = 0; // pet id - set = sscanf(str, "%d\t%d,%d\t%127[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d" - "\t%d,%d,%d\t%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d" - "\t%127[^,],%d,%d\t%127[^,],%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], tmp_str[0], // - &tmp_int[3], &tmp_int[4], &tmp_int[5], - &tmp_int[6], &tmp_int[7], &tmp_int[8], - &tmp_int[9], &tmp_int[10], &tmp_int[11], &tmp_int[12], - &tmp_int[13], &tmp_int[14], &tmp_int[15], &tmp_int[16], &tmp_int[17], &tmp_int[18], - &tmp_int[19], &tmp_int[20], - &tmp_int[21], &tmp_int[22], &tmp_int[23], // - &tmp_int[24], &tmp_int[25], // - &tmp_int[27], &tmp_int[28], &tmp_int[29], - &tmp_int[30], &tmp_int[31], &tmp_int[32], &tmp_int[33], &tmp_int[34], - tmp_str[1], &tmp_int[35], &tmp_int[36], // - tmp_str[2], &tmp_int[37], &tmp_int[38], &next); - set += 2; - //printf("char: old char data ver.1\n"); - // Char structure of version 1007 or older - } else { - set++; - //printf("char: old char data ver.2\n"); - } - // Char structure of version 1008+ - } else { - set += 3; - //printf("char: new char data ver.3\n"); - } - // Char structture of version 1363+ - } else { - set++; - //printf("char: new char data ver.4\n"); - } - // Char structure of version 1488+ - } else { - //printf("char: new char data ver.5\n"); - } - if (set != 47) - return 0; - - memcpy(p->name, tmp_str[0], NAME_LENGTH-1); //Overflow protection [Skotlex] - p->char_id = tmp_int[0]; - p->account_id = tmp_int[1]; - p->char_num = tmp_int[2]; - p->class_ = tmp_int[3]; - p->base_level = tmp_int[4]; - p->job_level = tmp_int[5]; - p->base_exp = tmp_int[6]; - p->job_exp = tmp_int[7]; - p->zeny = tmp_int[8]; - p->hp = tmp_int[9]; - p->max_hp = tmp_int[10]; - p->sp = tmp_int[11]; - p->max_sp = tmp_int[12]; - p->str = tmp_int[13]; - p->agi = tmp_int[14]; - p->vit = tmp_int[15]; - p->int_ = tmp_int[16]; - p->dex = tmp_int[17]; - p->luk = tmp_int[18]; - p->status_point = tmp_int[19]; - p->skill_point = tmp_int[20]; - p->option = tmp_int[21]; - p->karma = tmp_int[22]; - p->manner = tmp_int[23]; - p->party_id = tmp_int[24]; - p->guild_id = tmp_int[25]; - p->pet_id = tmp_int[26]; - p->hair = tmp_int[27]; - p->hair_color = tmp_int[28]; - p->clothes_color = tmp_int[29]; - p->weapon = tmp_int[30]; - p->shield = tmp_int[31]; - p->head_top = tmp_int[32]; - p->head_mid = tmp_int[33]; - p->head_bottom = tmp_int[34]; - p->last_point.map = mapindex_name2id(tmp_str[1]); - p->last_point.x = tmp_int[35]; - p->last_point.y = tmp_int[36]; - p->save_point.map = mapindex_name2id(tmp_str[2]); - p->save_point.x = tmp_int[37]; - p->save_point.y = tmp_int[38]; - p->partner_id = tmp_int[39]; - p->father = tmp_int[40]; - p->mother = tmp_int[41]; - p->child = tmp_int[42]; - p->fame = tmp_int[43]; - - // Some checks - for(i = 0; i < char_num; i++) { - if (char_dat[i].status.char_id == p->char_id) { - ShowError("\033[1;31mmmo_auth_init: a character has an identical id to another.\n"); - ShowError(" character id #%d -> new character not readed.\n", p->char_id); - ShowError(" Character saved in log file.\033[0m\n"); - return -1; - } else if (strcmp(char_dat[i].status.name, p->name) == 0) { - ShowError("\033[1;31mmmo_auth_init: a character name already exists.\n"); - ShowError(" character name '%s' -> new character not read.\n", p->name); - ShowError(" Character saved in log file.\033[0m\n"); - return -2; - } - } - - if (str[next] == '\n' || str[next] == '\r') - return 1; - - next++; - - for(i = 0; str[next] && str[next] != '\t'; i++) { - if (sscanf(str+next, "%[^,],%d,%d%n", tmp_str[0], &tmp_int[0], &tmp_int[1], &len) != 3) - return -3; - p->memo_point[i].map = mapindex_name2id(tmp_str[0]); - p->memo_point[i].x = tmp_int[0]; - p->memo_point[i].y = tmp_int[1]; - next += len; - if (str[next] == ' ') - next++; - } - - next++; - - for(i = 0; str[next] && str[next] != '\t'; i++) { - if (sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3], - &tmp_int[4], &tmp_int[5], &tmp_int[6], - &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[10], &len) == 12) { - // do nothing, it's ok - } else if (sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3], - &tmp_int[4], &tmp_int[5], &tmp_int[6], - &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &len) == 11) { - } else // invalid structure - return -4; - p->inventory[i].id = tmp_int[0]; - p->inventory[i].nameid = tmp_int[1]; - p->inventory[i].amount = tmp_int[2]; - p->inventory[i].equip = tmp_int[3]; - p->inventory[i].identify = tmp_int[4]; - p->inventory[i].refine = tmp_int[5]; - p->inventory[i].attribute = tmp_int[6]; - p->inventory[i].card[0] = tmp_int[7]; - p->inventory[i].card[1] = tmp_int[8]; - p->inventory[i].card[2] = tmp_int[9]; - p->inventory[i].card[3] = tmp_int[10]; - next += len; - if (str[next] == ' ') - next++; - } - - next++; - - for(i = 0; str[next] && str[next] != '\t'; i++) { - if (sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3], - &tmp_int[4], &tmp_int[5], &tmp_int[6], - &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[10], &len) == 12) { - // do nothing, it's ok - } else if (sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3], - &tmp_int[4], &tmp_int[5], &tmp_int[6], - &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &len) == 11) { - } else // invalid structure - return -5; - p->cart[i].id = tmp_int[0]; - p->cart[i].nameid = tmp_int[1]; - p->cart[i].amount = tmp_int[2]; - p->cart[i].equip = tmp_int[3]; - p->cart[i].identify = tmp_int[4]; - p->cart[i].refine = tmp_int[5]; - p->cart[i].attribute = tmp_int[6]; - p->cart[i].card[0] = tmp_int[7]; - p->cart[i].card[1] = tmp_int[8]; - p->cart[i].card[2] = tmp_int[9]; - p->cart[i].card[3] = tmp_int[10]; - next += len; - if (str[next] == ' ') - next++; - } - - next++; - - for(i = 0; str[next] && str[next] != '\t'; i++) { - if (sscanf(str + next, "%d,%d%n", &tmp_int[0], &tmp_int[1], &len) != 2) - return -6; - p->skill[tmp_int[0]].id = tmp_int[0]; - p->skill[tmp_int[0]].lv = tmp_int[1]; - next += len; - if (str[next] == ' ') - next++; - } - - next++; - - for(i = 0; str[next] && str[next] != '\t' && str[next] != '\n' && str[next] != '\r'; i++) { - if (sscanf(str + next, "%[^,],%s%n", reg->reg[i].str, reg->reg[i].value, &len) != 2) { - // because some scripts are not correct, the str can be "". So, we must check that. - // If it's, we must not refuse the character, but just this REG value. - // Character line will have something like: nov_2nd_cos,9 ,9 nov_1_2_cos_c,1 (here, ,9 is not good) - if (str[next] == ',' && sscanf(str + next, ",%s%n", reg->reg[i].value, &len) == 1) - i--; - else - return -7; - } - next += len; - if (str[next] == ' ') - next++; - } - reg->reg_num = i; - - return 1; -} -/* Because of the friend database update, it is no longer possible to convert friends. -//Note: Keep updated with the same function found in src/char/char.c [Skotlex] -int parse_friend_txt(struct mmo_charstatus *p) -{ - char line[1024]; - int i,cid=0,temp[20]; - FILE *fp; - - // Open the file and look for the ID - fp = fopen(friends_txt, "r"); - - if(fp == NULL) - return 1; - - - while(fgets(line, sizeof(line)-1, fp)) { - - if(line[0] == '/' && line[1] == '/') - continue; - //Character names must not exceed the 23+\0 limit. [Skotlex] - sscanf(line, "%d,%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23[^,],%d,%23s",&cid, - &temp[0],p->friends[0].name, - &temp[1],p->friends[1].name, - &temp[2],p->friends[2].name, - &temp[3],p->friends[3].name, - &temp[4],p->friends[4].name, - &temp[5],p->friends[5].name, - &temp[6],p->friends[6].name, - &temp[7],p->friends[7].name, - &temp[8],p->friends[8].name, - &temp[9],p->friends[9].name, - &temp[10],p->friends[10].name, - &temp[11],p->friends[11].name, - &temp[12],p->friends[12].name, - &temp[13],p->friends[13].name, - &temp[14],p->friends[14].name, - &temp[15],p->friends[15].name, - &temp[16],p->friends[16].name, - &temp[17],p->friends[17].name, - &temp[18],p->friends[18].name, - &temp[19],p->friends[19].name); - if (cid == p->char_id) - break; - } - - // No register of friends list - if (cid == 0) { - fclose(fp); - return 0; - } - - // Fill in the list - - for (i=0; i<20; i++) - p->friends[i].char_id = temp[i]; - - fclose(fp); - return 0; -} -*/ - -// Note: Remember to keep this function updated with the one in src/char_sql/char.c [Skotlex] -// Unneded code was left commented for easier merging of changes. -// Function by [Ilpalazzo-sama] - -int memitemdata_to_sql(struct itemtmp mapitem[], int count, int char_id, int tableswitch) -{ - int i; //, flag, id; - char *tablename; - char selectoption[16]; - - switch (tableswitch) { - case TABLE_INVENTORY: - tablename = inventory_db; // no need for sprintf here as *_db are char*. - sprintf(selectoption,"char_id"); - break; - case TABLE_CART: - tablename = cart_db; - sprintf(selectoption,"char_id"); - break; - case TABLE_STORAGE: - tablename = storage_db; - sprintf(selectoption,"account_id"); - break; - case TABLE_GUILD_STORAGE: - tablename = guild_storage_db; - sprintf(selectoption,"guild_id"); - break; - default: - ShowError("Invalid table name!\n"); - return 1; - } - - //=======================================mysql database data > memory=============================================== -/* - sprintf(tmp_sql, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3` " - "FROM `%s` WHERE `%s`='%d'", tablename, selectoption, char_id); - - if (mysql_query(&mysql_handle, tmp_sql)) { - ShowSQL("DB server Error (select `%s` to Memory)- %s\n",tablename ,mysql_error(&mysql_handle)); - return 1; - } - sql_res = mysql_store_result(&mysql_handle); - if (sql_res) { - while ((sql_row = mysql_fetch_row(sql_res))) { - flag = 0; - id = atoi(sql_row[0]); - for(i = 0; i < count; i++) { - if(mapitem[i].flag == 1) - continue; - if(mapitem[i].nameid == atoi(sql_row[1])) { // produced items fixup - if((mapitem[i].equip == atoi(sql_row[3])) && - (mapitem[i].identify == atoi(sql_row[4])) && - (mapitem[i].amount == atoi(sql_row[2])) && - (mapitem[i].refine == atoi(sql_row[5])) && - (mapitem[i].attribute == atoi(sql_row[6])) && - (mapitem[i].card[0] == atoi(sql_row[7])) && - (mapitem[i].card[1] == atoi(sql_row[8])) && - (mapitem[i].card[2] == atoi(sql_row[9])) && - (mapitem[i].card[3] == atoi(sql_row[10]))) { - //printf("the same item : %d , equip : %d , i : %d , flag : %d\n", mapitem.equip[i].nameid,mapitem.equip[i].equip , i, mapitem.equip[i].flag); //DEBUG-STRING - } else { -//==============================================Memory data > SQL =============================== - if(itemdb_isequip(mapitem[i].nameid) || (mapitem[i].card[0] == atoi(sql_row[7]))) { - sprintf(tmp_sql,"UPDATE `%s` SET `equip`='%d', `identify`='%d', `refine`='%d'," - "`attribute`='%d', `card0`='%d', `card1`='%d', `card2`='%d', `card3`='%d', `amount`='%d' WHERE `id`='%d' LIMIT 1", - tablename, mapitem[i].equip, mapitem[i].identify, mapitem[i].refine, mapitem[i].attribute, mapitem[i].card[0], - mapitem[i].card[1], mapitem[i].card[2], mapitem[i].card[3], mapitem[i].amount, id); - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB server Error (UPdate `equ %s`)- %s\n", tablename, mysql_error(&mysql_handle)); - } - //printf("not the same item : %d ; i : %d ; flag : %d\n", mapitem.equip[i].nameid, i, mapitem.equip[i].flag); - } - flag = mapitem[i].flag = 1; - break; - } - } - if(!flag) { - sprintf(tmp_sql,"DELETE from `%s` where `id`='%d'", tablename, id); - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB server Error (DELETE `equ %s`)- %s\n", tablename, mysql_error(&mysql_handle)); - } - } - mysql_free_result(sql_res); - } -*/ - for(i = 0; i < count; i++) { - if(mapitem[i].nameid) { - sprintf(tmp_sql,"INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3` )" - " VALUES ( '%d','%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d' )", - tablename, selectoption, char_id, mapitem[i].nameid, mapitem[i].amount, mapitem[i].equip, mapitem[i].identify, mapitem[i].refine, - mapitem[i].attribute, mapitem[i].card[0], mapitem[i].card[1], mapitem[i].card[2], mapitem[i].card[3]); - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB server Error (INSERT `equ %s`)- %s\n", tablename, mysql_error(&mysql_handle)); - } - } - return 0; -} - -//Note: Remember to keep this function updated with src/char_sql/char.c [Skotlex] -//Unncessary code is left commented for easy merging. -int mmo_char_tosql(int char_id, struct mmo_charstatus *p){ - int i=0 ,party_exist=0;//,guild_exist; - int count = 0; - int diff = 1; - char *tmp_ptr; //Building a single query should be more efficient than running - //multiple queries for each thing about to be saved, right? [Skotlex] - char save_status[100]; //For displaying save information. [Skotlex] -// struct mmo_charstatus *cp; - struct itemtmp mapitem[MAX_GUILD_STORAGE]; - - if (char_id!=p->char_id) return 0; - -/* - cp = (struct mmo_charstatus*)idb_get(char_db_,char_id); - - if (cp == NULL) { - cp = (struct mmo_charstatus *) aMalloc(sizeof(struct mmo_charstatus)); - memset(cp, 0, sizeof(struct mmo_charstatus)); - idb_put(char_db_, char_id,cp); - } -*/ - ShowInfo("Saving char "CL_WHITE"%d"CL_RESET" (%s)...\n",char_id,p->name); - memset(save_status, 0, sizeof(save_status)); - - count = 0; -// diff = 0; - //map inventory data - for(i=0;iinventory[i], &cp->inventory[i])) -// diff = 1; - if(p->inventory[i].nameid>0){ - mapitem[count].flag=0; - mapitem[count].id = p->inventory[i].id; - mapitem[count].nameid=p->inventory[i].nameid; - mapitem[count].amount = p->inventory[i].amount; - mapitem[count].equip = p->inventory[i].equip; - mapitem[count].identify = p->inventory[i].identify; - mapitem[count].refine = p->inventory[i].refine; - mapitem[count].attribute = p->inventory[i].attribute; - mapitem[count].card[0] = p->inventory[i].card[0]; - mapitem[count].card[1] = p->inventory[i].card[1]; - mapitem[count].card[2] = p->inventory[i].card[2]; - mapitem[count].card[3] = p->inventory[i].card[3]; - count++; - } - } - //printf("- Save item data to MySQL!\n"); - if (diff) - if (!memitemdata_to_sql(mapitem, count, p->char_id,TABLE_INVENTORY)) - strcat(save_status, " inventory"); - - count = 0; - -// diff = 0; - //map cart data - for(i=0;icart[i], &cp->cart[i])) -// diff = 1; - if(p->cart[i].nameid>0){ - mapitem[count].flag=0; - mapitem[count].id = p->cart[i].id; - mapitem[count].nameid=p->cart[i].nameid; - mapitem[count].amount = p->cart[i].amount; - mapitem[count].equip = p->cart[i].equip; - mapitem[count].identify = p->cart[i].identify; - mapitem[count].refine = p->cart[i].refine; - mapitem[count].attribute = p->cart[i].attribute; - mapitem[count].card[0] = p->cart[i].card[0]; - mapitem[count].card[1] = p->cart[i].card[1]; - mapitem[count].card[2] = p->cart[i].card[2]; - mapitem[count].card[3] = p->cart[i].card[3]; - count++; - } - } - - if (diff) - if (!memitemdata_to_sql(mapitem, count, p->char_id,TABLE_CART)) - strcat(save_status, " cart"); -/* - if ((p->base_exp != cp->base_exp) || (p->class_ != cp->class_) || - (p->base_level != cp->base_level) || (p->job_level != cp->job_level) || - (p->job_exp != cp->job_exp) || (p->zeny != cp->zeny) || - (p->last_point.x != cp->last_point.x) || (p->last_point.y != cp->last_point.y) || - (p->max_hp != cp->max_hp) || (p->hp != cp->hp) || - (p->max_sp != cp->max_sp) || (p->sp != cp->sp) || - (p->status_point != cp->status_point) || (p->skill_point != cp->skill_point) || - (p->str != cp->str) || (p->agi != cp->agi) || (p->vit != cp->vit) || - (p->int_ != cp->int_) || (p->dex != cp->dex) || (p->luk != cp->luk) || - (p->option != cp->option) || (p->karma != cp->karma) || (p->manner != cp->manner) || - (p->party_id != cp->party_id) || (p->guild_id != cp->guild_id) || - (p->pet_id != cp->pet_id) || (p->hair != cp->hair) || (p->hair_color != cp->hair_color) || - (p->clothes_color != cp->clothes_color) || (p->weapon != cp->weapon) || - (p->shield != cp->shield) || (p->head_top != cp->head_top) || - (p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || - (p->partner_id != cp->partner_id) || (p->father != cp->father) || - (p->mother != cp->mother) || (p->child != cp->child) || (p->fame != cp->fame)) - { //Save status - - //Check for party - party_exist=1; - sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `party_id` = '%d'",party_db, p->party_id); // TBR - if (mysql_query(&mysql_handle, tmp_sql)) { - ShowSQL("DB Error - %s\n", mysql_error(&mysql_handle)); - } else { //In case of failure, don't touch the data. [Skotlex - sql_res = mysql_store_result(&mysql_handle); - sql_row = mysql_fetch_row(sql_res); - if (sql_row) - party_exist = atoi(sql_row[0]); - mysql_free_result(sql_res); - } - - //check guild_exist - guild_exist=1; - sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `guild_id` = '%d'",guild_db, p->guild_id); // TBR - if (mysql_query(&mysql_handle, tmp_sql)) { - ShowSQL("DB Error (select guild): %s\n", mysql_error(&mysql_handle)); - } else { //If we fail to confirm, don't touch the data. - sql_res = mysql_store_result(&mysql_handle); - sql_row = mysql_fetch_row(sql_res); - if (sql_row) - guild_exist = atoi(sql_row[0]); - mysql_free_result(sql_res); - } - if (guild_exist==0) p->guild_id=0; - */ - if (party_exist==0) p->party_id=0; //Parties are not converted. [Skotlex] - - //sql query - //`char`( `char_id`,`account_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`, //9 - //`str`,`agi`,`vit`,`int`,`dex`,`luk`, //15 - //`max_hp`,`hp`,`max_sp`,`sp`,`status_point`,`skill_point`, //21 - //`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`, //27 - //`hair`,`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`, //35 - //`last_map`,`last_x`,`last_y`,`save_map`,`save_x`,`save_y`) - - //Rather than converting the update to a insert, let's insert a blank char. [Skotlex] - sprintf(tmp_sql, "INSERT INTO `%s` (`char_id`, `account_id`, `name`, `char_num`) VALUES ('%d','%d','%s', '%d')", char_db, char_id, p->account_id, p->name, p->char_num); - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (insert char): %s\n", mysql_error(&mysql_handle)); - //If there is an error, we could assume it already exists, so just update anyway. - - sprintf(tmp_sql ,"UPDATE `%s` SET `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`='%d',`karma`='%d',`manner`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d'," - "`hair`='%d',`hair_color`='%d',`clothes_color`='%d',`weapon`='%d',`shield`='%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', `father`='%d', `mother`='%d', `child`='%d', `fame`='%d'" - "WHERE `account_id`='%d' AND `char_id` = '%d'", - char_db, p->class_, p->base_level, p->job_level, - p->base_exp, p->job_exp, p->zeny, - p->max_hp, p->hp, p->max_sp, p->sp, p->status_point, p->skill_point, - p->str, p->agi, p->vit, p->int_, p->dex, p->luk, - p->option, p->karma, p->manner, p->party_id, p->guild_id, p->pet_id, - p->hair, p->hair_color, p->clothes_color, - p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom, - mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y, - mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->partner_id, p->father, p->mother, - p->child, p->fame, p->account_id, p->char_id - ); - - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (update char): %s\n", mysql_error(&mysql_handle)); - else - strcat(save_status, " status"); -/* - } - diff = 0; - - for(i=0;imemo_point[i].map,cp->memo_point[i].map) == 0) && (p->memo_point[i].x == cp->memo_point[i].x) && (p->memo_point[i].y == cp->memo_point[i].y)) - continue; - diff = 1; - break; - } -*/ - if (diff) - { //Save memo - //`memo` (`memo_id`,`char_id`,`map`,`x`,`y`) - sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",memo_db, p->char_id); - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (delete memo): %s\n", mysql_error(&mysql_handle)); - - //insert here. - tmp_ptr = tmp_sql; - tmp_ptr += sprintf(tmp_ptr, "INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ", memo_db); - count = 0; - for(i=0;imemo_point[i].map){ - tmp_ptr += sprintf(tmp_ptr,"('%d', '%s', '%d', '%d'),", - char_id, mapindex_id2name(p->memo_point[i].map), p->memo_point[i].x, p->memo_point[i].y); - count++; - } - } - if (count) - { //Dangerous? Only if none of the above sprintf worked. [Skotlex] - tmp_ptr[-1] = '\0'; //Remove the trailing comma. - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (insert memo): %s\n", mysql_error(&mysql_handle)); - else - strcat(save_status, " memo"); - } else //Memo Points cleared (how is this possible?). - strcat(save_status, " memo"); - } -/* - diff = 0; - for(i=0;iskill[i].lv != 0) && (p->skill[i].id == 0)) - p->skill[i].id = i; // Fix skill tree - - if((p->skill[i].id != cp->skill[i].id) || (p->skill[i].lv != cp->skill[i].lv) || - (p->skill[i].flag != cp->skill[i].flag)) - { - diff = 1; - break; - } - } -*/ - if (diff) - { //Save skills - - //`skill` (`char_id`, `id`, `lv`) - sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",skill_db, p->char_id); - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (delete skill): %s\n", mysql_error(&mysql_handle)); - - tmp_ptr = tmp_sql; - tmp_ptr += sprintf(tmp_ptr,"INSERT INTO `%s`(`char_id`,`id`,`lv`) VALUES ", skill_db); - count = 0; - //insert here. - for(i=0;iskill[i].id && p->skill[i].flag!=1) - { - tmp_ptr += sprintf(tmp_ptr,"('%d','%d','%d'),", - char_id, p->skill[i].id, (p->skill[i].flag==0)?p->skill[i].lv:p->skill[i].flag-2); - count++; - } - } - - if (count) - { - tmp_ptr[-1] = '\0'; //Remove trailing comma. - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (insert skill): %s\n", mysql_error(&mysql_handle)); - else - strcat(save_status, " skills"); - } else //Skills removed (reset?) - strcat(save_status, " skills"); - } -/* - diff = 0; - for(i=0;iglobal_reg_num;i++) { - if ((p->global_reg[i].str == NULL) && (cp->global_reg[i].str == NULL)) - continue; - if (((p->global_reg[i].str == NULL) != (cp->global_reg[i].str == NULL)) || - (p->global_reg[i].value != cp->global_reg[i].value) || - strcmp(p->global_reg[i].str, cp->global_reg[i].str) != 0 - ) { - diff = 1; - break; - } - } -*/ -/* - if (diff) - { //Save global registry. - //`global_reg_value` (`char_id`, `str`, `value`) - - sprintf(tmp_sql,"DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'",reg_db, p->char_id); - if (mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (delete global_reg_value): %s\n", mysql_error(&mysql_handle)); - - //insert here. - tmp_ptr = tmp_sql; - tmp_ptr += sprintf(tmp_ptr,"INSERT INTO `%s` (`char_id`, `str`, `value`) VALUES", reg_db); - count = 0; - for(i=0;iglobal_reg_num;i++) - { - if (p->global_reg[i].str && p->global_reg[i].value !=0) - { - tmp_ptr += sprintf(tmp_ptr,"('%d','%s','%s'),", - char_id, jstrescapecpy(temp_str,p->global_reg[i].str), p->global_reg[i].value); - if (++count%100 == 0) - { //Save every X registers to avoid overflowing tmp_sql [Skotlex] - tmp_ptr[-1] = '\0'; - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (insert global_reg_value sub): %s\n", mysql_error(&mysql_handle)); - else - strcat(save_status, " global_reg"); - - tmp_ptr = tmp_sql; - tmp_ptr += sprintf(tmp_ptr,"INSERT INTO `%s` (`char_id`, `str`, `value`) VALUES", reg_db); - count = 0; - } - } - } - - if (count) - { - tmp_ptr[-1] = '\0'; - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (insert global_reg_value): %s\n", mysql_error(&mysql_handle)); - else - strcat(save_status, " global_reg"); - } else //Values cleared. - strcat(save_status, " global_reg"); - } -*/ -/* - diff = 0; - for(i = 0; i < MAX_FRIENDS; i++){ - if(p->friend_id[i] != cp->friend_id[i]){ - diff = 1; - break; - } - } - if(diff) - { //Save friends - sprintf(tmp_sql, "DELETE FROM `%s` WHERE `char_id`='%d'", friend_db, char_id); - if(mysql_query(&mysql_handle, tmp_sql)){ - ShowSQL("DB Error (delete friend): %s\n", mysql_error(&mysql_handle)); - } - - tmp_ptr = tmp_sql; - tmp_ptr += sprintf(tmp_ptr, "INSERT INTO `%s` (`char_id`, `friend_id`) VALUES ", friend_db); - count = 0; - for(i = 0; i < MAX_FRIENDS; i++){ - if(p->friend_id[i] > 0) - { - tmp_ptr += sprintf(tmp_ptr, "('%d', '%d'),", char_id, p->friend_id[i]); - count++; - } - } - if (count) - { - tmp_ptr[-1] = '\0'; //Remove the last comma. [Skotlex] - if(mysql_query(&mysql_handle, tmp_sql)) - ShowSQL("DB Error (insert friend): %s\n", mysql_error(&mysql_handle)); - else - strcat(save_status, " friends"); - } else //Friend list cleared. - strcat(save_status, " friends"); - - } -*/ - ShowInfo("Saved char %d:%s.\n", char_id, save_status); -// memcpy(cp, p, sizeof(struct mmo_charstatus)); - - return 0; -} - //-------------------------------------------------------- -// Save registry to sql -int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type){ - - int j; - char temp_str[64]; //Needs be twice the source to ensure it fits [Skotlex] - char temp_str2[512]; - if (account_id<=0) return 0; - - switch (type) { - case 3: //Char Reg - //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`) - sprintf(tmp_sql,"DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'",reg_db, char_id); - break; - case 2: //Account Reg - //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`) - sprintf(tmp_sql,"DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'",reg_db, account_id); - break; - case 1: //Account2 Reg - ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); - return 0; - default: - ShowError("inter_accreg_tosql: Invalid type %d\n", type); - return 0; - - } - if(mysql_query(&mysql_handle, tmp_sql) ) { - ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); - ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); - } - - if (reg->reg_num<=0) return 0; - - for(j=0;jreg_num;j++){ - if(reg->reg[j].str != NULL){ - sprintf(tmp_sql,"INSERT INTO `%s` (`type`, `account_id`, `char_id`, `str`, `value`) VALUES ('%d','%d','%d','%s','%s')", - reg_db, type, type!=3?account_id:0, type==3?char_id:0, - jstrescapecpy(temp_str,reg->reg[j].str), jstrescapecpy(temp_str2,reg->reg[j].value)); - if(mysql_query(&mysql_handle, tmp_sql) ) { - ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); - ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); - } - } - } - return 1; -} -//Note: Keep this function updated with the one in src/char/int_storage.c [Skotlex] -int storage_fromstr(char *str,struct storage *p) -{ - int tmp_int[256]; - int set,next,len,i; - - set=sscanf(str,"%d,%d%n",&tmp_int[0],&tmp_int[1],&next); - p->storage_amount=tmp_int[1]; - - if(set!=2) - return 1; - if(str[next]=='\n' || str[next]=='\r') - return 0; - next++; - for(i=0;str[next] && str[next]!='\t';i++){ - if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3], - &tmp_int[4], &tmp_int[5], &tmp_int[6], - &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[10], &len) == 12) { - p->storage_[i].id = tmp_int[0]; - p->storage_[i].nameid = tmp_int[1]; - p->storage_[i].amount = tmp_int[2]; - p->storage_[i].equip = tmp_int[3]; - p->storage_[i].identify = tmp_int[4]; - p->storage_[i].refine = tmp_int[5]; - p->storage_[i].attribute = tmp_int[6]; - p->storage_[i].card[0] = tmp_int[7]; - p->storage_[i].card[1] = tmp_int[8]; - p->storage_[i].card[2] = tmp_int[9]; - p->storage_[i].card[3] = tmp_int[10]; - next += len; - if (str[next] == ' ') - next++; - } - - else if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n", - &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3], - &tmp_int[4], &tmp_int[5], &tmp_int[6], - &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &len) == 11) { - p->storage_[i].id = tmp_int[0]; - p->storage_[i].nameid = tmp_int[1]; - p->storage_[i].amount = tmp_int[2]; - p->storage_[i].equip = tmp_int[3]; - p->storage_[i].identify = tmp_int[4]; - p->storage_[i].refine = tmp_int[5]; - p->storage_[i].attribute = tmp_int[6]; - p->storage_[i].card[0] = tmp_int[7]; - p->storage_[i].card[1] = tmp_int[8]; - p->storage_[i].card[2] = tmp_int[9]; - p->storage_[i].card[3] = tmp_int[10]; - next += len; - if (str[next] == ' ') - next++; - } - - else return 1; - } - return 0; -} - -//Note: Keep this function synched with the one in src/char_sql/int_storage.c -int storage_tosql(int account_id,struct storage *p){ - int i; -// int eqcount=1; -// int noteqcount=1; - int count=0; - struct itemtmp mapitem[MAX_GUILD_STORAGE]; - for(i=0;istorage_[i].nameid>0){ - mapitem[count].flag=0; - mapitem[count].id = p->storage_[i].id; - mapitem[count].nameid=p->storage_[i].nameid; - mapitem[count].amount = p->storage_[i].amount; - mapitem[count].equip = p->storage_[i].equip; - mapitem[count].identify = p->storage_[i].identify; - mapitem[count].refine = p->storage_[i].refine; - mapitem[count].attribute = p->storage_[i].attribute; - mapitem[count].card[0] = p->storage_[i].card[0]; - mapitem[count].card[1] = p->storage_[i].card[1]; - mapitem[count].card[2] = p->storage_[i].card[2]; - mapitem[count].card[3] = p->storage_[i].card[3]; - count++; - } - } - - memitemdata_to_sql(mapitem, count, account_id,TABLE_STORAGE); - - //printf ("storage dump to DB - id: %d (total: %d)\n", account_id, j); - return 0; -} - -//Note: Keep updated with the function in src/char/int_pet.c [Skotlex] -int inter_pet_fromstr(char *str,struct s_pet *p) -{ - int s; - int tmp_int[16]; - char tmp_str[256]; - - memset(p,0,sizeof(struct s_pet)); - -// printf("sscanf pet main info\n"); - s=sscanf(str,"%d,%d,%[^\t]\t%d,%d,%d,%d,%d,%d,%d,%d,%d",&tmp_int[0],&tmp_int[1],tmp_str,&tmp_int[2], - &tmp_int[3],&tmp_int[4],&tmp_int[5],&tmp_int[6],&tmp_int[7],&tmp_int[8],&tmp_int[9],&tmp_int[10]); - - if(s!=12) - return 1; - - p->pet_id = tmp_int[0]; - p->class_ = tmp_int[1]; - memcpy(p->name,tmp_str,NAME_LENGTH-1); - p->account_id = tmp_int[2]; - p->char_id = tmp_int[3]; - p->level = tmp_int[4]; - p->egg_id = tmp_int[5]; - p->equip = tmp_int[6]; - p->intimate = tmp_int[7]; - p->hungry = tmp_int[8]; - p->rename_flag = tmp_int[9]; - p->incuvate = tmp_int[10]; - - if(p->hungry < 0) - p->hungry = 0; - else if(p->hungry > 100) - p->hungry = 100; - if(p->intimate < 0) - p->intimate = 0; - else if(p->intimate > 1000) - p->intimate = 1000; - - return 0; -} - -//Note: Keep updated with the function in src/char_sql/int_pet.c [Skotlex] -int inter_pet_tosql(int pet_id, struct s_pet *p) { - //`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) - char t_name[NAME_LENGTH*2]; - - ShowInfo("Saving pet (%d)...\n",pet_id); - - jstrescapecpy(t_name, p->name); - - if(p->hungry < 0) - p->hungry = 0; - else if(p->hungry > 100) - p->hungry = 100; - if(p->intimate < 0) - p->intimate = 0; - else if(p->intimate > 1000) - p->intimate = 1000; - sprintf(tmp_sql,"SELECT * FROM `%s` WHERE `pet_id`='%d'",pet_db, pet_id); - if(mysql_query(&mysql_handle, tmp_sql) ) { - ShowSQL("DB server Error - %s\n", mysql_error(&mysql_handle) ); - } - sql_res = mysql_store_result(&mysql_handle) ; - if (sql_res!=NULL && mysql_num_rows(sql_res)>0) - //row reside -> updating - sprintf(tmp_sql, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incuvate`='%d' WHERE `pet_id`='%d'", - pet_db, p->class_, t_name, p->account_id, p->char_id, p->level, p->egg_id, - p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate, p->pet_id); - else //no row -> insert - sprintf(tmp_sql,"INSERT INTO `%s` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) VALUES ('%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')", - pet_db, pet_id, p->class_, t_name, p->account_id, p->char_id, p->level, p->egg_id, - p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate); - mysql_free_result(sql_res) ; //resource free - if(mysql_query(&mysql_handle, tmp_sql) ) { - ShowSQL("DB server Error (inset/update `pet`)- %s\n", mysql_error(&mysql_handle) ); - } - - ShowInfo("Pet saved (%d). \n", pet_id); - return 0; -} - - -int mmo_char_init(void){ +int convert_init(void){ char line[65536]; - struct storage *storage_ = NULL; - struct s_pet *p; int ret; - int i=0,set,tmp_int[2], c= 0; + int set,tmp_int[2], lineno, count; char input; FILE *fp; - mysql_init(&mysql_handle); - ShowInfo("Connect DB server.... (inter server)\n"); - if(!mysql_real_connect(&mysql_handle, db_server_ip, db_server_id, db_server_pw, - db_server_logindb ,db_server_port, (char *)NULL, 0)) { - //pointer check - ShowFatalError("%s\n",mysql_error(&mysql_handle)); - exit(1); - } - else { - ShowStatus ("connect success! (inter server)\n"); - } - ShowWarning("Make sure you backup your databases before continuing!\n"); printf("\n"); ShowNotice("Do you wish to convert your Character Database to SQL? (y/n) : "); input=getchar(); if(input == 'y' || input == 'Y'){ + struct character_data char_dat; + struct accreg reg; + ShowStatus("Converting Character Database...\n"); - fp=fopen("save/athena.txt","r"); - char_dat = (struct character_data*)malloc(sizeof(struct character_data)*256); - char_max=256; - if(fp==NULL) + fp = fopen(char_txt, "r"); + memset (&char_dat, 0, sizeof(struct character_data)); + if(fp==NULL) { + ShowError("Unable to open file [%s]!\n", char_txt); return 0; + } + lineno = count = 0; while(fgets(line, 65535, fp)){ - if(char_num>=char_max){ - char_max+=256; - char_dat = (struct character_data*)realloc(char_dat, sizeof(char_dat[0]) *char_max); - } - memset(&char_dat[char_num], 0, sizeof(char_dat[0])); - ret=mmo_char_fromstr(line, &char_dat[char_num].status, &char_dat[char_num].global); - if(ret){ - mmo_char_tosql(char_dat[char_num].status.char_id , &char_dat[char_num].status); - inter_accreg_tosql(char_dat[char_num].status.account_id, char_dat[char_num].status.char_id, &char_dat[char_num].global, 3); //Type 3: Character regs - if(char_dat[char_num].status.char_id>=char_id_count) - char_id_count=char_dat[char_num].status.char_id+1; - char_num++; + lineno++; + memset(&char_dat, 0, sizeof(char_dat)); + ret=mmo_char_fromstr(line, &char_dat.status, char_dat.global, &char_dat.global_num); + if(ret > 0){ + count++; + parse_friend_txt(&char_dat.status); //Retrieve friends. + mmo_char_tosql(char_dat.status.char_id , &char_dat.status); + + memset(®, 0, sizeof(reg)); + reg.account_id = char_dat.status.account_id; + reg.char_id = char_dat.status.char_id; + reg.reg_num = char_dat.global_num; + memcpy(®.reg, &char_dat.global, sizeof(struct global_reg)); + inter_accreg_tosql(reg.account_id, reg.char_id, ®, 3); //Type 3: Character regs + } else { + ShowError("Error %d converting character line [%s] (at %s:%d).\n", ret, line, char_txt, lineno); } } - ShowStatus("char data convert end\n"); + ShowStatus("Converted %d characters.\n", count); + fclose(fp); + ShowStatus("Converting Account variables Database...\n"); + if( (fp=fopen(accreg_txt,"r")) ==NULL ) + { + ShowError("Unable to open file %s!", accreg_txt); + return 1; + } + lineno=count=0; + while(fgets(line, sizeof(line), fp)){ + lineno++; + memset (®, 0, sizeof(struct accreg)); + if(inter_accreg_fromstr(line, ®) == 0 && reg.account_id > 0) { + count++; + inter_accreg_tosql(reg.account_id, 0, ®, 3); //Type 2: Account regs + }else{ + ShowError("accreg reading: broken data [%s] at %s:%d\n", line, accreg_txt, lineno); + } + } + ShowStatus("Converted %d account registries.\n", count); fclose(fp); } @@ -1165,6 +101,7 @@ int mmo_char_init(void){ ShowNotice("Do you wish to convert your Storage Database to SQL? (y/n) : "); input=getchar(); if(input == 'y' || input == 'Y') { + struct storage storage_; printf("\n"); ShowStatus("Converting Storage Database...\n"); fp=fopen(storage_txt,"r"); @@ -1172,22 +109,22 @@ int mmo_char_init(void){ ShowError("cant't read : %s\n",storage_txt); return 0; } - + lineno=count=0; while(fgets(line,65535,fp)){ + lineno++; set=sscanf(line,"%d,%d",&tmp_int[0],&tmp_int[1]); if(set==2) { - if(i==0){ - storage_ = (struct storage*)malloc(sizeof(struct storage)); - }else{ - storage_ = (struct storage*)realloc(storage_,sizeof(struct storage)*(i+1)); + memset(&storage_, 0, sizeof(struct storage)); + storage_.account_id=tmp_int[0]; + if (storage_fromstr(line,&storage_) == 0) { + count++; + storage_tosql(storage_.account_id,&storage_); //to sql. (dump) + } else { + ShowError("Error parsing storage line [%s] (at %s:%d)\n", line, storage_txt, lineno); } - memset(&storage_[i],0,sizeof(struct storage)); - storage_[i].account_id=tmp_int[0]; - storage_fromstr(line,&storage_[i]); - storage_tosql(tmp_int[0],&storage_[i]); //to sql. (dump) - i++; } } + ShowStatus("Converted %d storages.\n", count); fclose(fp); } @@ -1196,162 +133,146 @@ int mmo_char_init(void){ ShowNotice("Do you wish to convert your Pet Database to SQL? (y/n) : "); input=getchar(); if(input == 'y' || input == 'Y') { + struct s_pet p; printf("\n"); ShowStatus("Converting Pet Database...\n"); if( (fp=fopen(pet_txt,"r")) ==NULL ) + { + ShowError("Unable to open file %s!", pet_txt); return 1; - p = (struct s_pet*)malloc(sizeof(struct s_pet)); + } + lineno=count=0; while(fgets(line, sizeof(line), fp)){ - if(p==NULL){ - ShowFatalError("int_pet: out of memory!\n"); - exit(0); - } - if(inter_pet_fromstr(line, p)==0 && p->pet_id>0){ - //pet dump - inter_pet_tosql(p->pet_id,p); + lineno++; + memset (&p, 0, sizeof(struct s_pet)); + if(inter_pet_fromstr(line, &p)==0 && p.pet_id>0){ + count++; + inter_pet_tosql(p.pet_id,&p); }else{ - ShowError("int_pet: broken data [%s] line %d\n", pet_txt, c); + ShowError("pet reading: broken data [%s] at %s:%d\n", line, pet_txt, lineno); } - c++; } + ShowStatus("Converted %d pets.\n", count); fclose(fp); } - return 0; -} -int inter_config_read(const char *cfgName) { - int i; - char line[1024], w1[1024], w2[1024]; - FILE *fp; - - ShowStatus("Start reading interserver configuration: %s\n",cfgName); - - fp=fopen(cfgName,"r"); - if(fp==NULL){ - ShowError("File not found: %s\n", cfgName); - return 1; - } - while(fgets(line, 1020, fp)){ - i=sscanf(line,"%[^:]:%s", w1, w2); - if(i!=2) - continue; - if(strcmpi(w1,"storage_txt")==0){ - ShowInfo ("set storage_txt : %s\n",w2); - strncpy(storage_txt, w2, sizeof(storage_txt)); - } else if(strcmpi(w1,"pet_txt")==0){ - ShowInfo ("set pet_txt : %s\n",w2); - strncpy(pet_txt, w2, sizeof(pet_txt)); + while(getchar() != '\n'); + printf("\n"); + ShowNotice("Do you wish to convert your Party Database to SQL? (y/n) : "); + input=getchar(); + if(input == 'y' || input == 'Y') { + struct party p; + printf("\n"); + ShowStatus("Converting Party Database...\n"); + if( (fp=fopen(party_txt,"r")) ==NULL ) + { + ShowError("Unable to open file %s!", party_txt); + return 1; } - //add for DB connection - else if(strcmpi(w1,"db_server_ip")==0){ - strcpy(db_server_ip, w2); - ShowInfo ("set db_server_ip : %s\n",w2); + lineno=count=0; + while(fgets(line, sizeof(line), fp)){ + lineno++; + memset (&p, 0, sizeof(struct party)); + if(inter_party_fromstr(line, &p) == 0 && + p.party_id > 0 && + inter_party_tosql(&p, PS_CREATE, 0)) + count++; + else{ + ShowError("party reading: broken data [%s] at %s:%d\n", line, pet_txt, lineno); + } } - else if(strcmpi(w1,"db_server_port")==0){ - db_server_port=atoi(w2); - ShowInfo ("set db_server_port : %s\n",w2); - } - else if(strcmpi(w1,"db_server_id")==0){ - strcpy(db_server_id, w2); - ShowInfo ("set db_server_id : %s\n",w2); - } - else if(strcmpi(w1,"db_server_pw")==0){ - strcpy(db_server_pw, w2); - ShowInfo ("set db_server_pw : %s\n",w2); - } - else if(strcmpi(w1,"db_server_logindb")==0){ - strcpy(db_server_logindb, w2); - ShowInfo ("set db_server_logindb : %s\n",w2); - } - else if(strcmpi(w1,"char_db")==0){ - strcpy(char_db, w2); - ShowInfo ("set char_db : %s\n",w2); - } - else if(strcmpi(w1,"cart_db")==0){ - strcpy(cart_db, w2); - ShowInfo ("set cart_db : %s\n",w2); - } - else if(strcmpi(w1,"inventory_db")==0){ - strcpy(inventory_db, w2); - ShowInfo ("set inventory_db : %s\n",w2); - } - else if(strcmpi(w1,"storage_db")==0){ - strcpy(storage_db, w2); - ShowInfo ("set storage_db : %s\n",w2); - } - else if(strcmpi(w1,"reg_db")==0){ - strcpy(reg_db, w2); - ShowInfo ("set reg_db : %s\n",w2); - } - else if(strcmpi(w1,"skill_db")==0){ - strcpy(skill_db, w2); - ShowInfo ("set skill_db : %s\n",w2); - } - else if(strcmpi(w1,"memo_db")==0){ - strcpy(memo_db, w2); - ShowInfo ("set memo_db : %s\n",w2); - } - else if(strcmpi(w1,"pet_db")==0){ - strcpy(pet_db, w2); - ShowInfo ("set pet_db : %s\n",w2); - } - else if(strcmpi(w1,"friend_db")==0){ - strcpy(friend_db, w2); - ShowInfo ("set friend_db : %s\n",w2); - //support the import command, just like any other config - }else if(strcmpi(w1,"import")==0){ - inter_config_read(w2); - } - } - fclose(fp); - - ShowStatus("Done reading %s.\n", cfgName); - - return 0; -} - -int char_config_read(const char *cfgName) { - int i; - char line[1024], w1[1024], w2[1024]; - FILE *fp; - - ShowStatus ("Start reading char-server configuration: %s\n",cfgName); - - fp=fopen(cfgName,"r"); - if(fp==NULL){ - ShowError("File not found: %s\n", cfgName); - return 1; + ShowStatus("Converted %d parties.\n", count); + fclose(fp); } - while(fgets(line, 1020, fp)){ - if(line[0] == '/' && line[1] == '/') - continue; + while(getchar() != '\n'); + printf("\n"); + ShowNotice("Do you wish to convert your Guilds/Guild Castles Database to SQL? (y/n) : "); + input=getchar(); + if(input == 'y' || input == 'Y') { + struct guild g; + struct guild_castle gc; + printf("\n"); + ShowStatus("Converting Guild Database...\n"); + if( (fp=fopen(guild_txt,"r")) ==NULL ) + { + ShowError("Unable to open file %s!", guild_txt); + return 1; + } + lineno=count=0; + while(fgets(line, sizeof(line), fp)){ + lineno++; + memset (&g, 0, sizeof(struct guild)); + if (inter_guild_fromstr(line, &g) == 0 && + g.guild_id > 0 && + inter_guild_tosql(&g,GS_MASK)) + count++; + else + ShowError("guild reading: broken data [%s] at %s:%d\n", line, guild_txt, lineno); + } + ShowStatus("Converted %d guilds.\n", count); + fclose(fp); + ShowStatus("Converting Guild Castles Database...\n"); + if( (fp=fopen(castle_txt,"r")) ==NULL ) + { + ShowError("Unable to open file %s!", castle_txt); + return 1; + } + lineno=count=0; + while(fgets(line, sizeof(line), fp)){ + lineno++; + memset (&gc, 0, sizeof(struct guild_castle)); + if (inter_guildcastle_fromstr(line, &gc) == 0) { + inter_guildcastle_tosql(&gc); + count++; + } + else + ShowError("guild castle reading: broken data [%s] at %s:%d\n", line, castle_txt, lineno); + } + ShowStatus("Converted %d guild castles.\n", count); + fclose(fp); + } - i=sscanf(line,"%[^:]:%s", w1, w2); - if(i!=2) - continue; - if(strcmpi(w1,"char_txt")==0){ - ShowInfo ("set char_txt : %s\n",w2); - strcpy(char_txt, w2); + while(getchar() != '\n'); + printf("\n"); + ShowNotice("Do you wish to convert your Guild Storage Database to SQL? (y/n) : "); + input=getchar(); + if(input == 'y' || input == 'Y') { + struct guild_storage storage_; + printf("\n"); + ShowStatus("Converting Guild Storage Database...\n"); + fp=fopen(guild_storage_txt,"r"); + if(fp==NULL){ + ShowError("cant't read : %s\n",guild_storage_txt); + return 0; + } + lineno=count=0; + while(fgets(line,65535,fp)){ + lineno++; + memset(&storage_, 0, sizeof(struct guild_storage)); + if (sscanf(line,"%d",&storage_.guild_id) == 1 && + storage_.guild_id > 0 && + guild_storage_fromstr(line,&storage_) == 0 + ) { + count++; + guild_storage_tosql(storage_.guild_id, &storage_); } else - if(strcmpi(w1,"friends_txt")==0){ - ShowInfo ("set friends_txt : %s\n",w2); - strcpy(friends_txt, w2); - } + ShowError("Error parsing guild storage line [%s] (at %s:%d)\n", line, guild_storage_txt, lineno); } + ShowStatus("Converted %d guild storages.\n", count); fclose(fp); - ShowStatus("Done reading %s.\n", cfgName); - + } return 0; } int do_init(int argc, char **argv){ char_config_read((argc>1)?argv[1]:CHAR_CONF_NAME); - inter_config_read((argc>2)?argv[2]:INTER_CONF_NAME); mapindex_init(); - - mmo_char_init(); + sql_config_read((argc>2)?argv[2]:SQL_CONF_NAME); + inter_init_txt((argc > 3) ? argv[3] :INTER_CONF_NAME); + inter_init_sql((argc > 3) ? argv[3] :INTER_CONF_NAME); + convert_init(); ShowStatus("Everything's been converted!\n"); mapindex_final(); exit (0);