1. Input item name or partial name to search for items.
+
2. Choose item icon to search for drops.
+
3. Select an NPC, you can see it's location on the world map.
+
+
+
+
+
+
+
ItemName:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %searchResult%
+
+
+ %pages%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LINEAGE II - COMMUNITY BOARD
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/gatekeeper/main.html b/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/gatekeeper/main.html
index 8192f527cc..e9fdf17659 100644
--- a/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/gatekeeper/main.html
+++ b/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/gatekeeper/main.html
@@ -8,24 +8,7 @@
diff --git a/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/navigation.html b/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/navigation.html
new file mode 100644
index 0000000000..b9a7522c57
--- /dev/null
+++ b/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/navigation.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/premium/main.html b/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/premium/main.html
new file mode 100644
index 0000000000..a1ac36655e
--- /dev/null
+++ b/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/premium/main.html
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+ %navigation%
+
+
+
+
+
+
+
+
+
Premium Manager
+
+
+
+
+
+
+
+
+
+
1. Premium benefits CAN NOT BE TRANSFERED.
+
2. Premium does not effect party members.
+
3. Premium benefits effect ALL characters in same account.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Your premium status can be checked
+
+ by typing following command in chat
+
+ .premium
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LINEAGE II - COMMUNITY BOARD
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/premium/thankyou.html b/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/premium/thankyou.html
new file mode 100644
index 0000000000..4064c0c599
--- /dev/null
+++ b/L2J_Mobius_HighFive/dist/game/data/html/CommunityBoard/Custom/premium/thankyou.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+ %navigation%
+
+
+
+
+
+
+
+
+
Premium Manager
+
+
+
+
+
+
+
+
+
+
1. Premium benefits CAN NOT BE TRANSFERED.
+
2. Premium does not effect party members.
+
3. Premium benefits effect ALL characters in same account.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Thank you!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Your premium status can be checked
+
+ by typing following command in chat
+
+ .premium
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LINEAGE II - COMMUNITY BOARD
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/MasterHandler.java b/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/MasterHandler.java
index 31760320fa..3588860da5 100644
--- a/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/MasterHandler.java
+++ b/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/MasterHandler.java
@@ -174,6 +174,7 @@ import handlers.chathandlers.ChatShout;
import handlers.chathandlers.ChatTrade;
import handlers.chathandlers.ChatWhisper;
import handlers.communityboard.ClanBoard;
+import handlers.communityboard.DropSearchBoard;
import handlers.communityboard.FavoriteBoard;
import handlers.communityboard.FriendsBoard;
import handlers.communityboard.HomeBoard;
@@ -459,6 +460,7 @@ public class MasterHandler
{
// Community Board
ClanBoard.class,
+ DropSearchBoard.class,
FavoriteBoard.class,
FriendsBoard.class,
HomeBoard.class,
diff --git a/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java b/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java
index a6761be85c..d871e74ac7 100644
--- a/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java
+++ b/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java
@@ -17,6 +17,7 @@
package handlers.admincommandhandlers;
import java.text.SimpleDateFormat;
+import java.util.concurrent.TimeUnit;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.cache.HtmCache;
@@ -118,15 +119,21 @@ public class AdminPremium implements IAdminCommandHandler
}
// TODO: Add check if account exists XD
- PremiumManager.getInstance().updatePremiumData(months, accountName);
- admin.sendMessage("Account " + accountName + " will now have premium status until " + String.valueOf(new SimpleDateFormat("dd.MM.yyyy HH:mm").format(PremiumManager.getInstance().getPremiumEndDate(accountName))) + ".");
+ PremiumManager.getInstance().addPremiumTime(accountName, months * 30, TimeUnit.DAYS);
+ admin.sendMessage("Account " + accountName + " will now have premium status until " + new SimpleDateFormat("dd.MM.yyyy HH:mm").format(PremiumManager.getInstance().getPremiumExpiration(accountName)) + ".");
}
private void viewPremiumInfo(L2PcInstance admin, String accountName)
{
- if (PremiumManager.getInstance().getPremiumEndDate(accountName) > 0)
+ if (!Config.PREMIUM_SYSTEM_ENABLED)
{
- admin.sendMessage("Account " + accountName + " has premium status until " + String.valueOf(new SimpleDateFormat("dd.MM.yyyy HH:mm").format(PremiumManager.getInstance().getPremiumEndDate(accountName))) + ".");
+ admin.sendMessage("Premium system is disabled.");
+ return;
+ }
+
+ if (PremiumManager.getInstance().getPremiumExpiration(accountName) > 0)
+ {
+ admin.sendMessage("Account " + accountName + " has premium status until " + new SimpleDateFormat("dd.MM.yyyy HH:mm").format(PremiumManager.getInstance().getPremiumExpiration(accountName)) + ".");
}
else
{
@@ -136,7 +143,13 @@ public class AdminPremium implements IAdminCommandHandler
private void removePremium(L2PcInstance admin, String accountName)
{
- if (PremiumManager.getInstance().getPremiumEndDate(accountName) > 0)
+ if (!Config.PREMIUM_SYSTEM_ENABLED)
+ {
+ admin.sendMessage("Premium system is disabled.");
+ return;
+ }
+
+ if (PremiumManager.getInstance().getPremiumExpiration(accountName) > 0)
{
PremiumManager.getInstance().removePremiumStatus(accountName);
admin.sendMessage("Account " + accountName + " has no longer premium status.");
diff --git a/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/communityboard/DropSearchBoard.java b/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/communityboard/DropSearchBoard.java
new file mode 100644
index 0000000000..bb9d598e87
--- /dev/null
+++ b/L2J_Mobius_HighFive/dist/game/data/scripts/handlers/communityboard/DropSearchBoard.java
@@ -0,0 +1,331 @@
+/*
+ * 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 handlers.communityboard;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringJoiner;
+
+import com.l2jmobius.gameserver.cache.HtmCache;
+import com.l2jmobius.gameserver.data.xml.impl.NpcData;
+import com.l2jmobius.gameserver.datatables.ItemTable;
+import com.l2jmobius.gameserver.datatables.SpawnTable;
+import com.l2jmobius.gameserver.handler.CommunityBoardHandler;
+import com.l2jmobius.gameserver.handler.IParseBoardHandler;
+import com.l2jmobius.gameserver.model.L2Spawn;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jmobius.gameserver.model.drops.DropListScope;
+import com.l2jmobius.gameserver.model.drops.GeneralDropItem;
+import com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem;
+import com.l2jmobius.gameserver.model.drops.IDropItem;
+import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
+import com.l2jmobius.gameserver.model.items.L2Item;
+
+/**
+ * @author yksdtc
+ */
+public class DropSearchBoard implements IParseBoardHandler
+{
+ private static final String NAVIGATION_PATH = "data/html/CommunityBoard/Custom/navigation.html";
+ private static final String[] COMMAND =
+ {
+ "_bbs_search_item",
+ "_bbs_search_drop",
+ "_bbs_npc_trace"
+ };
+
+ class DropHolder
+ {
+ int itemId;
+ int npcId;
+ byte npcLevel;
+ long basemin;
+ long basemax;
+ double baseGroupChance;
+ double basechance;
+ boolean isSweep;
+
+ public DropHolder(L2NpcTemplate npc, GeneralDropItem item, double groupChance, boolean isSweep)
+ {
+ itemId = item.getItemId();
+ npcId = npc.getId();
+ npcLevel = npc.getLevel();
+ basemin = item.getMin();
+ basemax = item.getMax();
+ baseGroupChance = groupChance;
+ basechance = item.getChance();
+ this.isSweep = isSweep;
+ }
+
+ /**
+ * only for debug'/;
+ */
+ @Override
+ public String toString()
+ {
+ return "DropHolder [itemId=" + itemId + ", npcId=" + npcId + ", npcLevel=" + npcLevel + ", basemin=" + basemin + ", basemax=" + basemax + ", baseGroupChance=" + baseGroupChance + ", basechance=" + basechance + ", isSweep=" + isSweep + "]";
+ }
+ }
+
+ private final Map> DROP_INDEX_CACHE = new HashMap<>();
+
+ // nonsupport items
+ private final Set BLOCK_ID = new HashSet<>();
+ {
+ BLOCK_ID.add(Inventory.ADENA_ID);
+ }
+
+ public DropSearchBoard()
+ {
+ buildDropIndex();
+ }
+
+ private void buildDropIndex()
+ {
+ NpcData.getInstance().getTemplates(npc -> npc.getDropLists() != null).forEach(npcTemplate ->
+ {
+ for (Entry> entry : npcTemplate.getDropLists().entrySet())
+ {
+ entry.getValue().forEach(idrop ->
+ {
+ if (idrop instanceof GroupedGeneralDropItem)
+ {
+ GroupedGeneralDropItem ggd = (GroupedGeneralDropItem) idrop;
+ ggd.getItems().stream().forEach(gd -> addToDropList(npcTemplate, gd, ggd.getChance(), entry.getKey() == DropListScope.CORPSE));
+ }
+ else
+ {
+ GeneralDropItem gd = (GeneralDropItem) idrop;
+ addToDropList(npcTemplate, gd, 100.0, entry.getKey() == DropListScope.CORPSE);
+ }
+ });
+ }
+ });
+
+ DROP_INDEX_CACHE.values().stream().forEach(l -> l.sort((d1, d2) -> Byte.valueOf(d1.npcLevel).compareTo(Byte.valueOf(d2.npcLevel))));
+ }
+
+ private void addToDropList(L2NpcTemplate npcTemplate, GeneralDropItem gd, double groupChance, boolean isSweep)
+ {
+ if (BLOCK_ID.contains(gd.getItemId()))
+ {
+ return;
+ }
+
+ List dropList = DROP_INDEX_CACHE.get(gd.getItemId());
+ if (dropList == null)
+ {
+ dropList = new ArrayList<>();
+ DROP_INDEX_CACHE.put(gd.getItemId(), dropList);
+ }
+
+ dropList.add(new DropHolder(npcTemplate, gd, groupChance, isSweep));
+ }
+
+ @Override
+ public boolean parseCommunityBoardCommand(String command, L2PcInstance player)
+ {
+ final String navigation = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), NAVIGATION_PATH);
+ String[] params = command.split(" ");
+ String html = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "data/html/CommunityBoard/Custom/dropsearch/main.html");
+ switch (params[0])
+ {
+ case "_bbs_search_item":
+ {
+ String itemName = buildItemName(params);
+ String result = buildItemSearchResult(itemName);
+ html = html.replace("%searchResult%", result);
+ break;
+ }
+ case "_bbs_search_drop":
+ {
+ final DecimalFormat chanceFormat = new DecimalFormat("0.00##");
+ int itemId = Integer.parseInt(params[1]);
+ int page = Integer.parseInt(params[2]);
+ List list = DROP_INDEX_CACHE.get(itemId);
+ int pages = list.size() / 14;
+ if (pages == 0)
+ {
+ pages++;
+ }
+
+ int start = (page - 1) * 14;
+ int end = Math.min(list.size() - 1, start + 14);
+ StringBuilder builder = new StringBuilder();
+ for (int index = start; index <= end; index++)
+ {
+ DropHolder dropHolder = list.get(index);
+ builder.append("