Browse Source

Fixed cooldown saving (#8890)

Fixed primary key definition for skill cooldowns
Added missing deletion for mercenary skill cooldowns
Fixed order of deletion of homunculus data
Clear the data for skills and skill cooldowns before saving and not after loading

Thanks to @mrfiziot for reporting and thanks to @Daegaladh for his help with testing.

Co-authored-by: vstumpf <vincents.995@gmail.com>
Lemongrass3110 4 months ago
parent
commit
ed0530c640
4 changed files with 54 additions and 57 deletions
  1. 2 2
      sql-files/main.sql
  2. 9 0
      sql-files/upgrades/upgrade_20250201.sql
  3. 39 46
      src/char/int_homun.cpp
  4. 4 9
      src/char/int_mercenary.cpp

+ 2 - 2
sql-files/main.sql

@@ -1064,7 +1064,7 @@ CREATE TABLE IF NOT EXISTS `skillcooldown_homunculus` (
   `homun_id` int(11) NOT NULL,
   `skill` smallint(11) unsigned NOT NULL DEFAULT '0',
   `tick` bigint(20) NOT NULL,
-  PRIMARY KEY (`homun_id`)
+  PRIMARY KEY (`homun_id`,`skill`)
 ) ENGINE=MyISAM;
 
 --
@@ -1075,7 +1075,7 @@ CREATE TABLE IF NOT EXISTS `skillcooldown_mercenary` (
   `mer_id` int(11) NOT NULL,
   `skill` smallint(11) unsigned NOT NULL DEFAULT '0',
   `tick` bigint(20) NOT NULL,
-  PRIMARY KEY (`mer_id`)
+  PRIMARY KEY (`mer_id`,`skill`)
 ) ENGINE=MyISAM;
 
 --

+ 9 - 0
sql-files/upgrades/upgrade_20250201.sql

@@ -0,0 +1,9 @@
+ALTER TABLE `skillcooldown_homunculus`
+	DROP PRIMARY KEY,
+	ADD PRIMARY KEY(`homun_id`, `skill`)
+;
+
+ALTER TABLE `skillcooldown_mercenary`
+	DROP PRIMARY KEY,
+	ADD PRIMARY KEY(`mer_id`, `skill`)
+;

+ 39 - 46
src/char/int_homun.cpp

@@ -114,49 +114,49 @@ bool mapif_homunculus_save(struct s_homunculus* hd)
 			Sql_ShowDebug(sql_handle);
 			return false;
 		}
-		else
-		{
-			SqlStmt stmt{ *sql_handle };
+	}
 
-			// Save skills
-			if (SQL_ERROR == stmt.Prepare("REPLACE INTO `%s` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", schema_config.skill_homunculus_db, hd->hom_id)) {
-				SqlStmt_ShowDebug(stmt);
-				return false;
-			}
+	SqlStmt stmt{ *sql_handle };
 
-			for (uint16 i = 0; i < MAX_HOMUNSKILL; ++i) {
-				if (hd->hskill[i].id > 0 && hd->hskill[i].lv != 0) {
-					if (SQL_ERROR == stmt.BindParam(0, SQLDT_UINT16, &hd->hskill[i].id, 0)
-						|| SQL_ERROR == stmt.BindParam(1, SQLDT_UINT16, &hd->hskill[i].lv, 0)
-						|| SQL_ERROR == stmt.Execute()) {
-						SqlStmt_ShowDebug(stmt);
-						return false;
-					}
-				}
-			}
+	// Save skills
+	if( SQL_ERROR == Sql_Query( sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%d'", schema_config.skill_homunculus_db, hd->hom_id )
+	 || SQL_ERROR == stmt.Prepare( "INSERT INTO `%s` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", schema_config.skill_homunculus_db, hd->hom_id ) ){
+		SqlStmt_ShowDebug(stmt);
+		return false;
+	}
 
-			// Save skill cooldowns
-			if (SQL_ERROR == stmt.Prepare("INSERT INTO `%s` (`homun_id`, `skill`, `tick`) VALUES (%d, ?, ?)", schema_config.skillcooldown_homunculus_db, hd->hom_id)) {
+	for (uint16 i = 0; i < MAX_HOMUNSKILL; ++i) {
+		if (hd->hskill[i].id > 0 && hd->hskill[i].lv != 0) {
+			if (SQL_ERROR == stmt.BindParam(0, SQLDT_UINT16, &hd->hskill[i].id, 0)
+				|| SQL_ERROR == stmt.BindParam(1, SQLDT_UINT16, &hd->hskill[i].lv, 0)
+				|| SQL_ERROR == stmt.Execute()) {
 				SqlStmt_ShowDebug(stmt);
 				return false;
 			}
+		}
+	}
 
-			for (uint16 i = 0; i < MAX_SKILLCOOLDOWN; ++i) {
-				if (hd->scd[i].skill_id == 0) {
-					continue;
-				}
-
-				if (hd->scd[i].tick == 0) {
-					continue;
-				}
-
-				if (SQL_ERROR == stmt.BindParam(0, SQLDT_UINT16, &hd->scd[i].skill_id, 0)
-					|| SQL_ERROR == stmt.BindParam(1, SQLDT_LONGLONG, &hd->scd[i].tick, 0)
-					|| SQL_ERROR == stmt.Execute()) {
-					SqlStmt_ShowDebug(stmt);
-					return false;
-				}
-			}
+	// Save skill cooldowns
+	if( SQL_ERROR == Sql_Query( sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%d'", schema_config.skillcooldown_homunculus_db, hd->hom_id )
+	 || SQL_ERROR == stmt.Prepare( "INSERT INTO `%s` (`homun_id`, `skill`, `tick`) VALUES (%d, ?, ?)", schema_config.skillcooldown_homunculus_db, hd->hom_id ) ){
+		SqlStmt_ShowDebug(stmt);
+		return false;
+	}
+
+	for (uint16 i = 0; i < MAX_SKILLCOOLDOWN; ++i) {
+		if (hd->scd[i].skill_id == 0) {
+			continue;
+		}
+
+		if (hd->scd[i].tick == 0) {
+			continue;
+		}
+
+		if (SQL_ERROR == stmt.BindParam(0, SQLDT_UINT16, &hd->scd[i].skill_id, 0)
+			|| SQL_ERROR == stmt.BindParam(1, SQLDT_LONGLONG, &hd->scd[i].tick, 0)
+			|| SQL_ERROR == stmt.Execute()) {
+			SqlStmt_ShowDebug(stmt);
+			return false;
 		}
 	}
 
@@ -273,12 +273,6 @@ bool mapif_homunculus_load(int32 homun_id, struct s_homunculus* hd)
 	}
 	Sql_FreeResult(sql_handle);
 
-	// Clear the data once loaded.
-	if (count > 0) {
-		if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id`='%d'", schema_config.skillcooldown_homunculus_db, homun_id))
-			Sql_ShowDebug(sql_handle);
-	}
-
 	if( charserv_config.save_log )
 		ShowInfo("Homunculus loaded (ID: %d - %s / Class: %d / CID: %d).\n", hd->hom_id, hd->name, hd->class_, hd->char_id);
 
@@ -287,10 +281,9 @@ bool mapif_homunculus_load(int32 homun_id, struct s_homunculus* hd)
 
 bool mapif_homunculus_delete(int32 homun_id)
 {
-	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", schema_config.homunculus_db, homun_id)
-	||	SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", schema_config.skill_homunculus_db, homun_id)
-	||	SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", schema_config.skillcooldown_homunculus_db, homun_id)
-	) {
+	if( SQL_ERROR == Sql_Query( sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", schema_config.skillcooldown_homunculus_db, homun_id )
+	 || SQL_ERROR == Sql_Query( sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", schema_config.skill_homunculus_db, homun_id )
+	 || SQL_ERROR == Sql_Query( sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", schema_config.homunculus_db, homun_id ) ){
 		Sql_ShowDebug(sql_handle);
 		return false;
 	}

+ 4 - 9
src/char/int_mercenary.cpp

@@ -94,7 +94,8 @@ bool mapif_mercenary_save(struct s_mercenary* merc)
 	// Save skill cooldowns
 	SqlStmt stmt{ *sql_handle };
 
-	if (SQL_ERROR == stmt.Prepare("INSERT INTO `%s` (`mer_id`, `skill`, `tick`) VALUES (%d, ?, ?)", schema_config.skillcooldown_mercenary_db, merc->mercenary_id)) {
+	if( SQL_ERROR == Sql_Query( sql_handle, "DELETE FROM `%s` WHERE `mer_id` = '%d'", schema_config.skillcooldown_mercenary_db, merc->mercenary_id )
+	 || SQL_ERROR == stmt.Prepare( "INSERT INTO `%s` (`mer_id`, `skill`, `tick`) VALUES (%d, ?, ?)", schema_config.skillcooldown_mercenary_db, merc->mercenary_id ) ){
 		SqlStmt_ShowDebug(stmt);
 		return false;
 	}
@@ -178,19 +179,13 @@ bool mapif_mercenary_load(int32 merc_id, uint32 char_id, struct s_mercenary *mer
 	}
 	Sql_FreeResult(sql_handle);
 
-	// Clear the data once loaded.
-	if (count > 0) {
-		if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `mer_id`='%d'", schema_config.skillcooldown_mercenary_db, merc_id))
-			Sql_ShowDebug(sql_handle);
-	}
-
 	return true;
 }
 
 bool mapif_mercenary_delete(int32 merc_id)
 {
-	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `mer_id` = '%d'", schema_config.mercenary_db, merc_id) )
-	{
+	if( SQL_ERROR == Sql_Query( sql_handle, "DELETE FROM `%s` WHERE `mer_id` = '%d'", schema_config.skillcooldown_mercenary_db, merc_id )
+	 || SQL_ERROR == Sql_Query( sql_handle, "DELETE FROM `%s` WHERE `mer_id` = '%d'", schema_config.mercenary_db, merc_id ) ){
 		Sql_ShowDebug(sql_handle);
 		return false;
 	}