From 2dc01faa53a5317a8560d62b2b638a9b2ac899f3 Mon Sep 17 00:00:00 2001
From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com>
Date: Wed, 19 May 2021 21:23:03 +0000
Subject: [PATCH] Addition of purge system. Contributed by iDesy.
---
.../db_installer/sql/game/character_purge.sql | 8 +
.../dist/game/config/General.ini | 8 +
.../dist/game/data/SubjugationData.xml | 128 +++++++++
.../dist/game/data/SubjugationGacha.xml | 58 ++++
.../others/Subjugation/CrumaTowerPurge.java | 84 ++++++
.../others/Subjugation/DragonValleyPurge.java | 84 ++++++
.../others/Subjugation/OrcBarracksPurge.java | 84 ++++++
.../PlainsOfTheLizardmenPurge.java | 84 ++++++
.../others/Subjugation/SelMahumBasePurge.java | 84 ++++++
.../others/Subjugation/SilentValleyPurge.java | 84 ++++++
.../Subjugation/TowerOfInsolencePurge.java | 84 ++++++
.../dist/game/data/xsd/Subjugation.xsd | 24 ++
.../dist/game/data/xsd/SubjugationGacha.xsd | 22 ++
.../java/org/l2jmobius/Config.java | 6 +-
.../org/l2jmobius/gameserver/GameServer.java | 6 +
.../gameserver/data/xml/SubjugationData.java | 90 ++++++
.../gameserver/data/xml/SubjugationGacha.java | 84 ++++++
.../l2jmobius/gameserver/enums/MailType.java | 4 +-
.../GlobalVariablesManager.java | 1 +
.../instancemanager/PurgeRankingManager.java | 259 ++++++++++++++++++
.../model/actor/instance/PlayerInstance.java | 81 ++++++
.../model/holders/PurgePlayerHolder.java | 42 +++
.../model/holders/SubjugationHolder.java | 52 ++++
.../gameserver/network/ExIncomingPackets.java | 14 +-
.../subjugation/RequestSubjugationGacha.java | 88 ++++++
.../RequestSubjugationGachaUI.java | 50 ++++
.../subjugation/RequestSubjugationList.java | 47 ++++
.../RequestSubjugationRanking.java | 50 ++++
.../subjugation/ExSubjugationGacha.java | 49 ++++
.../subjugation/ExSubjugationGachaUI.java | 42 +++
.../subjugation/ExSubjugationList.java | 55 ++++
.../subjugation/ExSubjugationRanking.java | 59 ++++
.../subjugation/ExSubjugationSidebar.java | 48 ++++
L2J_Mobius_Essence_5.0_Sylph/readme.txt | 1 +
34 files changed, 1956 insertions(+), 8 deletions(-)
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/db_installer/sql/game/character_purge.sql
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/SubjugationData.xml
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/SubjugationGacha.xml
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/CrumaTowerPurge.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/DragonValleyPurge.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/OrcBarracksPurge.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/PlainsOfTheLizardmenPurge.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/SelMahumBasePurge.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/SilentValleyPurge.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/TowerOfInsolencePurge.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/xsd/Subjugation.xsd
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/dist/game/data/xsd/SubjugationGacha.xsd
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/SubjugationData.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/SubjugationGacha.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/PurgeRankingManager.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/holders/PurgePlayerHolder.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/holders/SubjugationHolder.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationGacha.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationGachaUI.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationList.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationRanking.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationGacha.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationGachaUI.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationList.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationRanking.java
create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationSidebar.java
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/db_installer/sql/game/character_purge.sql b/L2J_Mobius_Essence_5.0_Sylph/dist/db_installer/sql/game/character_purge.sql
new file mode 100644
index 0000000000..c324505a25
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/db_installer/sql/game/character_purge.sql
@@ -0,0 +1,8 @@
+DROP TABLE IF EXISTS `character_purge`;
+CREATE TABLE IF NOT EXISTS `character_purge` (
+ `charId` int(10) unsigned NOT NULL DEFAULT 0,
+ `category` int(3) UNSIGNED NOT NULL DEFAULT 0,
+ `points` int(10) UNSIGNED NOT NULL DEFAULT 0,
+ `keys` int(10) UNSIGNED NOT NULL DEFAULT 0,
+ PRIMARY KEY (`charId`,`category`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/config/General.ini b/L2J_Mobius_Essence_5.0_Sylph/dist/game/config/General.ini
index c9df7fcf50..d79154252b 100644
--- a/L2J_Mobius_Essence_5.0_Sylph/dist/game/config/General.ini
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/config/General.ini
@@ -658,6 +658,14 @@ EnableAutoBuff = True
EnableAutoItem = True
+# ---------------------------------------------------------------------------
+# Purge Settings
+# ---------------------------------------------------------------------------
+# Purge reward mail message.
+SubjugationTopicHeader = Purge reward
+SubjugationTopicBody = Reward for being in the top of the best players in clearing the lands of Aden
+
+
# ---------------------------------------------------------------------------
# Developer Settings
# ---------------------------------------------------------------------------
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/SubjugationData.xml b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/SubjugationData.xml
new file mode 100644
index 0000000000..2920f947d2
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/SubjugationData.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/SubjugationGacha.xml b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/SubjugationGacha.xml
new file mode 100644
index 0000000000..b70c08bc33
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/SubjugationGacha.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/CrumaTowerPurge.java b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/CrumaTowerPurge.java
new file mode 100644
index 0000000000..a295f90815
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/CrumaTowerPurge.java
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ai.others.Subjugation;
+
+import java.util.Calendar;
+
+import org.l2jmobius.gameserver.data.xml.SubjugationData;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.model.holders.SubjugationHolder;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationSidebar;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class CrumaTowerPurge extends AbstractNpcAI
+{
+ private static final int CATEGORY = 1;
+ private static final int PURGE_MAX_POINT = 1000000;
+ private static final SubjugationHolder PURGE_DATA = SubjugationData.getInstance().getSubjugation(CATEGORY);
+
+ private CrumaTowerPurge()
+ {
+ addKillId(PURGE_DATA.getNpcs().keySet().stream().mapToInt(it -> it).toArray());
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (killer.getVitalityPoints() > 0)
+ {
+ boolean isHotTime = false;
+ for (int[] it : SubjugationData.getInstance().getSubjugation(CATEGORY).getHottimes())
+ {
+ final int minHour = it[0];
+ final int maxHour = it[1];
+ final int currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
+ if ((currentHour >= minHour) && (maxHour > currentHour))
+ {
+ isHotTime = true;
+ }
+ }
+ final int pointsForMob = isHotTime ? PURGE_DATA.getNpcs().get(npc.getId()) * 2 : PURGE_DATA.getNpcs().get(npc.getId());
+ final int currentPurgePoints = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getPoints();
+ final int currentKeys = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getKeys();
+ killer.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(Math.min(PURGE_MAX_POINT, currentPurgePoints + pointsForMob), currentKeys));
+ checkPurgeComplete(killer);
+ killer.sendPacket(new ExSubjugationSidebar(CATEGORY, killer.getPurgePoints().get(CATEGORY)));
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ private void checkPurgeComplete(PlayerInstance player)
+ {
+ final int points = player.getPurgePoints().get(CATEGORY).getPoints();
+ final int keys = player.getPurgePoints().get(CATEGORY).getKeys();
+ if ((points >= PURGE_MAX_POINT) && (keys < 70))
+ {
+ player.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(points - PURGE_MAX_POINT, keys + 1));
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new CrumaTowerPurge();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/DragonValleyPurge.java b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/DragonValleyPurge.java
new file mode 100644
index 0000000000..7d05fa7ca1
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/DragonValleyPurge.java
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ai.others.Subjugation;
+
+import java.util.Calendar;
+
+import org.l2jmobius.gameserver.data.xml.SubjugationData;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.model.holders.SubjugationHolder;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationSidebar;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class DragonValleyPurge extends AbstractNpcAI
+{
+ private static final int CATEGORY = 5;
+ private static final int PURGE_MAX_POINT = 1000000;
+ private static final SubjugationHolder PURGE_DATA = SubjugationData.getInstance().getSubjugation(CATEGORY);
+
+ private DragonValleyPurge()
+ {
+ addKillId(PURGE_DATA.getNpcs().keySet().stream().mapToInt(it -> it).toArray());
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (killer.getVitalityPoints() > 0)
+ {
+ boolean isHotTime = false;
+ for (int[] it : SubjugationData.getInstance().getSubjugation(CATEGORY).getHottimes())
+ {
+ final int minHour = it[0];
+ final int maxHour = it[1];
+ final int currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
+ if ((currentHour >= minHour) && (maxHour > currentHour))
+ {
+ isHotTime = true;
+ }
+ }
+ final int pointsForMob = isHotTime ? PURGE_DATA.getNpcs().get(npc.getId()) * 2 : PURGE_DATA.getNpcs().get(npc.getId());
+ final int currentPurgePoints = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getPoints();
+ final int currentKeys = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getKeys();
+ killer.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(Math.min(PURGE_MAX_POINT, currentPurgePoints + pointsForMob), currentKeys));
+ checkPurgeComplete(killer);
+ killer.sendPacket(new ExSubjugationSidebar(CATEGORY, killer.getPurgePoints().get(CATEGORY)));
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ private void checkPurgeComplete(PlayerInstance player)
+ {
+ final int points = player.getPurgePoints().get(CATEGORY).getPoints();
+ final int keys = player.getPurgePoints().get(CATEGORY).getKeys();
+ if ((points >= PURGE_MAX_POINT) && (keys < 70))
+ {
+ player.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(points - PURGE_MAX_POINT, keys + 1));
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new DragonValleyPurge();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/OrcBarracksPurge.java b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/OrcBarracksPurge.java
new file mode 100644
index 0000000000..481aab9614
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/OrcBarracksPurge.java
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ai.others.Subjugation;
+
+import java.util.Calendar;
+
+import org.l2jmobius.gameserver.data.xml.SubjugationData;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.model.holders.SubjugationHolder;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationSidebar;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class OrcBarracksPurge extends AbstractNpcAI
+{
+ private static final int CATEGORY = 7;
+ private static final int PURGE_MAX_POINT = 1000000;
+ private static final SubjugationHolder PURGE_DATA = SubjugationData.getInstance().getSubjugation(CATEGORY);
+
+ private OrcBarracksPurge()
+ {
+ addKillId(PURGE_DATA.getNpcs().keySet().stream().mapToInt(it -> it).toArray());
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (killer.getVitalityPoints() > 0)
+ {
+ boolean isHotTime = false;
+ for (int[] it : SubjugationData.getInstance().getSubjugation(CATEGORY).getHottimes())
+ {
+ final int minHour = it[0];
+ final int maxHour = it[1];
+ final int currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
+ if ((currentHour >= minHour) && (maxHour > currentHour))
+ {
+ isHotTime = true;
+ }
+ }
+ final int pointsForMob = isHotTime ? PURGE_DATA.getNpcs().get(npc.getId()) * 2 : PURGE_DATA.getNpcs().get(npc.getId());
+ final int currentPurgePoints = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getPoints();
+ final int currentKeys = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getKeys();
+ killer.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(Math.min(PURGE_MAX_POINT, currentPurgePoints + pointsForMob), currentKeys));
+ checkPurgeComplete(killer);
+ killer.sendPacket(new ExSubjugationSidebar(CATEGORY, killer.getPurgePoints().get(CATEGORY)));
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ private void checkPurgeComplete(PlayerInstance player)
+ {
+ final int points = player.getPurgePoints().get(CATEGORY).getPoints();
+ final int keys = player.getPurgePoints().get(CATEGORY).getKeys();
+ if ((points >= PURGE_MAX_POINT) && (keys < 70))
+ {
+ player.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(points - PURGE_MAX_POINT, keys + 1));
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new OrcBarracksPurge();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/PlainsOfTheLizardmenPurge.java b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/PlainsOfTheLizardmenPurge.java
new file mode 100644
index 0000000000..9adf7f3002
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/PlainsOfTheLizardmenPurge.java
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ai.others.Subjugation;
+
+import java.util.Calendar;
+
+import org.l2jmobius.gameserver.data.xml.SubjugationData;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.model.holders.SubjugationHolder;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationSidebar;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class PlainsOfTheLizardmenPurge extends AbstractNpcAI
+{
+ private static final int CATEGORY = 3;
+ private static final int PURGE_MAX_POINT = 1000000;
+ private static final SubjugationHolder PURGE_DATA = SubjugationData.getInstance().getSubjugation(CATEGORY);
+
+ private PlainsOfTheLizardmenPurge()
+ {
+ addKillId(PURGE_DATA.getNpcs().keySet().stream().mapToInt(it -> it).toArray());
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (killer.getVitalityPoints() > 0)
+ {
+ boolean isHotTime = false;
+ for (int[] it : SubjugationData.getInstance().getSubjugation(CATEGORY).getHottimes())
+ {
+ final int minHour = it[0];
+ final int maxHour = it[1];
+ final int currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
+ if ((currentHour >= minHour) && (maxHour > currentHour))
+ {
+ isHotTime = true;
+ }
+ }
+ final int pointsForMob = isHotTime ? PURGE_DATA.getNpcs().get(npc.getId()) * 2 : PURGE_DATA.getNpcs().get(npc.getId());
+ final int currentPurgePoints = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getPoints();
+ final int currentKeys = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getKeys();
+ killer.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(Math.min(PURGE_MAX_POINT, currentPurgePoints + pointsForMob), currentKeys));
+ checkPurgeComplete(killer);
+ killer.sendPacket(new ExSubjugationSidebar(CATEGORY, killer.getPurgePoints().get(CATEGORY)));
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ private void checkPurgeComplete(PlayerInstance player)
+ {
+ final int points = player.getPurgePoints().get(CATEGORY).getPoints();
+ final int keys = player.getPurgePoints().get(CATEGORY).getKeys();
+ if ((points >= PURGE_MAX_POINT) && (keys < 70))
+ {
+ player.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(points - PURGE_MAX_POINT, keys + 1));
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new PlainsOfTheLizardmenPurge();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/SelMahumBasePurge.java b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/SelMahumBasePurge.java
new file mode 100644
index 0000000000..9cd542ca9a
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/SelMahumBasePurge.java
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ai.others.Subjugation;
+
+import java.util.Calendar;
+
+import org.l2jmobius.gameserver.data.xml.SubjugationData;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.model.holders.SubjugationHolder;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationSidebar;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class SelMahumBasePurge extends AbstractNpcAI
+{
+ private static final int CATEGORY = 6;
+ private static final int PURGE_MAX_POINT = 1000000;
+ private static final SubjugationHolder PURGE_DATA = SubjugationData.getInstance().getSubjugation(CATEGORY);
+
+ private SelMahumBasePurge()
+ {
+ addKillId(PURGE_DATA.getNpcs().keySet().stream().mapToInt(it -> it).toArray());
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (killer.getVitalityPoints() > 0)
+ {
+ boolean isHotTime = false;
+ for (int[] it : SubjugationData.getInstance().getSubjugation(CATEGORY).getHottimes())
+ {
+ final int minHour = it[0];
+ final int maxHour = it[1];
+ final int currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
+ if ((currentHour >= minHour) && (maxHour > currentHour))
+ {
+ isHotTime = true;
+ }
+ }
+ final int pointsForMob = isHotTime ? PURGE_DATA.getNpcs().get(npc.getId()) * 2 : PURGE_DATA.getNpcs().get(npc.getId());
+ final int currentPurgePoints = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getPoints();
+ final int currentKeys = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getKeys();
+ killer.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(Math.min(PURGE_MAX_POINT, currentPurgePoints + pointsForMob), currentKeys));
+ checkPurgeComplete(killer);
+ killer.sendPacket(new ExSubjugationSidebar(CATEGORY, killer.getPurgePoints().get(CATEGORY)));
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ private void checkPurgeComplete(PlayerInstance player)
+ {
+ final int points = player.getPurgePoints().get(CATEGORY).getPoints();
+ final int keys = player.getPurgePoints().get(CATEGORY).getKeys();
+ if ((points >= PURGE_MAX_POINT) && (keys < 70))
+ {
+ player.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(points - PURGE_MAX_POINT, keys + 1));
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new SelMahumBasePurge();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/SilentValleyPurge.java b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/SilentValleyPurge.java
new file mode 100644
index 0000000000..b6632c2c73
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/SilentValleyPurge.java
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ai.others.Subjugation;
+
+import java.util.Calendar;
+
+import org.l2jmobius.gameserver.data.xml.SubjugationData;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.model.holders.SubjugationHolder;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationSidebar;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class SilentValleyPurge extends AbstractNpcAI
+{
+ private static final int CATEGORY = 2;
+ private static final int PURGE_MAX_POINT = 1000000;
+ private static final SubjugationHolder PURGE_DATA = SubjugationData.getInstance().getSubjugation(CATEGORY);
+
+ private SilentValleyPurge()
+ {
+ addKillId(PURGE_DATA.getNpcs().keySet().stream().mapToInt(it -> it).toArray());
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (killer.getVitalityPoints() > 0)
+ {
+ boolean isHotTime = false;
+ for (int[] it : SubjugationData.getInstance().getSubjugation(CATEGORY).getHottimes())
+ {
+ final int minHour = it[0];
+ final int maxHour = it[1];
+ final int currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
+ if ((currentHour >= minHour) && (maxHour > currentHour))
+ {
+ isHotTime = true;
+ }
+ }
+ final int pointsForMob = isHotTime ? PURGE_DATA.getNpcs().get(npc.getId()) * 2 : PURGE_DATA.getNpcs().get(npc.getId());
+ final int currentPurgePoints = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getPoints();
+ final int currentKeys = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getKeys();
+ killer.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(Math.min(PURGE_MAX_POINT, currentPurgePoints + pointsForMob), currentKeys));
+ checkPurgeComplete(killer);
+ killer.sendPacket(new ExSubjugationSidebar(CATEGORY, killer.getPurgePoints().get(CATEGORY)));
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ private void checkPurgeComplete(PlayerInstance player)
+ {
+ final int points = player.getPurgePoints().get(CATEGORY).getPoints();
+ final int keys = player.getPurgePoints().get(CATEGORY).getKeys();
+ if ((points >= PURGE_MAX_POINT) && (keys < 70))
+ {
+ player.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(points - PURGE_MAX_POINT, keys + 1));
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new SilentValleyPurge();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/TowerOfInsolencePurge.java b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/TowerOfInsolencePurge.java
new file mode 100644
index 0000000000..7b0f1552db
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/scripts/ai/others/Subjugation/TowerOfInsolencePurge.java
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ai.others.Subjugation;
+
+import java.util.Calendar;
+
+import org.l2jmobius.gameserver.data.xml.SubjugationData;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.model.holders.SubjugationHolder;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationSidebar;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class TowerOfInsolencePurge extends AbstractNpcAI
+{
+ private static final int CATEGORY = 4;
+ private static final int PURGE_MAX_POINT = 1000000;
+ private static final SubjugationHolder PURGE_DATA = SubjugationData.getInstance().getSubjugation(CATEGORY);
+
+ private TowerOfInsolencePurge()
+ {
+ addKillId(PURGE_DATA.getNpcs().keySet().stream().mapToInt(it -> it).toArray());
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (killer.getVitalityPoints() > 0)
+ {
+ boolean isHotTime = false;
+ for (int[] it : SubjugationData.getInstance().getSubjugation(CATEGORY).getHottimes())
+ {
+ final int minHour = it[0];
+ final int maxHour = it[1];
+ final int currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
+ if ((currentHour >= minHour) && (maxHour > currentHour))
+ {
+ isHotTime = true;
+ }
+ }
+ final int pointsForMob = isHotTime ? PURGE_DATA.getNpcs().get(npc.getId()) * 2 : PURGE_DATA.getNpcs().get(npc.getId());
+ final int currentPurgePoints = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getPoints();
+ final int currentKeys = (killer.getPurgePoints().get(CATEGORY) == null) ? 0 : killer.getPurgePoints().get(CATEGORY).getKeys();
+ killer.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(Math.min(PURGE_MAX_POINT, currentPurgePoints + pointsForMob), currentKeys));
+ checkPurgeComplete(killer);
+ killer.sendPacket(new ExSubjugationSidebar(CATEGORY, killer.getPurgePoints().get(CATEGORY)));
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ private void checkPurgeComplete(PlayerInstance player)
+ {
+ final int points = player.getPurgePoints().get(CATEGORY).getPoints();
+ final int keys = player.getPurgePoints().get(CATEGORY).getKeys();
+ if ((points >= PURGE_MAX_POINT) && (keys < 70))
+ {
+ player.getPurgePoints().put(CATEGORY, new PurgePlayerHolder(points - PURGE_MAX_POINT, keys + 1));
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new TowerOfInsolencePurge();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/xsd/Subjugation.xsd b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/xsd/Subjugation.xsd
new file mode 100644
index 0000000000..6cab924af8
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/xsd/Subjugation.xsd
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/xsd/SubjugationGacha.xsd b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/xsd/SubjugationGacha.xsd
new file mode 100644
index 0000000000..9960d20615
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/dist/game/data/xsd/SubjugationGacha.xsd
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/Config.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/Config.java
index 54b079369a..570edc5b3e 100644
--- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/Config.java
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/Config.java
@@ -1317,6 +1317,8 @@ public class Config
public static Map L2JBRASIL_REWARD = new HashMap<>();
public static int L2JBRASIL_DUALBOXES_ALLOWED;
public static boolean ALLOW_L2JBRASIL_GAME_SERVER_REPORT;
+ public static String SUBJUGATION_TOPIC_HEADER;
+ public static String SUBJUGATION_TOPIC_BODY;
public static boolean ENABLE_GUI;
public static boolean DARK_THEME;
@@ -2104,8 +2106,8 @@ public class Config
ENABLE_AUTO_POTION = General.getBoolean("EnableAutoPotion", true);
ENABLE_AUTO_BUFF = General.getBoolean("EnableAutoBuff", true);
ENABLE_AUTO_ITEM = General.getBoolean("EnableAutoItem", true);
-
- // Share Location
+ SUBJUGATION_TOPIC_BODY = General.getString("SubjugationTopicBody", "Reward for being in the top of the best players in clearing the lands of Aden");
+ SUBJUGATION_TOPIC_HEADER = General.getString("SubjugationTopicHeader", "Purge reward");
SHARING_LOCATION_COST = General.getInt("ShareLocationLcoinCost", 1);
TELEPORT_SHARE_LOCATION_COST = General.getInt("ShareLocationLcoinCost", 1);
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/GameServer.java
index 231931f82e..cfb8443ca5 100644
--- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/GameServer.java
@@ -108,6 +108,8 @@ import org.l2jmobius.gameserver.data.xml.SkillData;
import org.l2jmobius.gameserver.data.xml.SkillTreeData;
import org.l2jmobius.gameserver.data.xml.SpawnData;
import org.l2jmobius.gameserver.data.xml.StaticObjectData;
+import org.l2jmobius.gameserver.data.xml.SubjugationData;
+import org.l2jmobius.gameserver.data.xml.SubjugationGacha;
import org.l2jmobius.gameserver.data.xml.TeleportListData;
import org.l2jmobius.gameserver.data.xml.TeleporterData;
import org.l2jmobius.gameserver.data.xml.TimedHuntingZoneData;
@@ -148,6 +150,7 @@ import org.l2jmobius.gameserver.instancemanager.PetitionManager;
import org.l2jmobius.gameserver.instancemanager.PrecautionaryRestartManager;
import org.l2jmobius.gameserver.instancemanager.PremiumManager;
import org.l2jmobius.gameserver.instancemanager.PunishmentManager;
+import org.l2jmobius.gameserver.instancemanager.PurgeRankingManager;
import org.l2jmobius.gameserver.instancemanager.QuestManager;
import org.l2jmobius.gameserver.instancemanager.RankManager;
import org.l2jmobius.gameserver.instancemanager.SellBuffsManager;
@@ -262,6 +265,9 @@ public class GameServer
DailyMissionHandler.getInstance().executeScript();
DailyMissionData.getInstance();
ElementalSpiritData.getInstance();
+ SubjugationData.getInstance();
+ SubjugationGacha.getInstance();
+ PurgeRankingManager.getInstance();
printSection("Skills");
SkillConditionHandler.getInstance().executeScript();
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/SubjugationData.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/SubjugationData.java
new file mode 100644
index 0000000000..d5fec25ce8
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/SubjugationData.java
@@ -0,0 +1,90 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatSet;
+import org.l2jmobius.gameserver.model.holders.SubjugationHolder;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class SubjugationData implements IXmlReader
+{
+ private static final Logger LOGGER = Logger.getLogger(SubjugationData.class.getName());
+
+ private static final List _subjugations = new ArrayList<>();
+
+ public SubjugationData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ _subjugations.clear();
+ parseDatapackFile("data/SubjugationData.xml");
+ LOGGER.info(getClass().getSimpleName() + ": Loaded " + _subjugations.size() + " data.");
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "purge", purgeNode ->
+ {
+ final StatSet set = new StatSet(parseAttributes(purgeNode));
+ final int category = set.getInt("category");
+ final List hottimes = Arrays.stream(set.getString("hottimes").split(";")).map(it -> Arrays.stream(it.split("-")).mapToInt(Integer::parseInt).toArray()).collect(Collectors.toList());
+ final Map npcs = new HashMap<>();
+ forEach(purgeNode, "npc", npcNode ->
+ {
+ final StatSet stats = new StatSet(parseAttributes(npcNode));
+ final int npcId = stats.getInt("id");
+ final int points = stats.getInt("points");
+ npcs.put(npcId, points);
+ });
+ _subjugations.add(new SubjugationHolder(category, hottimes, npcs));
+ }));
+ }
+
+ public SubjugationHolder getSubjugation(int category)
+ {
+ return _subjugations.stream().filter(it -> it.getCategory() == category).findFirst().orElse(null);
+ }
+
+ public static SubjugationData getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final SubjugationData INSTANCE = new SubjugationData();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/SubjugationGacha.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/SubjugationGacha.java
new file mode 100644
index 0000000000..03b0caec12
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/SubjugationGacha.java
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.data.xml;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatSet;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class SubjugationGacha implements IXmlReader
+{
+ private static final Logger LOGGER = Logger.getLogger(SubjugationGacha.class.getName());
+
+ private static final Map> _subjugations = new HashMap<>();
+
+ public SubjugationGacha()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ _subjugations.clear();
+ parseDatapackFile("data/SubjugationGacha.xml");
+ LOGGER.info(getClass().getSimpleName() + ": Loaded " + _subjugations.size() + " data.");
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, "purge", purgeNode ->
+ {
+ final StatSet set = new StatSet(parseAttributes(purgeNode));
+ final int category = set.getInt("category");
+ final Map items = new HashMap<>();
+ forEach(purgeNode, "item", npcNode ->
+ {
+ final StatSet stats = new StatSet(parseAttributes(npcNode));
+ final int itemId = stats.getInt("id");
+ final double rate = stats.getDouble("rate");
+ items.put(itemId, rate);
+ });
+ _subjugations.put(category, items);
+ }));
+ }
+
+ public Map getSubjugation(int category)
+ {
+ return _subjugations.get(category);
+ }
+
+ public static SubjugationGacha getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final SubjugationGacha INSTANCE = new SubjugationGacha();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/enums/MailType.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/enums/MailType.java
index 32b9176b31..86699332eb 100644
--- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/enums/MailType.java
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/enums/MailType.java
@@ -28,5 +28,7 @@ public enum MailType
COMMISSION_ITEM_RETURNED,
COMMISSION_ITEM_SOLD,
MENTOR_NPC,
- PRIME_SHOP_GIFT
+ PRIME_SHOP_GIFT,
+ PURGE_REWARD,
+ PLEDGE_DONATION_CRITICAL_SUCCESS
}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/GlobalVariablesManager.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/GlobalVariablesManager.java
index 1a2ab29759..beddcd9a04 100644
--- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/GlobalVariablesManager.java
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/GlobalVariablesManager.java
@@ -46,6 +46,7 @@ public class GlobalVariablesManager extends AbstractVariables
public static final String COC_TOP_MEMBER = "COC_TOP_MEMBER";
public static final String COC_TRUE_HERO = "COC_TRUE_HERO";
public static final String COC_TRUE_HERO_REWARDED = "COC_TRUE_HERO_REWARDED";
+ public static final String PURGE_REWARD_TIME = "PURGE_REWARD_TIME";
protected GlobalVariablesManager()
{
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/PurgeRankingManager.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/PurgeRankingManager.java
new file mode 100644
index 0000000000..da54d4fb7f
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/PurgeRankingManager.java
@@ -0,0 +1,259 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.instancemanager;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.commons.database.DatabaseFactory;
+import org.l2jmobius.commons.util.Chronos;
+import org.l2jmobius.gameserver.data.sql.CharNameTable;
+import org.l2jmobius.gameserver.enums.MailType;
+import org.l2jmobius.gameserver.model.Message;
+import org.l2jmobius.gameserver.model.StatSet;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.model.itemcontainer.Mail;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationSidebar;
+
+/**
+ * @author Berezkin Nikolay
+ */
+public class PurgeRankingManager
+{
+ protected static final Logger LOGGER = Logger.getLogger(PurgeRankingManager.class.getName());
+
+ private static final Map> _ranking = new HashMap<>();
+ private static final String RESTORE_SUBJUGATION = "SELECT *, `points` + `keys` * 1000000 as `total` FROM `character_purge` WHERE `category`=? ORDER BY `total` DESC";
+ private static final String DELETE_SUBJUGATION = "DELETE FROM character_purge WHERE charId=? and category=?";
+
+ public PurgeRankingManager()
+ {
+ updateRankingFromDB();
+
+ int nextDate = Calendar.getInstance().get(Calendar.MINUTE);
+ while ((nextDate % 5) != 0)
+ {
+ nextDate = nextDate + 1;
+ }
+
+ ThreadPool.scheduleAtFixedRate(this::updateRankingFromDB, (nextDate - Calendar.getInstance().get(Calendar.MINUTE)) > 0 ? (long) (nextDate - Calendar.getInstance().get(Calendar.MINUTE)) * 60 * 1000 : (long) ((nextDate + 60) - Calendar.getInstance().get(Calendar.MINUTE)) * 60 * 1000, 300000);
+ }
+
+ private void updateRankingFromDB()
+ {
+ // Weekly rewards.
+ final long lastPurgeRewards = GlobalVariablesManager.getInstance().getLong(GlobalVariablesManager.PURGE_REWARD_TIME, 0);
+ if ((Calendar.getInstance().get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) && ((Chronos.currentTimeMillis() - lastPurgeRewards) > (604800000 /* 1 week */ - 600000 /* task delay x2 */)))
+ {
+ GlobalVariablesManager.getInstance().set(GlobalVariablesManager.PURGE_REWARD_TIME, Chronos.currentTimeMillis());
+ for (int category = 1; category <= 7; category++)
+ {
+ if (getTop5(category) != null)
+ {
+ int counter = 0;
+ for (Entry purgeData : getTop5(category).entrySet())
+ {
+ final int charId = CharNameTable.getInstance().getIdByName(purgeData.getKey());
+ final Message msg = new Message(charId, Config.SUBJUGATION_TOPIC_HEADER, Config.SUBJUGATION_TOPIC_BODY, MailType.PURGE_REWARD);
+ final Mail attachment = msg.createAttachments();
+ int reward;
+ switch (category)
+ {
+ case 1:
+ {
+ reward = 95460;
+ break;
+ }
+ case 2:
+ {
+ reward = 95461;
+ break;
+ }
+ case 3:
+ {
+ reward = 95462;
+ break;
+ }
+ case 4:
+ {
+ reward = 95463;
+ break;
+ }
+ case 5:
+ {
+ reward = 95464;
+ break;
+ }
+ case 6:
+ {
+ reward = 96465;
+ break;
+ }
+ case 7:
+ {
+ reward = 96456;
+ break;
+ }
+ default:
+ {
+ throw new IllegalStateException("Unexpected value: " + category);
+ }
+ }
+ attachment.addItem("Purge reward", reward, 5 - counter, null, null);
+ MailManager.getInstance().sendMessage(msg);
+
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(DELETE_SUBJUGATION))
+ {
+ st.setInt(1, charId);
+ st.setInt(2, category);
+ st.execute();
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.SEVERE, "Failed to delete character subjugation info " + charId, e);
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.SEVERE, "Failed to delete character subjugation info " + charId, e);
+ }
+
+ final PlayerInstance onlinePlayer = World.getInstance().getPlayer(charId);
+ if (onlinePlayer != null)
+ {
+ onlinePlayer.getPurgePoints().clear();
+ onlinePlayer.sendPacket(new ExSubjugationSidebar(category, new PurgePlayerHolder(0, 0)));
+ }
+
+ counter++;
+ }
+ }
+ }
+ }
+
+ // Clear ranking.
+ _ranking.clear();
+
+ // Restore ranking.
+ for (int category = 1; category <= 7; category++)
+ {
+ restoreByCategories(category);
+ }
+ }
+
+ private void restoreByCategories(int category)
+ {
+ try (Connection con = DatabaseFactory.getConnection();
+ PreparedStatement statement = con.prepareStatement(RESTORE_SUBJUGATION))
+ {
+ statement.setInt(1, category);
+ try (ResultSet rset = statement.executeQuery())
+ {
+ int rank = 1;
+ Map rankingInCategory = new HashMap<>();
+ while (rset.next())
+ {
+ final StatSet set = new StatSet();
+ set.set("charId", rset.getInt("charId"));
+ set.set("points", rset.getInt("total"));
+ rankingInCategory.put(rank, set);
+ rank++;
+ }
+ _ranking.put(category, rankingInCategory);
+ }
+ // LOGGER.info(getClass().getSimpleName() + ": Loaded " + _ranking.get(category).size() + " records for category " + category + ".");
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.SEVERE, "Could not restore subjugation ranking data", e);
+ }
+ }
+
+ public Map getTop5(int category)
+ {
+ Map top5 = new HashMap<>();
+ for (int i = 1; i <= 5; i++)
+ {
+ try
+ {
+ if (_ranking.get(category) == null)
+ {
+ continue;
+ }
+
+ final StatSet ss = _ranking.get(category).get(i);
+ if (ss == null)
+ {
+ continue;
+ }
+
+ final String charName = CharNameTable.getInstance().getNameById(ss.getInt("charId"));
+ final int points = ss.getInt("points");
+ top5.put(charName, points);
+ }
+ catch (IndexOutOfBoundsException ignored)
+ {
+ }
+ }
+ return top5;
+ }
+
+ public SimpleEntry getPlayerRating(int category, int charId)
+ {
+ if (_ranking.get(category) == null)
+ {
+ return new SimpleEntry<>(0, 0);
+ }
+
+ final Optional> player = _ranking.get(category).entrySet().stream().filter(it -> it.getValue().getInt("charId") == charId).findFirst();
+ if (player.isPresent())
+ {
+ if (player.get().getValue() == null)
+ {
+ return new SimpleEntry<>(0, 0);
+ }
+ return new SimpleEntry<>(player.get().getKey(), player.get().getValue().getInt("points"));
+ }
+
+ return new SimpleEntry<>(0, 0);
+ }
+
+ public static PurgeRankingManager getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final PurgeRankingManager INSTANCE = new PurgeRankingManager();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index cc7c0b338a..ffde3c9043 100644
--- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -236,6 +236,7 @@ import org.l2jmobius.gameserver.model.holders.MovieHolder;
import org.l2jmobius.gameserver.model.holders.PlayerCollectionData;
import org.l2jmobius.gameserver.model.holders.PlayerEventHolder;
import org.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
import org.l2jmobius.gameserver.model.holders.SellBuffHolder;
import org.l2jmobius.gameserver.model.holders.SkillUseHolder;
import org.l2jmobius.gameserver.model.holders.SubClassHolder;
@@ -446,6 +447,11 @@ public class PlayerInstance extends Playable
private static final String INSERT_CHAR_RECIPE_SHOP = "REPLACE INTO character_recipeshoplist (`charId`, `recipeId`, `price`, `index`) VALUES (?, ?, ?, ?)";
private static final String RESTORE_CHAR_RECIPE_SHOP = "SELECT * FROM character_recipeshoplist WHERE charId=? ORDER BY `index`";
+ // Purge list:
+ private static final String DELETE_SUBJUGATION = "DELETE FROM character_purge WHERE charId=?";
+ private static final String INSERT_SUBJUGATION = "REPLACE INTO character_purge (`charId`, `category`, `points`, `keys`) VALUES (?, ?, ?, ?)";
+ private static final String RESTORE_SUBJUGATION = "SELECT * FROM character_purge WHERE charId=?";
+
// Elemental Spirits:
private static final String RESTORE_ELEMENTAL_SPIRITS = "SELECT * FROM character_spirits WHERE charId=?";
@@ -915,6 +921,8 @@ public class PlayerInstance extends Playable
private final List _collections = new ArrayList<>();
private final List _collectionFavorites = new ArrayList<>();
+ private final Map purgePoints = new HashMap<>();
+
private final List _questTimers = new ArrayList<>();
private final List> _timerHolders = new ArrayList<>();
@@ -6933,6 +6941,8 @@ public class PlayerInstance extends Playable
restoreCollectionBonuses();
restoreCollectionFavorites();
+ // Purge.
+ restoreSubjugation();
// Load Premium Item List.
loadPremiumItemList();
@@ -7084,6 +7094,9 @@ public class PlayerInstance extends Playable
storeCollections();
storeCollectionFavorites();
+ // Purge.
+ storeSubjugation();
+
final PlayerVariables vars = getScript(PlayerVariables.class);
if (vars != null)
{
@@ -14761,4 +14774,72 @@ public class PlayerInstance extends Playable
LOGGER.log(Level.SEVERE, "Could not restore collection favorite list data for playerId: " + getObjectId(), e);
}
}
+
+ public Map getPurgePoints()
+ {
+ return purgePoints;
+ }
+
+ public void storeSubjugation()
+ {
+ try (Connection con = DatabaseFactory.getConnection())
+ {
+ try (PreparedStatement st = con.prepareStatement(DELETE_SUBJUGATION))
+ {
+ st.setInt(1, getObjectId());
+ st.execute();
+ }
+
+ try (PreparedStatement st = con.prepareStatement(INSERT_SUBJUGATION))
+ {
+ getPurgePoints().forEach((category, data) ->
+ {
+ try
+ {
+ st.setInt(1, getObjectId());
+ st.setInt(2, category);
+ st.setInt(3, data.getPoints());
+ st.setInt(4, data.getKeys());
+ st.addBatch();
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.SEVERE, "Could not store subjugation data for playerId " + getObjectId() + ": ", e);
+ }
+ });
+ st.executeBatch();
+ con.commit();
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.SEVERE, "Could not store subjugation data for playerId " + getObjectId() + ": ", e);
+ }
+ }
+
+ private void restoreSubjugation()
+ {
+ if (purgePoints != null)
+ {
+ purgePoints.clear();
+ }
+
+ try (Connection con = DatabaseFactory.getConnection();
+ PreparedStatement statement = con.prepareStatement(RESTORE_SUBJUGATION))
+ {
+ statement.setInt(1, getObjectId());
+ try (ResultSet rset = statement.executeQuery())
+ {
+ while (rset.next())
+ {
+ purgePoints.put(rset.getInt("category"), new PurgePlayerHolder(rset.getInt("points"), rset.getInt("keys")));
+
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.SEVERE, "Could not restore subjugation data for playerId: " + getObjectId(), e);
+ }
+ }
}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/holders/PurgePlayerHolder.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/holders/PurgePlayerHolder.java
new file mode 100644
index 0000000000..7ce8b95ca2
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/holders/PurgePlayerHolder.java
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.model.holders;
+
+/**
+ * Written by Berezkin Nikolay, on 04.05.2021
+ */
+public class PurgePlayerHolder
+{
+ private final int _points;
+ private final int _keys;
+
+ public PurgePlayerHolder(int points, int keys)
+ {
+ _points = points;
+ _keys = keys;
+ }
+
+ public int getPoints()
+ {
+ return _points;
+ }
+
+ public int getKeys()
+ {
+ return _keys;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/holders/SubjugationHolder.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/holders/SubjugationHolder.java
new file mode 100644
index 0000000000..28f69eaddf
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/holders/SubjugationHolder.java
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.model.holders;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Written by Berezkin Nikolay, on 04.05.2021
+ */
+public class SubjugationHolder
+{
+ private final int _category;
+ private final List _hottimes;
+ private final Map _npcs;
+
+ public SubjugationHolder(int category, List hottimes, Map npcs)
+ {
+ _category = category;
+ _hottimes = hottimes;
+ _npcs = npcs;
+ }
+
+ public int getCategory()
+ {
+ return _category;
+ }
+
+ public List getHottimes()
+ {
+ return _hottimes;
+ }
+
+ public Map getNpcs()
+ {
+ return _npcs;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
index 7f7177b1fd..da1bfd8eb4 100644
--- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
@@ -46,13 +46,13 @@ import org.l2jmobius.gameserver.network.clientpackets.ceremonyofchaos.RequestCan
import org.l2jmobius.gameserver.network.clientpackets.ceremonyofchaos.RequestCuriousHouseHtml;
import org.l2jmobius.gameserver.network.clientpackets.ceremonyofchaos.RequestJoinCuriousHouse;
import org.l2jmobius.gameserver.network.clientpackets.classchange.ExRequestClassChange;
-import org.l2jmobius.gameserver.network.clientpackets.collection.RequestExCollectionOpenUI;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionCloseUI;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionFavoriteList;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionReceiveReward;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionRegister;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionUpdateFavorite;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestExCollectionList;
+import org.l2jmobius.gameserver.network.clientpackets.collection.RequestExCollectionOpenUI;
import org.l2jmobius.gameserver.network.clientpackets.commission.RequestCommissionBuyInfo;
import org.l2jmobius.gameserver.network.clientpackets.commission.RequestCommissionBuyItem;
import org.l2jmobius.gameserver.network.clientpackets.commission.RequestCommissionCancel;
@@ -129,6 +129,10 @@ import org.l2jmobius.gameserver.network.clientpackets.shuttle.RequestShuttleGetO
import org.l2jmobius.gameserver.network.clientpackets.shuttle.RequestShuttleGetOn;
import org.l2jmobius.gameserver.network.clientpackets.stats.ExResetStatusBonus;
import org.l2jmobius.gameserver.network.clientpackets.stats.ExSetStatusBonus;
+import org.l2jmobius.gameserver.network.clientpackets.subjugation.RequestSubjugationGacha;
+import org.l2jmobius.gameserver.network.clientpackets.subjugation.RequestSubjugationGachaUI;
+import org.l2jmobius.gameserver.network.clientpackets.subjugation.RequestSubjugationList;
+import org.l2jmobius.gameserver.network.clientpackets.subjugation.RequestSubjugationRanking;
import org.l2jmobius.gameserver.network.clientpackets.teleports.ExRequestSharedLocationTeleportUi;
import org.l2jmobius.gameserver.network.clientpackets.teleports.ExRequestSharingLocationUi;
import org.l2jmobius.gameserver.network.clientpackets.teleports.ExRequestTeleport;
@@ -643,10 +647,10 @@ public enum ExIncomingPackets implements IIncomingPackets
EX_USER_WATCHER_DELETE(0x1EB, null, ConnectionState.IN_GAME),
EX_HOMUNCULUS_ACTIVATE_SLOT(0x1EC, null, ConnectionState.IN_GAME),
EX_SUMMON_HOMUNCULUS_COUPON(0x1ED, null, ConnectionState.IN_GAME),
- EX_SUBJUGATION_LIST(0x1EE, null, ConnectionState.IN_GAME),
- EX_SUBJUGATION_RANKING(0x1EF, null, ConnectionState.IN_GAME),
- EX_SUBJUGATION_GACHA_UI(0x1F0, null, ConnectionState.IN_GAME),
- EX_SUBJUGATION_GACHA(0x1F1, null, ConnectionState.IN_GAME),
+ EX_SUBJUGATION_LIST(0x1EE, RequestSubjugationList::new, ConnectionState.IN_GAME),
+ EX_SUBJUGATION_RANKING(0x1EF, RequestSubjugationRanking::new, ConnectionState.IN_GAME),
+ EX_SUBJUGATION_GACHA_UI(0x1F0, RequestSubjugationGachaUI::new, ConnectionState.IN_GAME),
+ EX_SUBJUGATION_GACHA(0x1F1, RequestSubjugationGacha::new, ConnectionState.IN_GAME),
EX_PLEDGE_DONATION_INFO(0x1F2, null, ConnectionState.IN_GAME),
EX_PLEDGE_DONATION_REQUEST(0x1F3, null, ConnectionState.IN_GAME),
EX_PLEDGE_CONTRIBUTION_LIST(0x1F4, null, ConnectionState.IN_GAME),
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationGacha.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationGacha.java
new file mode 100644
index 0000000000..680ed9d032
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationGacha.java
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.network.clientpackets.subjugation;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.data.xml.SubjugationGacha;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationGacha;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationGachaUI;
+
+/**
+ * Written by Berezkin Nikolay, on 15.04.2021
+ */
+public class RequestSubjugationGacha implements IClientIncomingPacket
+{
+ private int _category;
+ private int _amount;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _category = packet.readD();
+ _amount = packet.readD();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final PlayerInstance player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ final PurgePlayerHolder playerKeys = player.getPurgePoints().get(_category);
+ final Map subjugationData = SubjugationGacha.getInstance().getSubjugation(_category);
+ if ((playerKeys != null) && (playerKeys.getKeys() >= _amount) && (player.getInventory().getAdena() > (20000L * _amount)))
+ {
+ player.getInventory().reduceAdena("Purge Gacha", 20000L * _amount, player, null);
+ final int curKeys = playerKeys.getKeys() - _amount;
+ player.getPurgePoints().put(_category, new PurgePlayerHolder(playerKeys.getPoints(), curKeys));
+ Map rewards = new HashMap<>();
+ for (int i = 0; i < _amount; i++)
+ {
+ double rate = 0;
+ for (int index = 0; index < subjugationData.size(); index++)
+ {
+ final double[] chances = subjugationData.values().stream().mapToDouble(it -> it).toArray();
+ final double maxBound = Arrays.stream(chances).sum();
+ final double itemChance = chances[index];
+ if (Rnd.get(maxBound - rate) < itemChance)
+ {
+ final int itemId = subjugationData.keySet().stream().mapToInt(it -> it).toArray()[index];
+ rewards.put(itemId, rewards.getOrDefault(itemId, 0) + 1);
+ player.addItem("Purge Gacha", itemId, 1, player, true);
+ break;
+ }
+ rate += itemChance;
+ }
+ }
+ player.sendPacket(new ExSubjugationGachaUI(curKeys));
+ player.sendPacket(new ExSubjugationGacha(rewards));
+ }
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationGachaUI.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationGachaUI.java
new file mode 100644
index 0000000000..ad99d24c6d
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationGachaUI.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.network.clientpackets.subjugation;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationGachaUI;
+
+/**
+ * Written by Berezkin Nikolay, on 15.04.2021
+ */
+public class RequestSubjugationGachaUI implements IClientIncomingPacket
+{
+ private int _category;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _category = packet.readC();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final PlayerInstance player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ player.sendPacket(new ExSubjugationGachaUI(player.getPurgePoints().get(_category).getKeys()));
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationList.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationList.java
new file mode 100644
index 0000000000..6e6c91926f
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationList.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.network.clientpackets.subjugation;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationList;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class RequestSubjugationList implements IClientIncomingPacket
+{
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final PlayerInstance player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ player.sendPacket(new ExSubjugationList(player.getPurgePoints()));
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationRanking.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationRanking.java
new file mode 100644
index 0000000000..ce077dd63e
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/clientpackets/subjugation/RequestSubjugationRanking.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.network.clientpackets.subjugation;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.subjugation.ExSubjugationRanking;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class RequestSubjugationRanking implements IClientIncomingPacket
+{
+ private int _rankingCategory;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _rankingCategory = packet.readD();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final PlayerInstance player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ player.sendPacket(new ExSubjugationRanking(_rankingCategory, player.getObjectId()));
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationGacha.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationGacha.java
new file mode 100644
index 0000000000..3b7e6314b7
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationGacha.java
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.network.serverpackets.subjugation;
+
+import java.util.Map;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * Written by Berezkin Nikolay, on 15.04.2021
+ */
+public class ExSubjugationGacha implements IClientOutgoingPacket
+{
+ private final Map _rewards;
+
+ public ExSubjugationGacha(Map rewards)
+ {
+ _rewards = rewards;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_SUBJUGATION_GACHA.writeId(packet);
+ packet.writeD(_rewards.size());
+ for (Map.Entry entry : _rewards.entrySet())
+ {
+ packet.writeD(entry.getKey());
+ packet.writeD(entry.getValue());
+ }
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationGachaUI.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationGachaUI.java
new file mode 100644
index 0000000000..ee9ae335f2
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationGachaUI.java
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.network.serverpackets.subjugation;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * Written by Berezkin Nikolay, on 15.04.2021
+ */
+public class ExSubjugationGachaUI implements IClientOutgoingPacket
+{
+ private final int _keys;
+
+ public ExSubjugationGachaUI(int keys)
+ {
+ _keys = keys;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_SUBJUGATION_GACHA_UI.writeId(packet);
+ packet.writeD(_keys);
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationList.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationList.java
new file mode 100644
index 0000000000..dbf3419109
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationList.java
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.network.serverpackets.subjugation;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021 01 00 00 00 //category 01 00 00 00 1901 00 00 //points 00 00 00 00 4600 00 00 //70 max keys ?
+ */
+public class ExSubjugationList implements IClientOutgoingPacket
+{
+ private final List> _playerHolder;
+
+ public ExSubjugationList(Map playerHolder)
+ {
+ _playerHolder = playerHolder.entrySet().stream().filter(it -> it.getValue() != null).collect(Collectors.toList());
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_SUBJUGATION_LIST.writeId(packet);
+ packet.writeD(_playerHolder.size());
+ for (Entry integerPurgePlayerHolderEntry : _playerHolder)
+ {
+ packet.writeD(integerPurgePlayerHolderEntry.getKey());
+ packet.writeD(integerPurgePlayerHolderEntry.getValue() != null ? integerPurgePlayerHolderEntry.getValue().getPoints() : 0);
+ packet.writeD(integerPurgePlayerHolderEntry.getValue() != null ? integerPurgePlayerHolderEntry.getValue().getKeys() : 0);
+ packet.writeD(70);
+ }
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationRanking.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationRanking.java
new file mode 100644
index 0000000000..e0254b9e24
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationRanking.java
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.network.serverpackets.subjugation;
+
+import java.util.Map;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.instancemanager.PurgeRankingManager;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021
+ */
+public class ExSubjugationRanking implements IClientOutgoingPacket
+{
+ private final Map _ranking;
+ private final int _category;
+ private final int _objectId;
+
+ public ExSubjugationRanking(int category, int objectId)
+ {
+ _ranking = PurgeRankingManager.getInstance().getTop5(category);
+ _category = category;
+ _objectId = objectId;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_SUBJUGATION_RANKING.writeId(packet);
+ packet.writeD(_ranking.entrySet().size());
+ int counter = 1;
+ for (Map.Entry data : _ranking.entrySet())
+ {
+ packet.writeString(data.getKey());
+ packet.writeD(data.getValue());
+ packet.writeD(counter++);
+ }
+ packet.writeD(_category);
+ packet.writeD(PurgeRankingManager.getInstance().getPlayerRating(_category, _objectId).getValue());
+ packet.writeD(PurgeRankingManager.getInstance().getPlayerRating(_category, _objectId).getKey());
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationSidebar.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationSidebar.java
new file mode 100644
index 0000000000..d923f79a6b
--- /dev/null
+++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/network/serverpackets/subjugation/ExSubjugationSidebar.java
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.network.serverpackets.subjugation;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.model.holders.PurgePlayerHolder;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * Written by Berezkin Nikolay, on 13.04.2021 01 00 00 00 19 01 00 00 0000 0000
+ */
+public class ExSubjugationSidebar implements IClientOutgoingPacket
+{
+ private final PurgePlayerHolder _purgeData;
+ private final int _category;
+
+ public ExSubjugationSidebar(int category, PurgePlayerHolder purgeData)
+ {
+ _category = category;
+ _purgeData = purgeData;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_SUBJUGATION_SIDEBAR.writeId(packet);
+ packet.writeD(_category); // key size
+ packet.writeD(_purgeData != null ? _purgeData.getPoints() : 0); // 1000000 = 100 percent
+ packet.writeD(_purgeData != null ? _purgeData.getKeys() : 0);
+ packet.writeD(0);
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.0_Sylph/readme.txt b/L2J_Mobius_Essence_5.0_Sylph/readme.txt
index d819070897..59cd167aaa 100644
--- a/L2J_Mobius_Essence_5.0_Sylph/readme.txt
+++ b/L2J_Mobius_Essence_5.0_Sylph/readme.txt
@@ -125,6 +125,7 @@ Dwelling of Spirits: https://eu.4game.com/patchnotes/lineage2essence/261/
Sylph: https://eu.4game.com/patchnotes/lineage2essence/281/
-Sylph creation support
-Collection system
+-Purge system
Customs:
-Newbie Helper NPC location info