From 63c2c3779bb0897bd61793fe9fe7cd8b65e4bfc0 Mon Sep 17 00:00:00 2001 From: Dastgir Date: Thu, 26 Jul 2018 10:08:21 +0530 Subject: Extended db2sql plugin to allow generation of mob_skill_db sql files. Fixes #2128 --- src/plugins/db2sql.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 329 insertions(+), 1 deletion(-) (limited to 'src/plugins/db2sql.c') diff --git a/src/plugins/db2sql.c b/src/plugins/db2sql.c index 57e68432e..2ece501b2 100644 --- a/src/plugins/db2sql.c +++ b/src/plugins/db2sql.c @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2015 Hercules Dev Team + * Copyright (C) 2013-2018 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 @@ -70,6 +70,10 @@ bool mobdb2sql_torun = false; int (*itemdb_readdb_libconfig_sub) (struct config_setting_t *it, int n, const char *source); /// Backup of the original mob_db parser function pointer. int (*mob_read_db_sub) (struct config_setting_t *it, int n, const char *source); +bool (*mob_skill_db_libconfig_sub_skill) (struct config_setting_t *it, int n, int mob_id); + +// +void do_mobskilldb2sql(void); /** * Normalizes and appends a string to the output buffer. @@ -811,6 +815,330 @@ void do_mobdb2sql(void) if (tosql.buf[i].p) aFree(tosql.buf[i].p); } + + // Run mob_skill_db converter + do_mobskilldb2sql(); +} + +/** + * Converts Mob Skill State constant to string + */ +const char* mob_skill_state_tostring(enum MobSkillState mss) +{ + switch(mss) { + case MSS_ANY: + return "any"; + case MSS_IDLE: + return "idle"; + case MSS_WALK: + return "walk"; + case MSS_LOOT: + return "loot"; + case MSS_DEAD: + return "dead"; + case MSS_BERSERK: + return "attack"; + case MSS_ANGRY: + return "angry"; + case MSS_RUSH: + return "chase"; + case MSS_FOLLOW: + return "follow"; + case MSS_ANYTARGET: + return "anytarget"; + } + + return "unknown"; +} + +/** + * Converts Mob Skill Target constant to string + */ +const char* mob_skill_target_tostring(int target) +{ + switch(target) { + case MST_TARGET: + return "target"; + case MST_RANDOM: + return "randomtarget"; + case MST_SELF: + return "self"; + case MST_FRIEND: + return "friend"; + case MST_MASTER: + return "master"; + case MST_AROUND1: + return "around1"; + case MST_AROUND2: + return "around2"; + case MST_AROUND3: + return "around3"; + //case MST_AROUND: // same value as MST_AROUND4 + case MST_AROUND4: + return "around4"; + case MST_AROUND5: + return "around5"; + case MST_AROUND6: + return "around6"; + case MST_AROUND7: + return "around7"; + case MST_AROUND8: + return "around8"; + } + return "unknown"; +} + +/** + * Converts Mob Skill Condition constant to string + */ +const char* mob_skill_condition_tostring(int condition) +{ + switch(condition) { + case MSC_ALWAYS: + return "always"; + case MSC_MYHPLTMAXRATE: + return "myhpltmaxrate"; + case MSC_MYHPINRATE: + return "myhpinrate"; + case MSC_FRIENDHPLTMAXRATE: + return "friendhpltmaxrate"; + case MSC_FRIENDHPINRATE: + return "friendhpinrate"; + case MSC_MYSTATUSON: + return "mystatuson"; + case MSC_MYSTATUSOFF: + return "mystatusoff"; + case MSC_FRIENDSTATUSON: + return "friendstatuson"; + case MSC_FRIENDSTATUSOFF: + return "friendstatusoff"; + case MSC_ATTACKPCGT: + return "attackpcgt"; + case MSC_ATTACKPCGE: + return "attackpcge"; + case MSC_SLAVELT: + return "slavelt"; + case MSC_SLAVELE: + return "slavele"; + case MSC_CLOSEDATTACKED: + return "closedattacked"; + case MSC_LONGRANGEATTACKED: + return "longrangeattacked"; + case MSC_AFTERSKILL: + return "afterskill"; + case MSC_SKILLUSED: + return "skillused"; + case MSC_CASTTARGETED: + return "casttargeted"; + case MSC_RUDEATTACKED: + return "rudeattacked"; + case MSC_MASTERHPLTMAXRATE: + return "masterhpltmaxrate"; + case MSC_MASTERATTACKED: + return "masterattacked"; + case MSC_ALCHEMIST: + return "alchemist"; + case MSC_SPAWN: + return "onspawn"; + } + return "unknown"; +} + +/** + * Converts a Mob Skill DB entry to SQL. + * + * @see mob_skill_db_libconfig_sub_skill. + */ +bool mobskilldb2sql_sub(struct config_setting_t *it, int n, int mob_id) +{ + int i32 = 0, i; + StringBuf buf; + struct mob_db *md = mob->db(mob_id); + char valname[15]; + const char *name = config_setting_name(it); + + nullpo_retr(false, it); + Assert_retr(false, mob_id <= 0 || md != mob->dummy); + + StrBuf->Init(&buf); + + // MonsterID + StrBuf->Printf(&buf, "%d,", mob_id); + + // Info + StrBuf->Printf(&buf, "'%s@%s',", md->name, name); + + if (mob->lookup_const(it, "SkillState", &i32) && (i32 < MSS_ANY || i32 > MSS_ANYTARGET)) { + ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill state %d for skill '%s' in monster %d, defaulting to MSS_ANY.\n", i32, name, mob_id); + i32 = MSS_ANY; + } + // State + StrBuf->Printf(&buf, "'%s',", mob_skill_state_tostring(i32)); + + // SkillID + if (!(i32 = skill->name2id(name))) { + ShowWarning("mob_skill_db_libconfig_sub_skill: Non existant skill id %d in monster %d, skipping.\n", i32, mob_id); + return false; + } + StrBuf->Printf(&buf, "%d,", i32); + + // SkillLv + if (!libconfig->setting_lookup_int(it, "SkillLevel", &i32) || i32 <= 0) + i32 = 1; + StrBuf->Printf(&buf, "%d,", i32); + + // Rate + i32 = 0; + libconfig->setting_lookup_int(it, "Rate", &i32); + StrBuf->Printf(&buf, "%d,", i32); + + // CastTime + i32 = 0; + libconfig->setting_lookup_int(it, "CastTime", &i32); + StrBuf->Printf(&buf, "%d,", i32); + + // Delay + i32 = 0; + libconfig->setting_lookup_int(it, "Delay", &i32); + StrBuf->Printf(&buf, "%d,", i32); + + // Cancelable + if (libconfig->setting_lookup_bool(it, "Cancelable", &i32)) { + StrBuf->Printf(&buf, "'%s',", ((i32 == 0) ? "no" : "yes")); + } else { + StrBuf->Printf(&buf, "'no',"); + } + + // Target + if (mob->lookup_const(it, "SkillTarget", &i32) && (i32 < MST_TARGET || i32 > MST_AROUND)) { + i32 = MST_TARGET; + } + StrBuf->Printf(&buf, "'%s',", mob_skill_target_tostring(i32)); + + // Condition + if (mob->lookup_const(it, "CastCondition", &i32) && (i32 < MSC_ALWAYS || i32 > MSC_SPAWN)) { + i32 = MSC_ALWAYS; + } + StrBuf->Printf(&buf, "'%s',", mob_skill_condition_tostring(i32)); + + // ConditionValue + i32 = 0; + if (mob->lookup_const(it, "ConditionData", &i32)) { + StrBuf->Printf(&buf, "'%d',", i32); + } else { + StrBuf->Printf(&buf, "NULL,"); + } + + // Val1-Val5 + for (i = 0; i < 5; i++) { + sprintf(valname, "val%1d", i); + if (libconfig->setting_lookup_int(it, valname, &i32)) { + StrBuf->Printf(&buf, "%d,", i32); + } else { + StrBuf->Printf(&buf, "NULL,"); + } + } + + // Emotion + if (libconfig->setting_lookup_int(it, "Emotion", &i32)) { + StrBuf->Printf(&buf, "'%d',", i32); + } else { + StrBuf->Printf(&buf, "NULL,"); + } + + if (libconfig->setting_lookup_int(it, "ChatMsgID", &i32) && i32 > 0 && i32 <= MAX_MOB_CHAT) { + StrBuf->Printf(&buf, "'%d'", i32); + } else { + StrBuf->Printf(&buf, "NULL"); + } + + fprintf(tosql.fp, "REPLACE INTO `%s` VALUES (%s);\n", tosql.db_name, StrBuf->Value(&buf)); + + StrBuf->Destroy(&buf); + + return true; + +} + + +/** + * Prints a SQL table header for the current mob_skill_db table. + */ +void mobskilldb2sql_tableheader(void) +{ + db2sql_fileheader(); + + fprintf(tosql.fp, + "--\n" + "-- Table structure for table `%s`\n" + "--\n" + "\n" + "DROP TABLE IF EXISTS `%s`;\n" + "CREATE TABLE `%s` (\n" + " `MOB_ID` SMALLINT(6) NOT NULL,\n" + " `INFO` TEXT NOT NULL,\n" + " `STATE` TEXT NOT NULL,\n" + " `SKILL_ID` SMALLINT(6) NOT NULL,\n" + " `SKILL_LV` TINYINT(4) NOT NULL,\n" + " `RATE` SMALLINT(4) NOT NULL,\n" + " `CASTTIME` MEDIUMINT(9) NOT NULL,\n" + " `DELAY` INT(9) NOT NULL,\n" + " `CANCELABLE` TEXT NOT NULL,\n" + " `TARGET` TEXT NOT NULL,\n" + " `CONDITION` TEXT NOT NULL,\n" + " `CONDITION_VALUE` TEXT,\n" + " `VAL1` INT(11) DEFAULT NULL,\n" + " `VAL2` INT(11) DEFAULT NULL,\n" + " `VAL3` INT(11) DEFAULT NULL,\n" + " `VAL4` INT(11) DEFAULT NULL,\n" + " `VAL5` INT(11) DEFAULT NULL,\n" + " `EMOTION` TEXT,\n" + " `CHAT` TEXT\n" + ") ENGINE=MyISAM;\n" + "\n", tosql.db_name, tosql.db_name, tosql.db_name); +} + +/** + * Mob Skill DB Conversion + */ +void do_mobskilldb2sql(void) +{ + int i; + struct convert_db_files { + const char *name; + const char *source; + const char *destination; + } files[] = { + {"mob_skill_db", DBPATH"mob_skill_db.conf", "sql-files/mob_skill_db" DBSUFFIX ".sql"}, + {"mob_skill_db2", "mob_skill_db2.conf", "sql-files/mob_skill_db2.sql"}, + }; + + /* link */ + mob_skill_db_libconfig_sub_skill = mob->skill_db_libconfig_sub_skill; + mob->skill_db_libconfig_sub_skill = mobskilldb2sql_sub; + + memset(&tosql.buf, 0, sizeof(tosql.buf)); + for (i = 0; i < ARRAYLENGTH(files); i++) { + if ((tosql.fp = fopen(files[i].destination, "wt+")) == NULL) { + ShowError("do_mobskilldb2sql: File not found \"%s\".\n", files[i].destination); + return; + } + + tosql.db_name = files[i].name; + mobskilldb2sql_tableheader(); + + mob->skill_db_libconfig(files[i].source, false); + + fclose(tosql.fp); + } + + /* unlink */ + mob->skill_db_libconfig_sub_skill = mob_skill_db_libconfig_sub_skill; + + for (i = 0; i < ARRAYLENGTH(tosql.buf); i++) { + if (tosql.buf[i].p) + aFree(tosql.buf[i].p); + } } /** -- cgit v1.2.3-60-g2f50