From 8c0cfc1716b4e41cbfd30ac0eebd276704c836fc Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 12 Nov 2008 02:03:25 +0300 Subject: [PATCH] [sql/updates/2008_11_11_01_mangos_db_script_string.sql sql/updates/2008_11_11_02_mangos_scripts.sql] Implement localization support for db script command SCRIPT_COMMAND_TALK. Now db script command strings stored in `db_script_string (mangos_string like table). Text field `datatext` replace by int field `dataint` that store index in `db_script_string` table. Indexes must be 2000000000+ (for avoid conflicts with mangos_string indexes). Changes required DB support and SCRIPT_COMMAND_TALK will not work with old data until fixing in DB. --- sql/mangos.sql | 49 +++++++++++++-- .../2008_11_11_01_mangos_db_script_string.sql | 21 +++++++ sql/updates/2008_11_11_02_mangos_scripts.sql | 21 +++++++ sql/updates/Makefile.am | 4 ++ src/game/Chat.cpp | 1 + src/game/Chat.h | 1 + src/game/Language.h | 4 +- src/game/Level3.cpp | 9 +++ src/game/ObjectMgr.cpp | 73 +++++++++++++++++++--- src/game/ObjectMgr.h | 13 +++- src/game/World.cpp | 16 +++-- 11 files changed, 184 insertions(+), 28 deletions(-) create mode 100644 sql/updates/2008_11_11_01_mangos_db_script_string.sql create mode 100644 sql/updates/2008_11_11_02_mangos_scripts.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index df0c142..18be4c8 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, - `required_2008_11_09_03_mangos_mangos_string` bit(1) default NULL + `required_2008_11_11_02_mangos_scripts` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -68,6 +68,15 @@ CREATE TABLE `areatrigger_scripts` ( ) ENGINE = MYISAM DEFAULT CHARSET=utf8; -- +-- Dumping data for table `areatrigger_scripts` +-- + +LOCK TABLES `areatrigger_scripts` WRITE; +/*!40000 ALTER TABLE `areatrigger_scripts` DISABLE KEYS */; +/*!40000 ALTER TABLE `areatrigger_scripts` ENABLE KEYS */; +UNLOCK TABLES; + +-- -- Table structure for table `areatrigger_tavern` -- @@ -814,6 +823,34 @@ LOCK TABLES `creature_template_addon` WRITE; UNLOCK TABLES; -- +-- Table structure for table `db_script_string` +-- + +DROP TABLE IF EXISTS `db_script_string`; +CREATE TABLE `db_script_string` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `content_default` text NOT NULL, + `content_loc1` text, + `content_loc2` text, + `content_loc3` text, + `content_loc4` text, + `content_loc5` text, + `content_loc6` text, + `content_loc7` text, + `content_loc8` text, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `db_script_string` +-- + +LOCK TABLES `db_script_string` WRITE; +/*!40000 ALTER TABLE `db_script_string` DISABLE KEYS */; +/*!40000 ALTER TABLE `db_script_string` ENABLE KEYS */; +UNLOCK TABLES; + +-- -- Table structure for table `disenchant_loot_template` -- @@ -851,7 +888,7 @@ CREATE TABLE `event_scripts` ( `command` mediumint(8) unsigned NOT NULL default '0', `datalong` mediumint(8) unsigned NOT NULL default '0', `datalong2` int(10) unsigned NOT NULL default '0', - `datatext` text NOT NULL, + `dataint` int(11) NOT NULL default '0', `x` float NOT NULL default '0', `y` float NOT NULL default '0', `z` float NOT NULL default '0', @@ -1303,7 +1340,7 @@ CREATE TABLE `gameobject_scripts` ( `command` mediumint(8) unsigned NOT NULL default '0', `datalong` mediumint(8) unsigned NOT NULL default '0', `datalong2` int(10) unsigned NOT NULL default '0', - `datatext` text NOT NULL, + `dataint` int(11) NOT NULL default '0', `x` float NOT NULL default '0', `y` float NOT NULL default '0', `z` float NOT NULL default '0', @@ -10531,7 +10568,7 @@ CREATE TABLE `quest_end_scripts` ( `command` mediumint(8) unsigned NOT NULL default '0', `datalong` mediumint(8) unsigned NOT NULL default '0', `datalong2` int(10) unsigned NOT NULL default '0', - `datatext` text NOT NULL, + `dataint` int(11) NOT NULL default '0', `x` float NOT NULL default '0', `y` float NOT NULL default '0', `z` float NOT NULL default '0', @@ -10558,7 +10595,7 @@ CREATE TABLE `quest_start_scripts` ( `command` mediumint(8) unsigned NOT NULL default '0', `datalong` mediumint(8) unsigned NOT NULL default '0', `datalong2` int(10) unsigned NOT NULL default '0', - `datatext` text NOT NULL, + `dataint` int(11) NOT NULL default '0', `x` float NOT NULL default '0', `y` float NOT NULL default '0', `z` float NOT NULL default '0', @@ -15283,7 +15320,7 @@ CREATE TABLE `spell_scripts` ( `command` mediumint(8) unsigned NOT NULL default '0', `datalong` mediumint(8) unsigned NOT NULL default '0', `datalong2` int(10) unsigned NOT NULL default '0', - `datatext` text NOT NULL, + `dataint` int(11) NOT NULL default '0', `x` float NOT NULL default '0', `y` float NOT NULL default '0', `z` float NOT NULL default '0', diff --git a/sql/updates/2008_11_11_01_mangos_db_script_string.sql b/sql/updates/2008_11_11_01_mangos_db_script_string.sql new file mode 100644 index 0000000..e992b84 --- /dev/null +++ b/sql/updates/2008_11_11_01_mangos_db_script_string.sql @@ -0,0 +1,21 @@ +ALTER TABLE db_version CHANGE COLUMN required_2008_11_09_03_mangos_mangos_string required_2008_11_11_01_mangos_db_script_string bit; + +-- +-- Table structure for table `db_script_string` +-- + +DROP TABLE IF EXISTS `db_script_string`; +CREATE TABLE `db_script_string` ( + `entry` int(11) unsigned NOT NULL default '0', + `content_default` text NOT NULL, + `content_loc1` text, + `content_loc2` text, + `content_loc3` text, + `content_loc4` text, + `content_loc5` text, + `content_loc6` text, + `content_loc7` text, + `content_loc8` text, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + diff --git a/sql/updates/2008_11_11_02_mangos_scripts.sql b/sql/updates/2008_11_11_02_mangos_scripts.sql new file mode 100644 index 0000000..a9fbd10 --- /dev/null +++ b/sql/updates/2008_11_11_02_mangos_scripts.sql @@ -0,0 +1,21 @@ +ALTER TABLE db_version CHANGE COLUMN required_2008_11_11_01_mangos_db_script_string required_2008_11_11_02_mangos_scripts bit; + +ALTER TABLE event_scripts + DROP datatext, + ADD COLUMN dataint int(11) NOT NULL default '0'; + +ALTER TABLE gameobject_scripts + DROP datatext, + ADD COLUMN dataint int(11) NOT NULL default '0'; + +ALTER TABLE quest_end_scripts + DROP datatext, + ADD COLUMN dataint int(11) NOT NULL default '0'; + +ALTER TABLE quest_start_scripts + DROP datatext, + ADD COLUMN dataint int(11) NOT NULL default '0'; + +ALTER TABLE spell_scripts + DROP datatext, + ADD COLUMN dataint int(11) NOT NULL default '0'; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 0e43789..f5a13a3 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -130,6 +130,8 @@ pkgdata_DATA = \ 2008_11_09_01_mangos_command.sql \ 2008_11_09_02_mangos_command.sql \ 2008_11_09_03_mangos_mangos_string.sql \ + 2008_11_11_01_mangos_db_script_string.sql \ + 2008_11_11_02_mangos_scripts.sql \ README ## Additional files to include when running 'make dist' @@ -241,4 +243,6 @@ EXTRA_DIST = \ 2008_11_09_01_mangos_command.sql \ 2008_11_09_02_mangos_command.sql \ 2008_11_09_03_mangos_mangos_string.sql \ + 2008_11_11_01_mangos_db_script_string.sql \ + 2008_11_11_02_mangos_scripts.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index d77838c..068476c 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -217,6 +217,7 @@ ChatCommand * ChatHandler::getCommandTable() { "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL }, { "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL }, { "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL }, + { "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL }, { "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL }, { "fishing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL }, { "game_graveyard_zone", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameGraveyardZoneCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index 86f310e..77a9d51 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -214,6 +214,7 @@ class ChatHandler bool HandleReloadCommandCommand(const char* args); bool HandleReloadCreatureQuestRelationsCommand(const char* args); bool HandleReloadCreatureQuestInvRelationsCommand(const char* args); + bool HandleReloadDbScriptStringCommand(const char* args); bool HandleReloadGameGraveyardZoneCommand(const char* args); bool HandleReloadGameObjectScriptsCommand(const char* args); bool HandleReloadGameTeleCommand(const char* args); diff --git a/src/game/Language.h b/src/game/Language.h index 9f279c0..ad5a2b4 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -707,6 +707,8 @@ enum MangosStrings // Use for custom patches 11000-11999 - // NOT RESERVED IDS 12000- + // NOT RESERVED IDS 12000-1999999999 + // `db_script_string` table index 2000000000-2000009999 (MIN_DB_SCRIPT_STRING_ID-MAX_DB_SCRIPT_STRING_ID) + // For other tables maybe 2000010000-2147483647 (max index) }; #endif diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 6d12b8b..54b307d 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -132,6 +132,7 @@ bool ChatHandler::HandleReloadAllScriptsCommand(const char*) HandleReloadQuestStartScriptsCommand("a"); HandleReloadSpellScriptsCommand("a"); SendGlobalSysMessage("DB tables `*_scripts` reloaded."); + HandleReloadDbScriptStringCommand("a"); return true; } @@ -597,6 +598,14 @@ bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg) return true; } +bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg) +{ + sLog.outString( "Re-Loading Script strings from `db_script_string`..."); + objmgr.LoadDbScriptStrings(); + SendGlobalSysMessage("DB table `db_script_string` reloaded."); + return true; +} + bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/) { sLog.outString( "Re-Loading Graveyard-zone links..."); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index a3fbf67..6350770 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -3651,7 +3651,7 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename) scripts.clear(); // need for reload support - QueryResult *result = WorldDatabase.PQuery( "SELECT id,delay,command,datalong,datalong2,datatext, x, y, z, o FROM %s", tablename ); + QueryResult *result = WorldDatabase.PQuery( "SELECT id,delay,command,datalong,datalong2,dataint, x, y, z, o FROM %s", tablename ); uint32 count = 0; @@ -3673,16 +3673,16 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename) Field *fields = result->Fetch(); ScriptInfo tmp; - tmp.id = fields[0].GetUInt32(); - tmp.delay = fields[1].GetUInt32(); - tmp.command = fields[2].GetUInt32(); - tmp.datalong = fields[3].GetUInt32(); + tmp.id = fields[0].GetUInt32(); + tmp.delay = fields[1].GetUInt32(); + tmp.command = fields[2].GetUInt32(); + tmp.datalong = fields[3].GetUInt32(); tmp.datalong2 = fields[4].GetUInt32(); - tmp.datatext = fields[5].GetCppString(); - tmp.x = fields[6].GetFloat(); - tmp.y = fields[7].GetFloat(); - tmp.z = fields[8].GetFloat(); - tmp.o = fields[9].GetFloat(); + tmp.dataint = fields[5].GetInt32(); + tmp.x = fields[6].GetFloat(); + tmp.y = fields[7].GetFloat(); + tmp.z = fields[8].GetFloat(); + tmp.o = fields[9].GetFloat(); // generic command args check switch(tmp.command) @@ -3694,6 +3694,21 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename) sLog.outErrorDb("Table `%s` has invalid talk type (datalong = %u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.datalong,tmp.id); continue; } + if(tmp.dataint==0) + { + sLog.outErrorDb("Table `%s` has invalid talk text id (dataint = %i) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,tmp.id); + continue; + } + if(tmp.dataint < MIN_DB_SCRIPT_STRING_ID || tmp.dataint >= MAX_DB_SCRIPT_STRING_ID) + { + sLog.outErrorDb("Table `%s` has out of range text id (dataint = %i expected %u-%u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,MIN_DB_SCRIPT_STRING_ID,MAX_DB_SCRIPT_STRING_ID,tmp.id); + continue; + } + if(!objmgr.GetMangosStringLocale(tmp.dataint)) + { + sLog.outErrorDb("Table `%s` has not existed text id (dataint = %i) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,tmp.id); + continue; + } break; } @@ -7184,6 +7199,44 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m return true; } +void ObjectMgr::CheckScripts(ScriptMapMap const& scripts,std::set& ids) +{ + for(ScriptMapMap::const_iterator itrMM = scripts.begin(); itrMM != scripts.end(); ++itrMM) + { + for(ScriptMap::const_iterator itrM = itrMM->second.begin(); itrM != itrMM->second.end(); ++itrM) + { + if(itrM->second.dataint) + { + if(ids.count(itrM->second.dataint)) + ids.erase(itrM->second.dataint); + else + sLog.outErrorDb( "Table `db_script_string` has not existed string id %u", *itrM); + } + } + } +} + +void ObjectMgr::LoadDbScriptStrings() +{ + LoadMangosStrings(WorldDatabase,"db_script_string",MIN_DB_SCRIPT_STRING_ID,MAX_DB_SCRIPT_STRING_ID); + + std::set ids; + + for(int32 i = MIN_DB_SCRIPT_STRING_ID; i < MAX_DB_SCRIPT_STRING_ID; ++i) + if(GetMangosStringLocale(i)) + ids.insert(i); + + CheckScripts(sQuestEndScripts,ids); + CheckScripts(sQuestStartScripts,ids); + CheckScripts(sSpellScripts,ids); + CheckScripts(sGameObjectScripts,ids); + CheckScripts(sEventScripts,ids); + + for(std::set::const_iterator itr = ids.begin(); itr != ids.end(); ++itr) + sLog.outErrorDb( "Table `db_script_string` has unused string id %u", *itr); +} + + // Functions for scripting access const char* GetAreaTriggerScriptNameById(uint32 id) { diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 788934e..4c5a1c4 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -81,7 +81,7 @@ struct ScriptInfo uint32 command; uint32 datalong; uint32 datalong2; - std::string datatext; + int32 dataint; float x; float y; float z; @@ -125,6 +125,13 @@ typedef UNORDERED_MAP MapOb typedef UNORDERED_MAP RespawnTimes; + +// mangos string ranges +#define MIN_MANGOS_STRING_ID 1 +#define MAX_MANGOS_STRING_ID 2000000000 +#define MIN_DB_SCRIPT_STRING_ID MAX_MANGOS_STRING_ID +#define MAX_DB_SCRIPT_STRING_ID 2000010000 + struct MangosStringLocale { std::vector Content; // 0 -> default, i -> i-1 locale index @@ -499,7 +506,8 @@ class ObjectMgr void LoadSpellScripts(); bool LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value); - bool LoadMangosStrings() { return LoadMangosStrings(WorldDatabase,"mangos_string",1,std::numeric_limits::max()); } + bool LoadMangosStrings() { return LoadMangosStrings(WorldDatabase,"mangos_string",MIN_MANGOS_STRING_ID,MAX_MANGOS_STRING_ID); } + void LoadDbScriptStrings(); void LoadPetCreateSpells(); void LoadCreatureLocales(); void LoadCreatureTemplates(); @@ -824,6 +832,7 @@ class ObjectMgr int DBCLocaleIndex; private: void LoadScripts(ScriptMapMap& scripts, char const* tablename); + void CheckScripts(ScriptMapMap const& scripts,std::set& ids); void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr); void LoadQuestRelationsHelper(QuestRelations& map,char const* table); diff --git a/src/game/World.cpp b/src/game/World.cpp index a3322cf..db9bee3 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1141,6 +1141,9 @@ void World::SetInitialWorldSettings() objmgr.LoadGameObjectScripts(); // must be after load Creature/Gameobject(Template/Data) objmgr.LoadEventScripts(); // must be after load Creature/Gameobject(Template/Data) + sLog.outString( "Loading Scripts text locales..." ); // must be after Load*Scripts calls + objmgr.LoadDbScriptStrings(); + sLog.outString( "Initializing Scripts..." ); if(!LoadScriptingModule()) exit(1); @@ -1561,11 +1564,6 @@ void World::ScriptsProcess() sLog.outError("SCRIPT_COMMAND_TALK call for non-creature (TypeId: %u), skipping.",source->GetTypeId()); break; } - if(step.script->datalong > 3) - { - sLog.outError("SCRIPT_COMMAND_TALK invalid chat type (%u), skipping.",step.script->datalong); - break; - } uint64 unit_target = target ? target->GetGUID() : 0; @@ -1573,7 +1571,7 @@ void World::ScriptsProcess() switch(step.script->datalong) { case 0: // Say - ((Creature *)source)->Say(step.script->datatext.c_str(), LANG_UNIVERSAL, unit_target); + ((Creature *)source)->Say(step.script->dataint, LANG_UNIVERSAL, unit_target); break; case 1: // Whisper if(!unit_target) @@ -1581,13 +1579,13 @@ void World::ScriptsProcess() sLog.outError("SCRIPT_COMMAND_TALK attempt to whisper (%u) NULL, skipping.",step.script->datalong); break; } - ((Creature *)source)->Whisper(step.script->datatext.c_str(),unit_target); + ((Creature *)source)->Whisper(step.script->dataint,unit_target); break; case 2: // Yell - ((Creature *)source)->Yell(step.script->datatext.c_str(), LANG_UNIVERSAL, unit_target); + ((Creature *)source)->Yell(step.script->dataint, LANG_UNIVERSAL, unit_target); break; case 3: // Emote text - ((Creature *)source)->TextEmote(step.script->datatext.c_str(), unit_target); + ((Creature *)source)->TextEmote(step.script->dataint, unit_target); break; default: break; // must be already checked at load -- 2.11.4.GIT