소스 검색

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 달 전
부모
커밋
ed0530c640
4개의 변경된 파일54개의 추가작업 그리고 57개의 파일을 삭제
  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;
 	}