From 0f98aec1cd44964fdc766223ed7ee18bbbcab006 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Mon, 27 Dec 2021 17:32:36 -0500 Subject: [PATCH] Core/DB: Unify `creature_respawn` and `gameobject_respawn` into a single `respawn` table Port From (https://github.com/TrinityCore/TrinityCore/commit/be05590a12607cbf6c7f8e5436cfac0fb3625128) --- .../Database/Databases/CharacterDatabase.cs | 29 ++----- .../Maps/Instances/InstanceSaveManager.cs | 3 +- Source/Game/Maps/Map.cs | 66 ++++----------- Source/Game/Server/WorldManager.cs | 2 +- sql/base/characters_database.sql | 82 +++++++------------ ...00_characters_2019_07_14_00_characters.sql | 20 +++++ 6 files changed, 78 insertions(+), 124 deletions(-) create mode 100644 sql/updates/characters/master/2021_12_16_00_characters_2019_07_14_00_characters.sql diff --git a/Source/Framework/Database/Databases/CharacterDatabase.cs b/Source/Framework/Database/Databases/CharacterDatabase.cs index f396df99a..1db072dd5 100644 --- a/Source/Framework/Database/Databases/CharacterDatabase.cs +++ b/Source/Framework/Database/Databases/CharacterDatabase.cs @@ -427,17 +427,11 @@ namespace Framework.Database PrepareStatement(CharStatements.DEL_CORPSE_CUSTOMIZATIONS, "DELETE FROM corpse_customizations WHERE ownerGuid = ?"); PrepareStatement(CharStatements.SEL_CORPSE_LOCATION, "SELECT mapId, posX, posY, posZ, orientation FROM corpse WHERE guid = ?"); - // Creature respawn - PrepareStatement(CharStatements.SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime FROM creature_respawn WHERE mapId = ? AND instanceId = ?"); - PrepareStatement(CharStatements.REP_CREATURE_RESPAWN, "REPLACE INTO creature_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)"); - PrepareStatement(CharStatements.DEL_CREATURE_RESPAWN, "DELETE FROM creature_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?"); - PrepareStatement(CharStatements.DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE mapId = ? AND instanceId = ?"); - - // Gameobject respawn - PrepareStatement(CharStatements.SEL_GO_RESPAWNS, "SELECT guid, respawnTime FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?"); - PrepareStatement(CharStatements.REP_GO_RESPAWN, "REPLACE INTO gameobject_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)"); - PrepareStatement(CharStatements.DEL_GO_RESPAWN, "DELETE FROM gameobject_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?"); - PrepareStatement(CharStatements.DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?"); + // Respawns + PrepareStatement(CharStatements.SEL_RESPAWNS, "SELECT type, spawnId, respawnTime FROM respawn WHERE mapId = ? AND instanceId = ?"); + PrepareStatement(CharStatements.REP_RESPAWN, "REPLACE INTO respawn (type, spawnId, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?, ?)"); + PrepareStatement(CharStatements.DEL_RESPAWN, "DELETE FROM respawn WHERE type = ? AND spawnId = ? AND mapId = ? AND instanceId = ?"); + PrepareStatement(CharStatements.DEL_ALL_RESPAWNS, "DELETE FROM respawn WHERE mapId = ? AND instanceId = ?"); // GM Bug PrepareStatement(CharStatements.SEL_GM_BUGS, "SELECT id, playerGuid, note, createTime, mapId, posX, posY, posZ, facing, closedBy, assignedTo, comment FROM gm_bug"); @@ -1111,15 +1105,10 @@ namespace Framework.Database DEL_CORPSE_CUSTOMIZATIONS, SEL_CORPSE_LOCATION, - SEL_CREATURE_RESPAWNS, - REP_CREATURE_RESPAWN, - DEL_CREATURE_RESPAWN, - DEL_CREATURE_RESPAWN_BY_INSTANCE, - - SEL_GO_RESPAWNS, - REP_GO_RESPAWN, - DEL_GO_RESPAWN, - DEL_GO_RESPAWN_BY_INSTANCE, + SEL_RESPAWNS, + REP_RESPAWN, + DEL_RESPAWN, + DEL_ALL_RESPAWNS, SEL_GM_BUGS, REP_GM_BUG, diff --git a/Source/Game/Maps/Instances/InstanceSaveManager.cs b/Source/Game/Maps/Instances/InstanceSaveManager.cs index 0b4c32585..6bd4db1bb 100644 --- a/Source/Game/Maps/Instances/InstanceSaveManager.cs +++ b/Source/Game/Maps/Instances/InstanceSaveManager.cs @@ -159,8 +159,7 @@ namespace Game.Maps DB.Characters.DirectExecute("DELETE i.* FROM instance AS i LEFT JOIN character_instance AS ci ON i.id = ci.instance LEFT JOIN group_instance AS gi ON i.id = gi.instance WHERE ci.guid IS NULL AND gi.guid IS NULL"); // Delete invalid references to instance - DB.Characters.DirectExecute("DELETE FROM creature_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); - DB.Characters.DirectExecute("DELETE FROM gameobject_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); + DB.Characters.DirectExecute("DELETE FROM respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); DB.Characters.DirectExecute("DELETE tmp.* FROM character_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL"); DB.Characters.DirectExecute("DELETE tmp.* FROM group_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL"); diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 297cdc284..8a6a71a72 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -812,6 +812,7 @@ namespace Game.Maps i_scriptLock = false; } + _weatherUpdateTimer.Update(diff); if (_weatherUpdateTimer.Passed()) { foreach (var zoneInfo in _zoneDynamicInfo) @@ -2547,23 +2548,11 @@ namespace Game.Maps public void RemoveRespawnTime(RespawnInfo info, bool doRespawn = false, SQLTransaction dbTrans = null) { - PreparedStatement stmt; - switch (info.type) - { - case SpawnObjectType.Creature: - stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CREATURE_RESPAWN); - break; - case SpawnObjectType.GameObject: - stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GO_RESPAWN); - break; - default: - Cypher.Assert(false, $"Invalid respawninfo type {info.type} for spawnid {info.spawnId} map {GetId()}"); - return; - } - - stmt.AddValue(0, info.spawnId); - stmt.AddValue(1, GetId()); - stmt.AddValue(2, GetInstanceId()); + PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_RESPAWN); + stmt.AddValue(0, (ushort)info.type); + stmt.AddValue(1, info.spawnId); + stmt.AddValue(2, GetId()); + stmt.AddValue(3, GetInstanceId()); DB.Characters.ExecuteOrAppend(dbTrans, stmt); if (doRespawn) @@ -3097,7 +3086,8 @@ namespace Game.Maps public void SaveRespawnTimeDB(SpawnObjectType type, ulong spawnId, long respawnTime, SQLTransaction dbTrans = null) { // Just here for support of compatibility mode - PreparedStatement stmt = DB.Characters.GetPreparedStatement((type == SpawnObjectType.GameObject) ? CharStatements.REP_GO_RESPAWN : CharStatements.REP_CREATURE_RESPAWN); + PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.REP_RESPAWN); + stmt.AddValue(0, (ushort)type); stmt.AddValue(0, spawnId); stmt.AddValue(1, respawnTime); stmt.AddValue(2, GetId()); @@ -3107,7 +3097,7 @@ namespace Game.Maps public void LoadRespawnTimes() { - PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CREATURE_RESPAWNS); + PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_RESPAWNS); stmt.AddValue(0, GetId()); stmt.AddValue(1, GetInstanceId()); SQLResult result = DB.Characters.Query(stmt); @@ -3115,30 +3105,15 @@ namespace Game.Maps { do { - var loguid = result.Read(0); - var respawnTime = result.Read(1); + SpawnObjectType type = (SpawnObjectType)result.Read(0); + var spawnId = result.Read(1); + var respawnTime = result.Read(2); - CreatureData cdata = Global.ObjectMgr.GetCreatureData(loguid); - if (cdata != null) - SaveRespawnTime(SpawnObjectType.Creature, loguid, cdata.Id, respawnTime, GetZoneId(PhasingHandler.EmptyPhaseShift, cdata.spawnPoint), GridDefines.ComputeGridCoord(cdata.spawnPoint.GetPositionX(), cdata.spawnPoint.GetPositionY()).GetId(), false); - - } while (result.NextRow()); - } - - stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_GO_RESPAWNS); - stmt.AddValue(0, GetId()); - stmt.AddValue(1, GetInstanceId()); - result = DB.Characters.Query(stmt); - if (!result.IsEmpty()) - { - do - { - var loguid = result.Read(0); - var respawnTime = result.Read(1); - - GameObjectData godata = Global.ObjectMgr.GetGameObjectData(loguid); - if (godata != null) - SaveRespawnTime(SpawnObjectType.GameObject, loguid, godata.Id, respawnTime, GetZoneId(PhasingHandler.EmptyPhaseShift, godata.spawnPoint), GridDefines.ComputeGridCoord(godata.spawnPoint.GetPositionX(), godata.spawnPoint.GetPositionY()).GetId(), false); + SpawnData data = Global.ObjectMgr.GetSpawnData(type, spawnId); + if (data != null) + SaveRespawnTime(type, spawnId, data.Id, respawnTime, GetZoneId(PhasingHandler.EmptyPhaseShift, data.spawnPoint), GridDefines.ComputeGridCoord(data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY()).GetId(), false); + else + Log.outError(LogFilter.Maps, $"Loading saved respawn time of {respawnTime} for spawnid ({type},{spawnId}) - spawn does not exist, ignoring"); } while (result.NextRow()); } @@ -3154,12 +3129,7 @@ namespace Game.Maps public static void DeleteRespawnTimesInDB(uint mapId, uint instanceId) { - PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CREATURE_RESPAWN_BY_INSTANCE); - stmt.AddValue(0, mapId); - stmt.AddValue(1, instanceId); - DB.Characters.Execute(stmt); - - stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GO_RESPAWN_BY_INSTANCE); + PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ALL_RESPAWNS); stmt.AddValue(0, mapId); stmt.AddValue(1, instanceId); DB.Characters.Execute(stmt); diff --git a/Source/Game/Server/WorldManager.cs b/Source/Game/Server/WorldManager.cs index 77a5257a2..bb6faa5e1 100644 --- a/Source/Game/Server/WorldManager.cs +++ b/Source/Game/Server/WorldManager.cs @@ -486,7 +486,7 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loading Instance Template..."); Global.ObjectMgr.LoadInstanceTemplate(); - // Must be called before `creature_respawn`/`gameobject_respawn` tables + // Must be called before `respawn` data Log.outInfo(LogFilter.ServerLoading, "Loading instances..."); Global.InstanceSaveMgr.LoadInstances(); diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index ee52a3e88..651be3c5c 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1963,32 +1963,6 @@ LOCK TABLES `corpse_phases` WRITE; /*!40000 ALTER TABLE `corpse_phases` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `creature_respawn` --- - -DROP TABLE IF EXISTS `creature_respawn`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `creature_respawn` ( - `guid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier', - `respawnTime` bigint(20) NOT NULL DEFAULT '0', - `mapId` smallint(10) unsigned NOT NULL DEFAULT '0', - `instanceId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Instance Identifier', - PRIMARY KEY (`guid`,`instanceId`), - KEY `idx_instance` (`instanceId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Grid Loading System'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `creature_respawn` --- - -LOCK TABLES `creature_respawn` WRITE; -/*!40000 ALTER TABLE `creature_respawn` DISABLE KEYS */; -/*!40000 ALTER TABLE `creature_respawn` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `game_event_condition_save` -- @@ -2037,32 +2011,6 @@ LOCK TABLES `game_event_save` WRITE; /*!40000 ALTER TABLE `game_event_save` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `gameobject_respawn` --- - -DROP TABLE IF EXISTS `gameobject_respawn`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `gameobject_respawn` ( - `guid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier', - `respawnTime` bigint(20) NOT NULL DEFAULT '0', - `mapId` smallint(10) unsigned NOT NULL DEFAULT '0', - `instanceId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Instance Identifier', - PRIMARY KEY (`guid`,`instanceId`), - KEY `idx_instance` (`instanceId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Grid Loading System'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `gameobject_respawn` --- - -LOCK TABLES `gameobject_respawn` WRITE; -/*!40000 ALTER TABLE `gameobject_respawn` DISABLE KEYS */; -/*!40000 ALTER TABLE `gameobject_respawn` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `gm_bug` -- @@ -3529,6 +3477,33 @@ LOCK TABLES `reserved_name` WRITE; /*!40000 ALTER TABLE `reserved_name` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `respawn` +-- + +DROP TABLE IF EXISTS `respawn`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `respawn` ( + `type` smallint(10) unsigned NOT NULL, + `spawnId` bigint(20) unsigned NOT NULL, + `respawnTime` bigint(20) NOT NULL, + `mapId` smallint(10) unsigned NOT NULL, + `instanceId` int(10) unsigned NOT NULL, + PRIMARY KEY (`type`,`spawnId`,`instanceId`), + KEY `idx_instance` (`instanceId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Stored respawn times'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `respawn` +-- + +LOCK TABLES `respawn` WRITE; +/*!40000 ALTER TABLE `respawn` DISABLE KEYS */; +/*!40000 ALTER TABLE `respawn` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `updates` -- @@ -3674,7 +3649,8 @@ INSERT INTO `updates` VALUES ('2021_10_16_00_characters.sql','B5A31BB6FBC34512767475EDF13099DEC948EBB7','ARCHIVED','2021-10-16 01:12:20',0), ('2021_11_02_00_characters.sql','A3C0A6DA70CC70803C80685E4E2ED6255156520A','ARCHIVED','2021-11-02 18:11:13',0), ('2021_11_04_00_characters.sql','ED533235ADAD174F91A6B8E51D1046243B78B46D','ARCHIVED','2021-11-04 21:53:04',0), -('2021_11_17_00_characters.sql','03A0AB8ECD8BE5D818D41A8A610097C94A9C7DB9','ARCHIVED','2021-11-17 13:23:17',0); +('2021_11_17_00_characters.sql','03A0AB8ECD8BE5D818D41A8A610097C94A9C7DB9','ARCHIVED','2021-11-17 13:23:17',0), +('2021_12_16_00_characters_2019_07_14_00_characters.sql','DC1A3D3311FCF9106B4D91F8D2C5B893AD66C093','RELEASED','2021-12-16 01:06:53',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/characters/master/2021_12_16_00_characters_2019_07_14_00_characters.sql b/sql/updates/characters/master/2021_12_16_00_characters_2019_07_14_00_characters.sql new file mode 100644 index 000000000..ca35b4b69 --- /dev/null +++ b/sql/updates/characters/master/2021_12_16_00_characters_2019_07_14_00_characters.sql @@ -0,0 +1,20 @@ +-- +DROP TABLE IF EXISTS `respawn`; +CREATE TABLE `respawn` ( + `type` smallint(10) unsigned NOT NULL, + `spawnId` bigint(20) unsigned NOT NULL, + `respawnTime` bigint(20) NOT NULL, + `mapId` smallint(10) unsigned NOT NULL, + `instanceId` int(10) unsigned NOT NULL, + PRIMARY KEY (`type`,`spawnId`,`instanceId`), + KEY `idx_instance` (`instanceId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Stored respawn times'; + +INSERT INTO `respawn` (`type`,`spawnId`,`respawnTime`,`mapId`,`instanceId`) +SELECT 0 as `type`,`guid`,`respawnTime`,`mapId`,`instanceId` FROM `creature_respawn`; + +INSERT INTO `respawn` (`type`,`spawnId`,`respawnTime`,`mapId`,`instanceId`) +SELECT 1 as `type`,`guid`,`respawnTime`,`mapId`,`instanceId` FROM `gameobject_respawn`; + +DROP TABLE `creature_respawn`; +DROP TABLE `gameobject_respawn`;