diff options
author | Happy <markaizer@gmail.com> | 2014-08-21 04:50:46 +0800 |
---|---|---|
committer | Happy <markaizer@gmail.com> | 2014-08-21 04:50:46 +0800 |
commit | f52e1007fe08c67003c0bc4c78231904dd3fd5cc (patch) | |
tree | 99907d827264e501774e58ab4630e41fa7103c02 /src/plugins/db2sql.c | |
parent | 2410110dece79b4598c12f1c953219f1d0d1904a (diff) | |
parent | 769b1d05aa5cfa8cddfe7d21b35d5c5e4da3bbd6 (diff) | |
download | hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.tar.gz hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.tar.bz2 hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.tar.xz hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.zip |
Merge pull request #1 from HerculesWS/master
Update from original
Diffstat (limited to 'src/plugins/db2sql.c')
-rw-r--r-- | src/plugins/db2sql.c | 439 |
1 files changed, 340 insertions, 99 deletions
diff --git a/src/plugins/db2sql.c b/src/plugins/db2sql.c index 723a3cc94..751f4be8a 100644 --- a/src/plugins/db2sql.c +++ b/src/plugins/db2sql.c @@ -1,130 +1,371 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file +#include "../config/core.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "../common/HPMi.h" #include "../common/cbasetypes.h" +#include "../common/conf.h" +#include "../common/malloc.h" +#include "../common/mmo.h" #include "../common/strlib.h" #include "../common/timer.h" -#include "../common/HPMi.h" -#include "../common/mmo.h" -#include "../config/core.h" #include "../map/clif.h" -#include "../map/pc.h" -#include "../map/map.h" #include "../map/itemdb.h" -#include <stdio.h> -#include <stdlib.h> +#include "../map/map.h" +#include "../map/pc.h" + +#include "../common/HPMDataCheck.h" HPExport struct hplugin_info pinfo = { - "DB2SQL", // Plugin name - SERVER_TYPE_MAP,// Which server types this plugin works with? - "0.1", // Plugin version - HPM_VERSION, // HPM Version (don't change, macro is automatically updated) + "DB2SQL", // Plugin name + SERVER_TYPE_MAP, // Which server types this plugin works with? + "0.5", // Plugin version + HPM_VERSION, // HPM Version (don't change, macro is automatically updated) }; -SqlStmt* stmt; +struct { + FILE *fp; + struct { + char *p; + size_t len; + } buf[4]; + char *db_name; +} tosql; +bool torun = false; -int (*parse_dbrow)(char** str, const char* source, int line, int scriptopt); +int (*itemdb_readdb_libconfig_sub) (config_setting_t *it, int n, const char *source); -char* trimbraces(char* str) { - size_t start; - size_t end; - - if( str == NULL ) - return str; - - for( start = 0; str[start] && str[start] == '{'; ++start ) - ; - for( end = strlen(str); start < end && str[end-1] && (str[end-1] == '}' || str[end-1] == '\n'); --end ) - ; - if( start == end ) - *str = '\0'; - else { - str[end] = '\0'; - memmove(str,str+start,end-start+1); - trim(str); +void hstr(const char *str) { + if( strlen(str) > tosql.buf[3].len ) { + tosql.buf[3].len = tosql.buf[3].len + strlen(str) + 1000; + RECREATE(tosql.buf[3].p,char,tosql.buf[3].len); } - return str; + safestrncpy(tosql.buf[3].p,str,strlen(str)); + normalize_name(tosql.buf[3].p,"\t\n "); } -int db2sql(char** str, const char* source, int line, int scriptopt) { +int db2sql(config_setting_t *entry, int n, const char *source) { struct item_data *it = NULL; - unsigned char offset = 0; -#ifdef RENEWAL - if( iMap->db_use_sqldbs ) offset = 1; -#endif - if( (it = itemdb->exists(parse_dbrow(str,source,line,scriptopt))) ) { - /* renewal has the 'matk' and 'equip_level' is now 'equip_level_min', and there is a new 'equip_level_max' field */ -#ifdef RENEWAL - if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`matk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level_min`,`equip_level_max`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",iMap->item_db_re_db, - it->nameid,it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->matk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11+offset],NULL,0),atoi(str[12+offset]),atoi(str[13+offset]),atoi(str[14+offset]),it->wlv,it->elv,it->elvmax,atoi(str[17+offset]),it->look) ) -#else - if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",iMap->item_db_db, - it->nameid,it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11],NULL,0),atoi(str[12]),atoi(str[13]),atoi(str[14]),it->wlv,it->elv,atoi(str[17]),it->look) ) -#endif - SqlStmt_ShowDebug(stmt); - else { - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, it->name, strlen(it->name)) ) - SqlStmt_ShowDebug(stmt); - else { - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, it->jname, strlen(it->jname)) ) - SqlStmt_ShowDebug(stmt); - else { - #ifdef RENEWAL - if( iMap->db_use_sqldbs ) offset += 1; - #endif - if( it->script ) trimbraces(str[19+offset]); - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_STRING, it->script?str[19+offset]:"", it->script?strlen(str[19+offset]):0) ) - SqlStmt_ShowDebug(stmt); - else { - if( it->equip_script ) trimbraces(str[20+offset]); - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 3, SQLDT_STRING, it->equip_script?str[20+offset]:"", it->equip_script?strlen(str[20+offset]):0) ) - SqlStmt_ShowDebug(stmt); - else { - if( it->unequip_script ) trimbraces(str[21+offset]); - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 4, SQLDT_STRING, it->unequip_script?str[21+offset]:"", it->unequip_script?strlen(str[21+offset]):0) ) - SqlStmt_ShowDebug(stmt); - else { - if( SQL_SUCCESS != SQL->StmtExecute(stmt) ) - SqlStmt_ShowDebug(stmt); - } - } - } - } + + if( (it = itemdb->exists(itemdb_readdb_libconfig_sub(entry,n,source))) ) { + char e_name[ITEM_NAME_LENGTH*2+1]; + const char *bonus = NULL; + char *str; + int i32; + unsigned int ui32; + config_setting_t *t = NULL; + StringBuf buf; + + StrBuf->Init(&buf); + + // id + StrBuf->Printf(&buf, "'%u',", it->nameid); + + // name_english + SQL->EscapeString(NULL, e_name, it->name); + StrBuf->Printf(&buf, "'%s',", e_name); + + // name_japanese + SQL->EscapeString(NULL, e_name, it->jname); + StrBuf->Printf(&buf, "'%s',", e_name); + + // type + StrBuf->Printf(&buf, "'%u',", it->flag.delay_consume?IT_DELAYCONSUME:it->type); + + // price_buy + StrBuf->Printf(&buf, "'%u',", it->value_buy); + + // price_sell + StrBuf->Printf(&buf, "'%u',", it->value_sell); + + // weight + StrBuf->Printf(&buf, "'%u',", it->weight); + + // atk + StrBuf->Printf(&buf, "'%u',", it->atk); + + // matk + StrBuf->Printf(&buf, "'%u',", it->matk); + + // defence + StrBuf->Printf(&buf, "'%u',", it->def); + + // range + StrBuf->Printf(&buf, "'%u',", it->range); + + // slots + StrBuf->Printf(&buf, "'%u',", it->slot); + + // equip_jobs + if( libconfig->setting_lookup_int(entry, "Job", &i32) ) // This is an unsigned value, do not check for >= 0 + ui32 = (unsigned int)i32; + else + ui32 = UINT_MAX; + StrBuf->Printf(&buf, "'%u',", ui32); + + // equip_upper + if( libconfig->setting_lookup_int(entry, "Upper", &i32) && i32 >= 0 ) + ui32 = (unsigned int)i32; + else + ui32 = ITEMUPPER_ALL; + StrBuf->Printf(&buf, "'%u',", ui32); + + // equip_genders + StrBuf->Printf(&buf, "'%u',", it->sex); + + // equip_locations + StrBuf->Printf(&buf, "'%u',", it->equip); + + // weapon_level + StrBuf->Printf(&buf, "'%u',", it->wlv); + + // equip_level_min + StrBuf->Printf(&buf, "'%u',", it->elv); + + // equip_level_max + if( (t = libconfig->setting_get_member(entry, "EquipLv")) && config_setting_is_aggregate(t) && libconfig->setting_length(t) >= 2 ) + StrBuf->Printf(&buf, "'%u',", it->elvmax); + else + StrBuf->AppendStr(&buf, "NULL,"); + + // refineable + StrBuf->Printf(&buf, "'%u',", it->flag.no_refine?0:1); + + // view + StrBuf->Printf(&buf, "'%u',", it->look); + + // bindonequip + StrBuf->Printf(&buf, "'%u',", it->flag.bindonequip?1:0); + + // buyingstore + StrBuf->Printf(&buf, "'%u',", it->flag.buyingstore?1:0); + + // delay + StrBuf->Printf(&buf, "'%u',", it->delay); + + // trade_flag + StrBuf->Printf(&buf, "'%u',", it->flag.trade_restriction); + + // trade_group + if (it->flag.trade_restriction != ITR_NONE && it->gm_lv_trade_override > 0 && it->gm_lv_trade_override < 100) { + StrBuf->Printf(&buf, "'%u',", it->gm_lv_trade_override); + } else { + StrBuf->AppendStr(&buf, "NULL,"); + } + + // nouse_flag + StrBuf->Printf(&buf, "'%u',", it->item_usage.flag); + + // nouse_group + if (it->item_usage.flag != INR_NONE && it->item_usage.override > 0 && it->item_usage.override < 100) { + StrBuf->Printf(&buf, "'%u',", it->item_usage.override); + } else { + StrBuf->AppendStr(&buf, "NULL,"); + } + + // stack_amount + StrBuf->Printf(&buf, "'%u',", it->stack.amount); + + // stack_flag + if (it->stack.amount) { + uint32 value = 0; // FIXME: Use an enum + value |= it->stack.inventory ? 1 : 0; + value |= it->stack.cart ? 2 : 0; + value |= it->stack.storage ? 4 : 0; + value |= it->stack.guildstorage ? 8 : 0; + StrBuf->Printf(&buf, "'%u',", value); + } else { + StrBuf->AppendStr(&buf, "NULL,"); + } + + // sprite + if (it->flag.available) { + StrBuf->Printf(&buf, "'%u',", it->view_id); + } else { + StrBuf->AppendStr(&buf, "NULL,"); + } + + // script + if (it->script) { + libconfig->setting_lookup_string(entry, "Script", &bonus); + hstr(bonus); + str = tosql.buf[3].p; + if (strlen(str) > tosql.buf[0].len) { + tosql.buf[0].len = tosql.buf[0].len + strlen(str) + 1000; + RECREATE(tosql.buf[0].p,char,tosql.buf[0].len); + } + SQL->EscapeString(NULL, tosql.buf[0].p, str); + } + StrBuf->Printf(&buf, "'%s',", it->script?tosql.buf[0].p:""); + + // equip_script + if (it->equip_script) { + libconfig->setting_lookup_string(entry, "OnEquipScript", &bonus); + hstr(bonus); + str = tosql.buf[3].p; + if (strlen(str) > tosql.buf[1].len) { + tosql.buf[1].len = tosql.buf[1].len + strlen(str) + 1000; + RECREATE(tosql.buf[1].p,char,tosql.buf[1].len); + } + SQL->EscapeString(NULL, tosql.buf[1].p, str); + } + StrBuf->Printf(&buf, "'%s',", it->equip_script?tosql.buf[1].p:""); + + // unequip_script + if (it->unequip_script) { + libconfig->setting_lookup_string(entry, "OnUnequipScript", &bonus); + hstr(bonus); + str = tosql.buf[3].p; + if (strlen(str) > tosql.buf[2].len) { + tosql.buf[2].len = tosql.buf[2].len + strlen(str) + 1000; + RECREATE(tosql.buf[2].p,char,tosql.buf[2].len); } + SQL->EscapeString(NULL, tosql.buf[2].p, str); } - return it->nameid; + StrBuf->Printf(&buf, "'%s'", it->unequip_script?tosql.buf[2].p:""); + + fprintf(tosql.fp, "REPLACE INTO `%s` VALUES (%s);\n", tosql.db_name, StrBuf->Value(&buf)); + + StrBuf->Destroy(&buf); } - return 0; -} -CPCMD(db2sql) { - - stmt = SQL->StmtMalloc(mysql_handle); - if( stmt == NULL ) { - SqlStmt_ShowDebug(stmt); + return it?it->nameid:0; +} +void totable(void) { + fprintf(tosql.fp, + "-- NOTE: This file was auto-generated and should never be manually edited,\n" + "-- as it will get overwritten. If you need to modify this file,\n" + "-- please consider modifying the corresponding .conf file inside\n" + "-- the db folder, and then re-run the db2sql plugin.\n" + "\n" + "--\n" + "-- Table structure for table `%s`\n" + "--\n" + "\n" + "DROP TABLE IF EXISTS `%s`;\n" + "CREATE TABLE `%s` (\n" + " `id` smallint(5) UNSIGNED NOT NULL DEFAULT '0',\n" + " `name_english` varchar(50) NOT NULL DEFAULT '',\n" + " `name_japanese` varchar(50) NOT NULL DEFAULT '',\n" + " `type` tinyint(2) UNSIGNED NOT NULL DEFAULT '0',\n" + " `price_buy` mediumint(10) DEFAULT NULL,\n" + " `price_sell` mediumint(10) DEFAULT NULL,\n" + " `weight` smallint(5) UNSIGNED DEFAULT NULL,\n" + " `atk` smallint(5) UNSIGNED DEFAULT NULL,\n" + " `matk` smallint(5) UNSIGNED DEFAULT NULL,\n" + " `defence` smallint(5) UNSIGNED DEFAULT NULL,\n" + " `range` tinyint(2) UNSIGNED DEFAULT NULL,\n" + " `slots` tinyint(2) UNSIGNED DEFAULT NULL,\n" + " `equip_jobs` int(12) UNSIGNED DEFAULT NULL,\n" + " `equip_upper` tinyint(8) UNSIGNED DEFAULT NULL,\n" + " `equip_genders` tinyint(2) UNSIGNED DEFAULT NULL,\n" + " `equip_locations` smallint(4) UNSIGNED DEFAULT NULL,\n" + " `weapon_level` tinyint(2) UNSIGNED DEFAULT NULL,\n" + " `equip_level_min` smallint(5) UNSIGNED DEFAULT NULL,\n" + " `equip_level_max` smallint(5) UNSIGNED DEFAULT NULL,\n" + " `refineable` tinyint(1) UNSIGNED DEFAULT NULL,\n" + " `view` smallint(3) UNSIGNED DEFAULT NULL,\n" + " `bindonequip` tinyint(1) UNSIGNED DEFAULT NULL,\n" + " `buyingstore` tinyint(1) UNSIGNED DEFAULT NULL,\n" + " `delay` mediumint(9) UNSIGNED DEFAULT NULL,\n" + " `trade_flag` smallint(4) UNSIGNED DEFAULT NULL,\n" + " `trade_group` smallint(3) UNSIGNED DEFAULT NULL,\n" + " `nouse_flag` smallint(4) UNSIGNED DEFAULT NULL,\n" + " `nouse_group` smallint(4) UNSIGNED DEFAULT NULL,\n" + " `stack_amount` mediumint(6) UNSIGNED DEFAULT NULL,\n" + " `stack_flag` tinyint(2) UNSIGNED DEFAULT NULL,\n" + " `sprite` mediumint(6) UNSIGNED DEFAULT NULL,\n" + " `script` text,\n" + " `equip_script` text,\n" + " `unequip_script` text,\n" + " PRIMARY KEY (`id`)\n" + ") ENGINE=MyISAM;\n" + "\n",tosql.db_name,tosql.db_name,tosql.db_name); +} +void do_db2sql(void) { + if( map->db_use_sql_item_db ) { + ShowInfo("db2sql: this should not be used with 'db_use_sql_item_db' enabled, skipping...\n"); return; } - + /* link */ - parse_dbrow = itemdb->parse_dbrow; - itemdb->parse_dbrow = db2sql; - - /* empty table */ - if ( SQL_ERROR == SQL->Query(mysql_handle, "DELETE FROM `%s`", iMap->item_db_db) ) - Sql_ShowDebug(mysql_handle); - else { - itemdb->reload(); - } + itemdb_readdb_libconfig_sub = itemdb->readdb_libconfig_sub; + itemdb->readdb_libconfig_sub = db2sql; + /* */ + + if ((tosql.fp = fopen("sql-files/item_db_re.sql", "wt+")) == NULL) { + ShowError("itemdb_tosql: File not found \"%s\".\n", "sql-files/item_db_re.sql"); + return; + } + + tosql.db_name = map->item_db_re_db; + totable(); + + memset(&tosql.buf, 0, sizeof(tosql.buf) ); + + itemdb->clear(false); + itemdb->readdb_libconfig("re/item_db.conf"); + + fclose(tosql.fp); + + if ((tosql.fp = fopen("sql-files/item_db.sql", "wt+")) == NULL) { + ShowError("itemdb_tosql: File not found \"%s\".\n", "sql-files/item_db.sql"); + return; + } + + tosql.db_name = map->item_db_db; + totable(); + + itemdb->clear(false); + itemdb->readdb_libconfig("pre-re/item_db.conf"); + + fclose(tosql.fp); + + if ((tosql.fp = fopen("sql-files/item_db2.sql", "wt+")) == NULL) { + ShowError("itemdb_tosql: File not found \"%s\".\n", "sql-files/item_db2.sql"); + return; + } + + tosql.db_name = map->item_db2_db; + totable(); + + itemdb->clear(false); + itemdb->readdb_libconfig("item_db2.conf"); + + fclose(tosql.fp); + /* unlink */ - itemdb->parse_dbrow = parse_dbrow; + itemdb->readdb_libconfig_sub = itemdb_readdb_libconfig_sub; - SQL->StmtFree(stmt); + if( tosql.buf[0].p ) aFree(tosql.buf[0].p); + if( tosql.buf[1].p ) aFree(tosql.buf[1].p); + if( tosql.buf[2].p ) aFree(tosql.buf[2].p); + if( tosql.buf[3].p ) aFree(tosql.buf[3].p); } - -HPExport void plugin_init (void) { +CPCMD(db2sql) { + do_db2sql(); +} +void db2sql_arg(char *param) { + map->minimal = torun = true; +} +HPExport void server_preinit (void) { SQL = GET_SYMBOL("SQL"); itemdb = GET_SYMBOL("itemdb"); - iMap = GET_SYMBOL("iMap"); + map = GET_SYMBOL("map"); strlib = GET_SYMBOL("strlib"); + iMalloc = GET_SYMBOL("iMalloc"); + libconfig = GET_SYMBOL("libconfig"); + StrBuf = GET_SYMBOL("StrBuf"); - HPMi->addCPCommand("server:tools:db2sql",CPCMD_A(db2sql)); -}
\ No newline at end of file + addArg("--db2sql",false,db2sql_arg,NULL); +} +HPExport void plugin_init (void) { + addCPCommand("server:tools:db2sql",db2sql); +} +HPExport void server_online (void) { + if( torun ) + do_db2sql(); +} |