L2JMobius

Public Development => Shares/Contributions => Archived User Contributions => Topic started by: shifu on February 05, 2025, 10:21:13 AM

Title: Relic System
Post by: shifu on February 05, 2025, 10:21:13 AM
Hello everyone! I am posting a patch fixing bugs in the Relic System. You can read more in the forum thread (https://l2jmobius.org/forum/index.php?topic=13407.0). It also fixes a bug where an activated relic was applied to all characters in the account. Apply the patch to the version from the repository.

#FIX version 1 (not relevant)
1. Create SQL file and execute in your DB :
Code: [Select]
SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `active_relic`
-- ----------------------------
DROP TABLE IF EXISTS `active_relic`;
CREATE TABLE `active_relic` (
  `charId` int(10) NOT NULL DEFAULT '0',
  `value` int(10) DEFAULT NULL,
  PRIMARY KEY (`charId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2. Create and apply this DIFF path:
Code: (diff) [Select]
### Eclipse Workspace Patch 1.0
#P L2J_Mobius_12.1_PathOfRogue
diff --git java/org/l2jmobius/gameserver/model/actor/Player.java java/org/l2jmobius/gameserver/model/actor/Player.java
index b3a5b07..6a8061d 100644
--- java/org/l2jmobius/gameserver/model/actor/Player.java
+++ java/org/l2jmobius/gameserver/model/actor/Player.java
@@ -14397,7 +14397,7 @@
  public AccountVariables getAccountVariables()
  {
  final AccountVariables vars = getScript(AccountVariables.class);
- return vars != null ? vars : addScript(new AccountVariables(getAccountName()));
+ return vars != null ? vars : addScript(new AccountVariables(getAccountName(), getObjectId()));
  }
 
  [member=79]override[/member]
@@ -16123,7 +16123,7 @@
  if (holder != null)
  {
  _relics.add(new PlayerRelicData(relicId, relicLevel, relicCount, relicIndex, relicSummonTime));
- giveRelicSkill(holder);
  }
  }
  }
diff --git java/org/l2jmobius/gameserver/model/variables/AccountVariables.java java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
index 7d12f82..cf32bba 100644
--- java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
+++ java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
@@ -20,6 +20,7 @@
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.SQLIntegrityConstraintViolationException;
 import java.util.Map.Entry;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -38,6 +39,10 @@
  private static final String DELETE_QUERY = "DELETE FROM account_gsdata WHERE account_name = ?";
  private static final String INSERT_QUERY = "REPLACE INTO account_gsdata (account_name, var, value) VALUES (?, ?, ?)";
 
+ private static final String SELECT_ACTIVE_RELIC = "SELECT `value` FROM `active_relic` WHERE charId = ?";
+ private static final String INSERT_ACTIVE_RELIC = "INSERT INTO `active_relic` (`charId`, `value`) VALUES (?, ?)";
+ private static final String UPDATE_ACTIVE_RELIC = "UPDATE `active_relic` SET `value`= ? WHERE (`charId`= ?)";
+
  // Public variable names
  public static final String HWID = "HWID";
  public static final String HWIDSLIT_VAR = " ";
@@ -53,10 +58,12 @@
  public static final String UNCONFIRMED_RELICS_COUNT = "UNCONFIRMED_RELICS_COUNT";
 
  private final String _accountName;
+ private final int _charId;
 
- public AccountVariables(String accountName)
+ public AccountVariables(String accountName, int charId)
  {
  _accountName = accountName;
+ _charId = charId;
  restoreMe();
  }
 
@@ -153,4 +160,52 @@
  }
  return true;
  }
+
+ public void setActiveRelic(int relicId)
+ {
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(INSERT_ACTIVE_RELIC))
+ {
+ st.setInt(1, _charId);
+ st.setInt(2, relicId);
+ st.execute();
+ }
+ catch (SQLIntegrityConstraintViolationException e)
+ {
+ PreparedStatement st = con.prepareStatement(UPDATE_ACTIVE_RELIC);
+ st.setInt(1, relicId);
+ st.setInt(2, _charId);
+ st.execute();
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't insert active relic for char ID : " + _charId, e);
+ }
+ }
+
+ public int getActiveRelic()
+ {
+ int relic = 0;
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(SELECT_ACTIVE_RELIC))
+ {
+ st.setInt(1, _charId);
+ try (ResultSet rset = st.executeQuery())
+ {
+ if (rset.next())
+ {
+ relic = rset.getInt(1);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't get active relic for char ID : " + _charId, e);
+ }
+ return relic;
+ }
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index 6b6bd1b..eb9724d 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -65,6 +65,7 @@
 import org.l2jmobius.gameserver.model.clan.Clan;
 import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
 import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
+import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.instancezone.Instance;
 import org.l2jmobius.gameserver.model.item.ItemTemplate;
 import org.l2jmobius.gameserver.model.item.instance.Item;
@@ -148,6 +149,7 @@
 import org.l2jmobius.gameserver.network.serverpackets.olympiad.ExOlympiadInfo;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestDialog;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestNotificationAll;
+import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsCollectionInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
@@ -807,14 +809,6 @@
  }
  player.sendPacket(new ExCollectionActiveEvent());
 
- // Relic Collections.
- if (Config.RELIC_SYSTEM_ENABLED)
- {
- player.sendPacket(new ExRelicsList(player));
- player.sendPacket(new ExRelicsCollectionInfo(player));
- player.sendPacket(new ExRelicsExchangeList(player));
- }
-
  // Virtual Items
  // TODO: Add a config for this.
  // player.sendPacket(new ExVirtualItemSystemBaseInfo(player));
@@ -979,6 +973,9 @@
 
  // Remove variable used by hunting zone system.
  player.getVariables().remove(PlayerVariables.LAST_HUNTING_ZONE_ID);
+
+ // Relic
+ relicSystem(getPlayer());
  }
 
  /**
@@ -1024,4 +1021,27 @@
  }
  }
  }
+
+ private void relicSystem(Player player)
+ {
+ if (Config.RELIC_SYSTEM_ENABLED)
+ {
+ int activeRelicId = player.getAccountVariables().getActiveRelic();
+ int activeRelicLevel = 0;
+ for (PlayerRelicData relic : player.getRelics())
+ {
+ if (relic.getRelicId() == activeRelicId)
+ {
+ activeRelicId = relic.getRelicId();
+ activeRelicLevel = relic.getRelicLevel();
+ break;
+ }
+ }
+ player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Stored active relic from acc var.
+ player.sendPacket(new ExRelicsCollectionInfo(player));
+ player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
+ player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
+ }
+ }
+
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
index 2bd917a..6f7e566 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
@@ -27,7 +27,6 @@
 import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.holders.RelicDataHolder;
 import org.l2jmobius.gameserver.model.skill.Skill;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 
@@ -65,8 +64,9 @@
  final int skillId = RelicData.getInstance().getRelicSkillId(_relicId);
  final int skillLevel = relicLevel + 1;
  player.sendPacket(new ExRelicsActiveInfo(_relicId, relicLevel));
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, _relicId);
- player.getAccountVariables().storeMe();
+ player.getAccountVariables().setActiveRelic(_relicId);
 
  final Skill relicSkill = SkillData.getInstance().getSkill(skillId, skillLevel);
  if (relicSkill != null)
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
index 0f4d0f5..715b525 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
@@ -21,10 +21,7 @@
 package org.l2jmobius.gameserver.network.clientpackets.relics;
 
 import org.l2jmobius.gameserver.model.actor.Player;
-import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
-import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
 
@@ -47,21 +44,6 @@
  return;
  }
 
- int activeRelicId = 0;
- int activeRelicLevel = 0;
- for (PlayerRelicData relic : player.getRelics())
- {
- if (relic.getRelicId() == player.getAccountVariables().getInt(AccountVariables.ACTIVE_RELIC, 0))
- {
- activeRelicId = relic.getRelicId();
- activeRelicLevel = relic.getRelicLevel();
- break;
- }
- }
- player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Show stored active relic from acc var.
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, activeRelicId);
- player.getAccountVariables().storeMe();
-
  player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
  player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
  }

#FIX Version 2 (https://l2jmobius.org/forum/index.php?topic=13610.msg57536#msg57536)
#FIX version 3 (https://l2jmobius.org/forum/index.php?topic=13610.msg57597#msg57597) (with character variables)
Title: Re: Relic System
Post by: GuruGel on February 05, 2025, 12:44:20 PM
Hello everyone! I am posting a patch fixing bugs in the Relic System. You can read more in the forum thread (https://l2jmobius.org/forum/index.php?topic=13407.0). It also fixes a bug where an activated relic was applied to all characters in the account. Apply the patch to the version from the repository.

1. Create SQL file and execute in your DB :
Code: [Select]
SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `active_relic`
-- ----------------------------
DROP TABLE IF EXISTS `active_relic`;
CREATE TABLE `active_relic` (
  `charId` int(10) NOT NULL DEFAULT '0',
  `value` int(10) DEFAULT NULL,
  PRIMARY KEY (`charId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2. Create and apply this DIFF path:
Code: (diff) [Select]
### Eclipse Workspace Patch 1.0
#P L2J_Mobius_12.1_PathOfRogue
diff --git java/org/l2jmobius/gameserver/model/actor/Player.java java/org/l2jmobius/gameserver/model/actor/Player.java
index b3a5b07..6a8061d 100644
--- java/org/l2jmobius/gameserver/model/actor/Player.java
+++ java/org/l2jmobius/gameserver/model/actor/Player.java
@@ -14397,7 +14397,7 @@
  public AccountVariables getAccountVariables()
  {
  final AccountVariables vars = getScript(AccountVariables.class);
- return vars != null ? vars : addScript(new AccountVariables(getAccountName()));
+ return vars != null ? vars : addScript(new AccountVariables(getAccountName(), getObjectId()));
  }
 
  [member=79]override[/member]
@@ -16123,7 +16123,7 @@
  if (holder != null)
  {
  _relics.add(new PlayerRelicData(relicId, relicLevel, relicCount, relicIndex, relicSummonTime));
- giveRelicSkill(holder);
  }
  }
  }
diff --git java/org/l2jmobius/gameserver/model/variables/AccountVariables.java java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
index 7d12f82..cf32bba 100644
--- java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
+++ java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
@@ -20,6 +20,7 @@
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.SQLIntegrityConstraintViolationException;
 import java.util.Map.Entry;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -38,6 +39,10 @@
  private static final String DELETE_QUERY = "DELETE FROM account_gsdata WHERE account_name = ?";
  private static final String INSERT_QUERY = "REPLACE INTO account_gsdata (account_name, var, value) VALUES (?, ?, ?)";
 
+ private static final String SELECT_ACTIVE_RELIC = "SELECT `value` FROM `active_relic` WHERE charId = ?";
+ private static final String INSERT_ACTIVE_RELIC = "INSERT INTO `active_relic` (`charId`, `value`) VALUES (?, ?)";
+ private static final String UPDATE_ACTIVE_RELIC = "UPDATE `active_relic` SET `value`= ? WHERE (`charId`= ?)";
+
  // Public variable names
  public static final String HWID = "HWID";
  public static final String HWIDSLIT_VAR = " ";
@@ -53,10 +58,12 @@
  public static final String UNCONFIRMED_RELICS_COUNT = "UNCONFIRMED_RELICS_COUNT";
 
  private final String _accountName;
+ private final int _charId;
 
- public AccountVariables(String accountName)
+ public AccountVariables(String accountName, int charId)
  {
  _accountName = accountName;
+ _charId = charId;
  restoreMe();
  }
 
@@ -153,4 +160,52 @@
  }
  return true;
  }
+
+ public void setActiveRelic(int relicId)
+ {
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(INSERT_ACTIVE_RELIC))
+ {
+ st.setInt(1, _charId);
+ st.setInt(2, relicId);
+ st.execute();
+ }
+ catch (SQLIntegrityConstraintViolationException e)
+ {
+ PreparedStatement st = con.prepareStatement(UPDATE_ACTIVE_RELIC);
+ st.setInt(1, relicId);
+ st.setInt(2, _charId);
+ st.execute();
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't insert active relic for char ID : " + _charId, e);
+ }
+ }
+
+ public int getActiveRelic()
+ {
+ int relic = 0;
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(SELECT_ACTIVE_RELIC))
+ {
+ st.setInt(1, _charId);
+ try (ResultSet rset = st.executeQuery())
+ {
+ if (rset.next())
+ {
+ relic = rset.getInt(1);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't get active relic for char ID : " + _charId, e);
+ }
+ return relic;
+ }
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index 6b6bd1b..eb9724d 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -65,6 +65,7 @@
 import org.l2jmobius.gameserver.model.clan.Clan;
 import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
 import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
+import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.instancezone.Instance;
 import org.l2jmobius.gameserver.model.item.ItemTemplate;
 import org.l2jmobius.gameserver.model.item.instance.Item;
@@ -148,6 +149,7 @@
 import org.l2jmobius.gameserver.network.serverpackets.olympiad.ExOlympiadInfo;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestDialog;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestNotificationAll;
+import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsCollectionInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
@@ -807,14 +809,6 @@
  }
  player.sendPacket(new ExCollectionActiveEvent());
 
- // Relic Collections.
- if (Config.RELIC_SYSTEM_ENABLED)
- {
- player.sendPacket(new ExRelicsList(player));
- player.sendPacket(new ExRelicsCollectionInfo(player));
- player.sendPacket(new ExRelicsExchangeList(player));
- }
-
  // Virtual Items
  // TODO: Add a config for this.
  // player.sendPacket(new ExVirtualItemSystemBaseInfo(player));
@@ -979,6 +973,9 @@
 
  // Remove variable used by hunting zone system.
  player.getVariables().remove(PlayerVariables.LAST_HUNTING_ZONE_ID);
+
+ // Relic
+ relicSystem(getPlayer());
  }
 
  /**
@@ -1024,4 +1021,27 @@
  }
  }
  }
+
+ private void relicSystem(Player player)
+ {
+ if (Config.RELIC_SYSTEM_ENABLED)
+ {
+ int activeRelicId = player.getAccountVariables().getActiveRelic();
+ int activeRelicLevel = 0;
+ for (PlayerRelicData relic : player.getRelics())
+ {
+ if (relic.getRelicId() == activeRelicId)
+ {
+ activeRelicId = relic.getRelicId();
+ activeRelicLevel = relic.getRelicLevel();
+ break;
+ }
+ }
+ player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Stored active relic from acc var.
+ player.sendPacket(new ExRelicsCollectionInfo(player));
+ player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
+ player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
+ }
+ }
+
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
index 2bd917a..6f7e566 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
@@ -27,7 +27,6 @@
 import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.holders.RelicDataHolder;
 import org.l2jmobius.gameserver.model.skill.Skill;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 
@@ -65,8 +64,9 @@
  final int skillId = RelicData.getInstance().getRelicSkillId(_relicId);
  final int skillLevel = relicLevel + 1;
  player.sendPacket(new ExRelicsActiveInfo(_relicId, relicLevel));
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, _relicId);
- player.getAccountVariables().storeMe();
+ player.getAccountVariables().setActiveRelic(_relicId);
 
  final Skill relicSkill = SkillData.getInstance().getSkill(skillId, skillLevel);
  if (relicSkill != null)
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
index 0f4d0f5..715b525 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
@@ -21,10 +21,7 @@
 package org.l2jmobius.gameserver.network.clientpackets.relics;
 
 import org.l2jmobius.gameserver.model.actor.Player;
-import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
-import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
 
@@ -47,21 +44,6 @@
  return;
  }
 
- int activeRelicId = 0;
- int activeRelicLevel = 0;
- for (PlayerRelicData relic : player.getRelics())
- {
- if (relic.getRelicId() == player.getAccountVariables().getInt(AccountVariables.ACTIVE_RELIC, 0))
- {
- activeRelicId = relic.getRelicId();
- activeRelicLevel = relic.getRelicLevel();
- break;
- }
- }
- player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Show stored active relic from acc var.
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, activeRelicId);
- player.getAccountVariables().storeMe();
-
  player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
  player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
  }

Everything works, thanks for your work.
Title: Re: Relic System
Post by: CostyKiller on February 05, 2025, 11:27:07 PM
You fixed something that you think is bugged but is not, we try to follow retail as much as possible.

Check this: https://l2wiki.com/main/articles/1002.html

Quote
The activated relic effect is shared among characters on the account.
Title: Re: Relic System
Post by: shifu on February 06, 2025, 03:10:24 AM
You fixed something that you think is bugged but is not, we try to follow retail as much as possible.

Check this: https://l2wiki.com/main/articles/1002.html

Firstly, it is at least stupid. Since the characters on the account are equipped with different weapons. Secondly, the topic was not created in the bugs section (but they clearly exist) ;)
Thirdly, on the official Russian server (https://l2central.info/main/articles/1002.html) "Эффект активированной реликвии сохраняется для каждого персонажа на аккаунте." (there may be inaccuracies in the description) - what does personal active effect mean in particular, exactly the same mechanics of the effect are implemented as in the patch.

P.S. I have personally tested it on a live official server. Check this video (https://drive.google.com/file/d/10YVRIL27HG1iF7sQPtujMJYC_gAH_AVa/view?usp=sharing)
Title: Re: Relic System
Post by: gigilo1968 on February 06, 2025, 11:16:00 AM
I play in core-71 official EU server and each character can choose personal relic
Title: Re: Relic System
Post by: CostyKiller on February 06, 2025, 01:32:28 PM
Ok, then it seems they translated it wrong, but I think you can store the active relic in player variables instead of creating another table just for that.
Title: Re: Relic System
Post by: shifu on February 06, 2025, 01:40:01 PM
Ok, then it seems they translated it wrong, but I think you can store the active relic in player variables instead of creating another table just for that.
You're right, I'll think about how to do it.
Title: Re: Relic System
Post by: shifu on February 07, 2025, 03:29:30 AM
#FIX version 2
1. Execute sql query:
Code: [Select]
ALTER TABLE `characters` ADD `active_relic` int DEFAULT NULL;Check that column "active_relic" was created in the table.

2. Create and apply this DIFF path:
Code: (diff) [Select]
### Eclipse Workspace Patch 1.0
#P L2J_Mobius_12.1_PathOfRogue
diff --git java/org/l2jmobius/gameserver/model/actor/Player.java java/org/l2jmobius/gameserver/model/actor/Player.java
index b3a5b07..2b8bff3 100644
--- java/org/l2jmobius/gameserver/model/actor/Player.java
+++ java/org/l2jmobius/gameserver/model/actor/Player.java
@@ -14397,7 +14397,7 @@
  public AccountVariables getAccountVariables()
  {
  final AccountVariables vars = getScript(AccountVariables.class);
- return vars != null ? vars : addScript(new AccountVariables(getAccountName()));
+ return vars != null ? vars : addScript(new AccountVariables(getAccountName(), getObjectId()));
  }
 
  [member=79]override[/member]
@@ -16123,7 +16123,6 @@
  if (holder != null)
  {
  _relics.add(new PlayerRelicData(relicId, relicLevel, relicCount, relicIndex, relicSummonTime));
- giveRelicSkill(holder);
  }
  }
  }
diff --git java/org/l2jmobius/gameserver/model/variables/AccountVariables.java java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
index 7d12f82..1b8040b 100644
--- java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
+++ java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
@@ -38,6 +38,9 @@
  private static final String DELETE_QUERY = "DELETE FROM account_gsdata WHERE account_name = ?";
  private static final String INSERT_QUERY = "REPLACE INTO account_gsdata (account_name, var, value) VALUES (?, ?, ?)";
 
+ private static final String SELECT_ACTIVE_RELIC = "SELECT `active_relic` FROM `characters` WHERE charId = ?";
+ private static final String UPDATE_ACTIVE_RELIC = "UPDATE `characters` SET `active_relic`= ? WHERE (`charId`= ?)";
+
  // Public variable names
  public static final String HWID = "HWID";
  public static final String HWIDSLIT_VAR = " ";
@@ -47,16 +50,18 @@
  public static final String LCOIN_SHOP_PRODUCT_DAILY_COUNT = "LCSDailyCount";
  public static final String LCOIN_SHOP_PRODUCT_WEEKLY_COUNT = "LCSWeeklyCount";
  public static final String LCOIN_SHOP_PRODUCT_MONTHLY_COUNT = "LCSMonthlyCount";
- public static final String ACTIVE_RELIC = "ACTIVE_RELIC";
  public static final String A_GRADE_RELIC_ATEMPTS = "A_GRADE_RELIC_ATEMPTS";
  public static final String B_GRADE_RELIC_ATEMPTS = "B_GRADE_RELIC_ATEMPTS";
  public static final String UNCONFIRMED_RELICS_COUNT = "UNCONFIRMED_RELICS_COUNT";
 
  private final String _accountName;
+ private final int _charId;
 
- public AccountVariables(String accountName)
+ public AccountVariables(String accountName, int charId)
  {
  _accountName = accountName;
+ _charId = charId;
  restoreMe();
  }
 
@@ -153,4 +158,45 @@
  }
  return true;
  }
+
+ public void setActiveRelic(int relicId)
+ {
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(UPDATE_ACTIVE_RELIC))
+ {
+ st.setInt(1, relicId);
+ st.setInt(2, _charId);
+ st.execute();
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't set active relic for char ID : " + _charId, e);
+ }
+ }
+
+ public int getActiveRelic()
+ {
+ int relic = 0;
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(SELECT_ACTIVE_RELIC))
+ {
+ st.setInt(1, _charId);
+ try (ResultSet rset = st.executeQuery())
+ {
+ if (rset.next())
+ {
+ relic = rset.getInt(1);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't get active relic for char ID : " + _charId, e);
+ }
+ return relic;
+ }
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index 6b6bd1b..eb9724d 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -65,6 +65,7 @@
 import org.l2jmobius.gameserver.model.clan.Clan;
 import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
 import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
+import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.instancezone.Instance;
 import org.l2jmobius.gameserver.model.item.ItemTemplate;
 import org.l2jmobius.gameserver.model.item.instance.Item;
@@ -148,6 +149,7 @@
 import org.l2jmobius.gameserver.network.serverpackets.olympiad.ExOlympiadInfo;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestDialog;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestNotificationAll;
+import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsCollectionInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
@@ -807,14 +809,6 @@
  }
  player.sendPacket(new ExCollectionActiveEvent());
 
- // Relic Collections.
- if (Config.RELIC_SYSTEM_ENABLED)
- {
- player.sendPacket(new ExRelicsList(player));
- player.sendPacket(new ExRelicsCollectionInfo(player));
- player.sendPacket(new ExRelicsExchangeList(player));
- }
-
  // Virtual Items
  // TODO: Add a config for this.
  // player.sendPacket(new ExVirtualItemSystemBaseInfo(player));
@@ -979,6 +973,9 @@
 
  // Remove variable used by hunting zone system.
  player.getVariables().remove(PlayerVariables.LAST_HUNTING_ZONE_ID);
+
+ // Relic
+ relicSystem(getPlayer());
  }
 
  /**
@@ -1024,4 +1021,27 @@
  }
  }
  }
+
+ private void relicSystem(Player player)
+ {
+ if (Config.RELIC_SYSTEM_ENABLED)
+ {
+ int activeRelicId = player.getAccountVariables().getActiveRelic();
+ int activeRelicLevel = 0;
+ for (PlayerRelicData relic : player.getRelics())
+ {
+ if (relic.getRelicId() == activeRelicId)
+ {
+ activeRelicId = relic.getRelicId();
+ activeRelicLevel = relic.getRelicLevel();
+ break;
+ }
+ }
+ player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Stored active relic from acc var.
+ player.sendPacket(new ExRelicsCollectionInfo(player));
+ player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
+ player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
+ }
+ }
+
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
index 2bd917a..53f04a1 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
@@ -27,7 +27,6 @@
 import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.holders.RelicDataHolder;
 import org.l2jmobius.gameserver.model.skill.Skill;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 
@@ -65,8 +64,7 @@
  final int skillId = RelicData.getInstance().getRelicSkillId(_relicId);
  final int skillLevel = relicLevel + 1;
  player.sendPacket(new ExRelicsActiveInfo(_relicId, relicLevel));
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, _relicId);
- player.getAccountVariables().storeMe();
+ player.getAccountVariables().setActiveRelic(_relicId);
 
  final Skill relicSkill = SkillData.getInstance().getSkill(skillId, skillLevel);
  if (relicSkill != null)
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
index 0f4d0f5..715b525 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
@@ -21,10 +21,7 @@
 package org.l2jmobius.gameserver.network.clientpackets.relics;
 
 import org.l2jmobius.gameserver.model.actor.Player;
-import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
-import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
 
@@ -47,21 +44,6 @@
  return;
  }
 
- int activeRelicId = 0;
- int activeRelicLevel = 0;
- for (PlayerRelicData relic : player.getRelics())
- {
- if (relic.getRelicId() == player.getAccountVariables().getInt(AccountVariables.ACTIVE_RELIC, 0))
- {
- activeRelicId = relic.getRelicId();
- activeRelicLevel = relic.getRelicLevel();
- break;
- }
- }
- player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Show stored active relic from acc var.
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, activeRelicId);
- player.getAccountVariables().storeMe();
-
  player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
  player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
  }

Have Fun!  ;)
Title: Re: Relic System
Post by: gigilo1968 on February 07, 2025, 09:23:28 AM
Insert in character_variables table better method, than change characters table
Title: Re: Relic System
Post by: shifu on February 07, 2025, 09:36:09 AM
Insert in character_variables table better method, than change characters table
Edit queries SELECT_ACTIVE_RELIC  and UPDATE_ACTIVE_RELIC  in file "java/org/l2jmobius/gameserver/model/variables/AccountVariables.java" as you see fit.
Title: Re: Relic System
Post by: GuruGel on February 08, 2025, 10:10:03 AM
Insert in character_variables table better method, than change characters table

What is the best way to write to this character_variables table? It is already overloaded with information. In just a couple of months, this file becomes 700-800 MB in size, and it becomes impossible to play because of freezes... On the contrary, I removed the entries for Conquest from this file. And it became much more comfortable to play. So I think the best option is a separate table or entry with characters. This will reduce the load on the server.
Title: Re: Relic System
Post by: GuruGel on February 08, 2025, 10:13:29 AM
Sometimes an error appears in the console:
Code: [Select]
[05/02 20:06:35] Could not store relics for playerId 268550364:
java.util.ConcurrentModificationException
at java.base/java.util.ArrayList.forEach(ArrayList.java:1598)
at org.l2jmobius.gameserver.model.actor.Player.storeRelics(Player.java:16027)
at org.l2jmobius.gameserver.network.clientpackets.relics.RequestRelicsCombination.runImpl(RequestRelicsCombination.java:112)
at org.l2jmobius.gameserver.network.clientpackets.ClientPacket.run(ClientPacket.java:53)
at org.l2jmobius.commons.network.PacketExecutor$PacketRunnable.run(PacketExecutor.java:74)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Before the fixes, this did not happen.
How to fix this?
Title: Re: Relic System
Post by: gigilo1968 on February 08, 2025, 03:51:51 PM
Yes, storeRelics error appears on my server too
Title: Re: Relic System
Post by: notorionn on February 08, 2025, 09:17:36 PM
Sorry to change the direction of the topic. The mechanics of Conquest in the official version have changed. Teleports, privileges. And some information apparently gets reset during the week.

On a 'random' l2j server that I was present to check, after opening 'Conquest' with hundreds of players, there were 'lags' and the game crashed.

Remembering that the 'Conquest' area apparently can have better performance if transferred to the 'Dimensional' server.

Regarding Relics, I got a little lost in the translation. :-\

In Chronos, on a new main account when using the card, the new account uses the 'sword'. The other characters on the same account see the same weapons, but they are not equipped, whether they are of the same class or not.
Title: Re: Relic System
Post by: shifu on February 09, 2025, 07:16:32 AM
Sometimes an error appears in the console:
Code: [Select]
[05/02 20:06:35] Could not store relics for playerId 268550364:
java.util.ConcurrentModificationException
at java.base/java.util.ArrayList.forEach(ArrayList.java:1598)
at org.l2jmobius.gameserver.model.actor.Player.storeRelics(Player.java:16027)
at org.l2jmobius.gameserver.network.clientpackets.relics.RequestRelicsCombination.runImpl(RequestRelicsCombination.java:112)
at org.l2jmobius.gameserver.network.clientpackets.ClientPacket.run(ClientPacket.java:53)
at org.l2jmobius.commons.network.PacketExecutor$PacketRunnable.run(PacketExecutor.java:74)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Before the fixes, this did not happen.
How to fix this?
After which version of the patch does the error appear? Have you made sure that the "active_relic" column is created? Try applying the patch to a "clean version" of the server from the repository.
P.s. the patch should not affect your error. I think it has nothing to do with it. After what actions does the error appear?
Title: Re: Relic System
Post by: GuruGel on February 09, 2025, 10:29:46 AM
Hello everyone! I am posting a patch fixing bugs in the Relic System. You can read more in the forum thread (https://l2jmobius.org/forum/index.php?topic=13407.0). It also fixes a bug where an activated relic was applied to all characters in the account. Apply the patch to the version from the repository.

#FIX version 1 (not relevant)
1. Create SQL file and execute in your DB :
Code: [Select]
SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `active_relic`
-- ----------------------------
DROP TABLE IF EXISTS `active_relic`;
CREATE TABLE `active_relic` (
  `charId` int(10) NOT NULL DEFAULT '0',
  `value` int(10) DEFAULT NULL,
  PRIMARY KEY (`charId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2. Create and apply this DIFF path:
Code: (diff) [Select]
### Eclipse Workspace Patch 1.0
#P L2J_Mobius_12.1_PathOfRogue
diff --git java/org/l2jmobius/gameserver/model/actor/Player.java java/org/l2jmobius/gameserver/model/actor/Player.java
index b3a5b07..6a8061d 100644
--- java/org/l2jmobius/gameserver/model/actor/Player.java
+++ java/org/l2jmobius/gameserver/model/actor/Player.java
@@ -14397,7 +14397,7 @@
  public AccountVariables getAccountVariables()
  {
  final AccountVariables vars = getScript(AccountVariables.class);
- return vars != null ? vars : addScript(new AccountVariables(getAccountName()));
+ return vars != null ? vars : addScript(new AccountVariables(getAccountName(), getObjectId()));
  }
 
  [member=79]override[/member]
@@ -16123,7 +16123,7 @@
  if (holder != null)
  {
  _relics.add(new PlayerRelicData(relicId, relicLevel, relicCount, relicIndex, relicSummonTime));
- giveRelicSkill(holder);
  }
  }
  }
diff --git java/org/l2jmobius/gameserver/model/variables/AccountVariables.java java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
index 7d12f82..cf32bba 100644
--- java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
+++ java/org/l2jmobius/gameserver/model/variables/AccountVariables.java
@@ -20,6 +20,7 @@
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.SQLIntegrityConstraintViolationException;
 import java.util.Map.Entry;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -38,6 +39,10 @@
  private static final String DELETE_QUERY = "DELETE FROM account_gsdata WHERE account_name = ?";
  private static final String INSERT_QUERY = "REPLACE INTO account_gsdata (account_name, var, value) VALUES (?, ?, ?)";
 
+ private static final String SELECT_ACTIVE_RELIC = "SELECT `value` FROM `active_relic` WHERE charId = ?";
+ private static final String INSERT_ACTIVE_RELIC = "INSERT INTO `active_relic` (`charId`, `value`) VALUES (?, ?)";
+ private static final String UPDATE_ACTIVE_RELIC = "UPDATE `active_relic` SET `value`= ? WHERE (`charId`= ?)";
+
  // Public variable names
  public static final String HWID = "HWID";
  public static final String HWIDSLIT_VAR = " ";
@@ -53,10 +58,12 @@
  public static final String UNCONFIRMED_RELICS_COUNT = "UNCONFIRMED_RELICS_COUNT";
 
  private final String _accountName;
+ private final int _charId;
 
- public AccountVariables(String accountName)
+ public AccountVariables(String accountName, int charId)
  {
  _accountName = accountName;
+ _charId = charId;
  restoreMe();
  }
 
@@ -153,4 +160,52 @@
  }
  return true;
  }
+
+ public void setActiveRelic(int relicId)
+ {
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(INSERT_ACTIVE_RELIC))
+ {
+ st.setInt(1, _charId);
+ st.setInt(2, relicId);
+ st.execute();
+ }
+ catch (SQLIntegrityConstraintViolationException e)
+ {
+ PreparedStatement st = con.prepareStatement(UPDATE_ACTIVE_RELIC);
+ st.setInt(1, relicId);
+ st.setInt(2, _charId);
+ st.execute();
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't insert active relic for char ID : " + _charId, e);
+ }
+ }
+
+ public int getActiveRelic()
+ {
+ int relic = 0;
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(SELECT_ACTIVE_RELIC))
+ {
+ st.setInt(1, _charId);
+ try (ResultSet rset = st.executeQuery())
+ {
+ if (rset.next())
+ {
+ relic = rset.getInt(1);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't get active relic for char ID : " + _charId, e);
+ }
+ return relic;
+ }
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index 6b6bd1b..eb9724d 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -65,6 +65,7 @@
 import org.l2jmobius.gameserver.model.clan.Clan;
 import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
 import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
+import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.instancezone.Instance;
 import org.l2jmobius.gameserver.model.item.ItemTemplate;
 import org.l2jmobius.gameserver.model.item.instance.Item;
@@ -148,6 +149,7 @@
 import org.l2jmobius.gameserver.network.serverpackets.olympiad.ExOlympiadInfo;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestDialog;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestNotificationAll;
+import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsCollectionInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
@@ -807,14 +809,6 @@
  }
  player.sendPacket(new ExCollectionActiveEvent());
 
- // Relic Collections.
- if (Config.RELIC_SYSTEM_ENABLED)
- {
- player.sendPacket(new ExRelicsList(player));
- player.sendPacket(new ExRelicsCollectionInfo(player));
- player.sendPacket(new ExRelicsExchangeList(player));
- }
-
  // Virtual Items
  // TODO: Add a config for this.
  // player.sendPacket(new ExVirtualItemSystemBaseInfo(player));
@@ -979,6 +973,9 @@
 
  // Remove variable used by hunting zone system.
  player.getVariables().remove(PlayerVariables.LAST_HUNTING_ZONE_ID);
+
+ // Relic
+ relicSystem(getPlayer());
  }
 
  /**
@@ -1024,4 +1021,27 @@
  }
  }
  }
+
+ private void relicSystem(Player player)
+ {
+ if (Config.RELIC_SYSTEM_ENABLED)
+ {
+ int activeRelicId = player.getAccountVariables().getActiveRelic();
+ int activeRelicLevel = 0;
+ for (PlayerRelicData relic : player.getRelics())
+ {
+ if (relic.getRelicId() == activeRelicId)
+ {
+ activeRelicId = relic.getRelicId();
+ activeRelicLevel = relic.getRelicLevel();
+ break;
+ }
+ }
+ player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Stored active relic from acc var.
+ player.sendPacket(new ExRelicsCollectionInfo(player));
+ player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
+ player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
+ }
+ }
+
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
index 2bd917a..6f7e566 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
@@ -27,7 +27,6 @@
 import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.holders.RelicDataHolder;
 import org.l2jmobius.gameserver.model.skill.Skill;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 
@@ -65,8 +64,9 @@
  final int skillId = RelicData.getInstance().getRelicSkillId(_relicId);
  final int skillLevel = relicLevel + 1;
  player.sendPacket(new ExRelicsActiveInfo(_relicId, relicLevel));
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, _relicId);
- player.getAccountVariables().storeMe();
+ player.getAccountVariables().setActiveRelic(_relicId);
 
  final Skill relicSkill = SkillData.getInstance().getSkill(skillId, skillLevel);
  if (relicSkill != null)
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
index 0f4d0f5..715b525 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
@@ -21,10 +21,7 @@
 package org.l2jmobius.gameserver.network.clientpackets.relics;
 
 import org.l2jmobius.gameserver.model.actor.Player;
-import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
-import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
 
@@ -47,21 +44,6 @@
  return;
  }
 
- int activeRelicId = 0;
- int activeRelicLevel = 0;
- for (PlayerRelicData relic : player.getRelics())
- {
- if (relic.getRelicId() == player.getAccountVariables().getInt(AccountVariables.ACTIVE_RELIC, 0))
- {
- activeRelicId = relic.getRelicId();
- activeRelicLevel = relic.getRelicLevel();
- break;
- }
- }
- player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Show stored active relic from acc var.
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, activeRelicId);
- player.getAccountVariables().storeMe();
-
  player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
  player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
  }

after this update, but the error does not always appear.
Title: Re: Relic System
Post by: shifu on February 09, 2025, 02:37:38 PM
(https://i.ibb.co/WNmBXp4d/2025-02-09-19-25-55.png) (https://imgbb.com/)
Try to reverse the patch or use the compilation from the repository. The error may repeat without a patch. At the moment I have not found a dependency between the error and the patch.
P.S. Use patch version 3
Title: Re: Relic System
Post by: Mobius on February 11, 2025, 05:01:54 PM
This is wrong.
Account variables should not be linked with character object id.
Title: Re: Relic System
Post by: shifu on February 12, 2025, 03:48:16 AM
#FIX version 3 (with character variables)
- Create and apply this DIFF path:
Code: (diff) [Select]
diff --git java/org/l2jmobius/gameserver/model/actor/Player.java java/org/l2jmobius/gameserver/model/actor/Player.java
index b3a5b07..d2ad8c5 100644
--- java/org/l2jmobius/gameserver/model/actor/Player.java
+++ java/org/l2jmobius/gameserver/model/actor/Player.java
@@ -16123,7 +16123,6 @@
  if (holder != null)
  {
  _relics.add(new PlayerRelicData(relicId, relicLevel, relicCount, relicIndex, relicSummonTime));
- giveRelicSkill(holder);
  }
  }
  }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index 6b6bd1b..075b5ab 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -65,6 +65,7 @@
 import org.l2jmobius.gameserver.model.clan.Clan;
 import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
 import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
+import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.instancezone.Instance;
 import org.l2jmobius.gameserver.model.item.ItemTemplate;
 import org.l2jmobius.gameserver.model.item.instance.Item;
@@ -148,6 +149,7 @@
 import org.l2jmobius.gameserver.network.serverpackets.olympiad.ExOlympiadInfo;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestDialog;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestNotificationAll;
+import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsCollectionInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
@@ -807,14 +809,6 @@
  }
  player.sendPacket(new ExCollectionActiveEvent());
 
- // Relic Collections.
- if (Config.RELIC_SYSTEM_ENABLED)
- {
- player.sendPacket(new ExRelicsList(player));
- player.sendPacket(new ExRelicsCollectionInfo(player));
- player.sendPacket(new ExRelicsExchangeList(player));
- }
-
  // Virtual Items
  // TODO: Add a config for this.
  // player.sendPacket(new ExVirtualItemSystemBaseInfo(player));
@@ -979,6 +973,9 @@
 
  // Remove variable used by hunting zone system.
  player.getVariables().remove(PlayerVariables.LAST_HUNTING_ZONE_ID);
+
+ // Relic
+ relicSystem(getPlayer());
  }
 
  /**
@@ -1024,4 +1021,27 @@
  }
  }
  }
+
+ private void relicSystem(Player player)
+ {
+ if (Config.RELIC_SYSTEM_ENABLED)
+ {
+ int activeRelicId = player.getVariables().getInt(AccountVariables.ACTIVE_RELIC, 0);
+ int activeRelicLevel = 0;
+ for (PlayerRelicData relic : player.getRelics())
+ {
+ if (relic.getRelicId() == activeRelicId)
+ {
+ activeRelicId = relic.getRelicId();
+ activeRelicLevel = relic.getRelicLevel();
+ break;
+ }
+ }
+ player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Stored active relic from acc var.
+ player.sendPacket(new ExRelicsCollectionInfo(player));
+ player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
+ player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
+ }
+ }
+
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
index 2bd917a..0383eb3 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
@@ -65,8 +65,7 @@
  final int skillId = RelicData.getInstance().getRelicSkillId(_relicId);
  final int skillLevel = relicLevel + 1;
  player.sendPacket(new ExRelicsActiveInfo(_relicId, relicLevel));
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, _relicId);
- player.getAccountVariables().storeMe();
+ player.getVariables().set(AccountVariables.ACTIVE_RELIC, _relicId);
 
  final Skill relicSkill = SkillData.getInstance().getSkill(skillId, skillLevel);
  if (relicSkill != null)
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
index 0f4d0f5..715b525 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
@@ -21,10 +21,7 @@
 package org.l2jmobius.gameserver.network.clientpackets.relics;
 
 import org.l2jmobius.gameserver.model.actor.Player;
-import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
-import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
 
@@ -47,21 +44,6 @@
  return;
  }
 
- int activeRelicId = 0;
- int activeRelicLevel = 0;
- for (PlayerRelicData relic : player.getRelics())
- {
- if (relic.getRelicId() == player.getAccountVariables().getInt(AccountVariables.ACTIVE_RELIC, 0))
- {
- activeRelicId = relic.getRelicId();
- activeRelicLevel = relic.getRelicLevel();
- break;
- }
- }
- player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Show stored active relic from acc var.
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, activeRelicId);
- player.getAccountVariables().storeMe();
-
  player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
  player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
  }
Title: Re: Relic System
Post by: GuruGel on February 12, 2025, 08:32:07 AM
#FIX version 3 (with character variables)
- Create and apply this DIFF path:
Code: (diff) [Select]
diff --git java/org/l2jmobius/gameserver/model/actor/Player.java java/org/l2jmobius/gameserver/model/actor/Player.java
index b3a5b07..d2ad8c5 100644
--- java/org/l2jmobius/gameserver/model/actor/Player.java
+++ java/org/l2jmobius/gameserver/model/actor/Player.java
@@ -16123,7 +16123,6 @@
  if (holder != null)
  {
  _relics.add(new PlayerRelicData(relicId, relicLevel, relicCount, relicIndex, relicSummonTime));
- giveRelicSkill(holder);
  }
  }
  }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index 6b6bd1b..075b5ab 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -65,6 +65,7 @@
 import org.l2jmobius.gameserver.model.clan.Clan;
 import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
 import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
+import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
 import org.l2jmobius.gameserver.model.instancezone.Instance;
 import org.l2jmobius.gameserver.model.item.ItemTemplate;
 import org.l2jmobius.gameserver.model.item.instance.Item;
@@ -148,6 +149,7 @@
 import org.l2jmobius.gameserver.network.serverpackets.olympiad.ExOlympiadInfo;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestDialog;
 import org.l2jmobius.gameserver.network.serverpackets.quest.ExQuestNotificationAll;
+import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsCollectionInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
@@ -807,14 +809,6 @@
  }
  player.sendPacket(new ExCollectionActiveEvent());
 
- // Relic Collections.
- if (Config.RELIC_SYSTEM_ENABLED)
- {
- player.sendPacket(new ExRelicsList(player));
- player.sendPacket(new ExRelicsCollectionInfo(player));
- player.sendPacket(new ExRelicsExchangeList(player));
- }
-
  // Virtual Items
  // TODO: Add a config for this.
  // player.sendPacket(new ExVirtualItemSystemBaseInfo(player));
@@ -979,6 +973,9 @@
 
  // Remove variable used by hunting zone system.
  player.getVariables().remove(PlayerVariables.LAST_HUNTING_ZONE_ID);
+
+ // Relic
+ relicSystem(getPlayer());
  }
 
  /**
@@ -1024,4 +1021,27 @@
  }
  }
  }
+
+ private void relicSystem(Player player)
+ {
+ if (Config.RELIC_SYSTEM_ENABLED)
+ {
+ int activeRelicId = player.getVariables().getInt(AccountVariables.ACTIVE_RELIC, 0);
+ int activeRelicLevel = 0;
+ for (PlayerRelicData relic : player.getRelics())
+ {
+ if (relic.getRelicId() == activeRelicId)
+ {
+ activeRelicId = relic.getRelicId();
+ activeRelicLevel = relic.getRelicLevel();
+ break;
+ }
+ }
+ player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Stored active relic from acc var.
+ player.sendPacket(new ExRelicsCollectionInfo(player));
+ player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
+ player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
+ }
+ }
+
 }
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
index 2bd917a..0383eb3 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsActive.java
@@ -65,8 +65,7 @@
  final int skillId = RelicData.getInstance().getRelicSkillId(_relicId);
  final int skillLevel = relicLevel + 1;
  player.sendPacket(new ExRelicsActiveInfo(_relicId, relicLevel));
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, _relicId);
- player.getAccountVariables().storeMe();
+ player.getVariables().set(AccountVariables.ACTIVE_RELIC, _relicId);
 
  final Skill relicSkill = SkillData.getInstance().getSkill(skillId, skillLevel);
  if (relicSkill != null)
diff --git java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
index 0f4d0f5..715b525 100644
--- java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
+++ java/org/l2jmobius/gameserver/network/clientpackets/relics/RequestRelicsOpenUI.java
@@ -21,10 +21,7 @@
 package org.l2jmobius.gameserver.network.clientpackets.relics;
 
 import org.l2jmobius.gameserver.model.actor.Player;
-import org.l2jmobius.gameserver.model.holders.PlayerRelicData;
-import org.l2jmobius.gameserver.model.variables.AccountVariables;
 import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
-import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsActiveInfo;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsExchangeList;
 import org.l2jmobius.gameserver.network.serverpackets.relics.ExRelicsList;
 
@@ -47,21 +44,6 @@
  return;
  }
 
- int activeRelicId = 0;
- int activeRelicLevel = 0;
- for (PlayerRelicData relic : player.getRelics())
- {
- if (relic.getRelicId() == player.getAccountVariables().getInt(AccountVariables.ACTIVE_RELIC, 0))
- {
- activeRelicId = relic.getRelicId();
- activeRelicLevel = relic.getRelicLevel();
- break;
- }
- }
- player.sendPacket(new ExRelicsActiveInfo(activeRelicId, activeRelicLevel)); // Show stored active relic from acc var.
- player.getAccountVariables().set(AccountVariables.ACTIVE_RELIC, activeRelicId);
- player.getAccountVariables().storeMe();
-
  player.sendPacket(new ExRelicsList(player)); // Update confirmed relic list relics count.
  player.sendPacket(new ExRelicsExchangeList(player)); // Update relic exchange/confirm list.
  }

I don't know about others, but I like the second version better... It puts less load on the server and database.
Title: Re: Relic System
Post by: gigilo1968 on February 12, 2025, 09:24:29 AM
In diff V3 - Not need Edit queries: SELECT_ACTIVE_RELIC /  INSERT_ACTIVE_RELIC / UPDATE_ACTIVE_RELIC ?  ;)
Title: Re: Relic System
Post by: shifu on February 12, 2025, 11:20:13 AM
In diff V3 - Not need Edit queries: SELECT_ACTIVE_RELIC /  INSERT_ACTIVE_RELIC / UPDATE_ACTIVE_RELIC ?  ;)
When working with variables, you can do without them. The existing queries in the source code are used. Which simplified the patch.  ;)