/** * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * * Copyright (C) 2013-2015 Hercules Dev Team * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config/core.h" #include "common/hercules.h" #include "common/cbasetypes.h" #include "common/conf.h" #include "common/memmgr.h" #include "common/mmo.h" #include "common/strlib.h" #include "common/timer.h" #include "map/clif.h" #include "map/itemdb.h" #include "map/map.h" #include "map/pc.h" #include "common/HPMDataCheck.h" #include #include HPExport struct hplugin_info pinfo = { "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) }; struct { FILE *fp; struct { char *p; size_t len; } buf[4]; char *db_name; } tosql; bool torun = false; int (*itemdb_readdb_libconfig_sub) (config_setting_t *it, int n, const char *source); 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); } safestrncpy(tosql.buf[3].p,str,strlen(str)); normalize_name(tosql.buf[3].p,"\t\n "); } int db2sql(config_setting_t *entry, int n, const char *source) { struct item_data *it = NULL; 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); // forceserial StrBuf->Printf(&buf, "'%u',", it->flag.force_serial?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); } 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 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" " `forceserial` 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) { /* link */ 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 = "item_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 = "item_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 = "item_db2"; totable(); itemdb->clear(false); itemdb->readdb_libconfig("item_db2.conf"); fclose(tosql.fp); /* unlink */ itemdb->readdb_libconfig_sub = itemdb_readdb_libconfig_sub; 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); } CPCMD(db2sql) { do_db2sql(); } CMDLINEARG(db2sql) { map->minimal = torun = true; return true; } HPExport void server_preinit(void) { addArg("--db2sql",false,db2sql,NULL); } HPExport void plugin_init(void) { addCPCommand("server:tools:db2sql",db2sql); } HPExport void server_online(void) { if( torun ) do_db2sql(); }