Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/game/data/xml/Custom/VipManager.xml b/game/data/xml/Custom/VipManager.xml
- new file mode 100644
- index 0000000..7d7e373
- --- /dev/null
- +++ b/game/data/xml/Custom/VipManager.xml
- @@ -0,0 +1,88 @@
- +<?xml version="1.0" encoding="UTF-8"?>
- +<VipData enabled="true">
- +
- + <!-- BRONZE -->
- + <Tier name="bronze" titleColor="#a97142" useTitleColor="true" xpRate="1.15" spRate="1.10" useXpSp="true">
- + <!-- Drops -->
- + <DropBonus itemId="57" addPercent="0.2"/>
- + <DropBonus itemId="9300" countMul="2.0"/>
- +
- + <!-- Enchant (global do tier) -->
- + <EnchantBonus addPercent="3.0"/>
- + <!-- Exemplo por scroll: +2 pp no 947 -->
- + <EnchantBonus scrollId="947" addPercent="2.0"/>
- + </Tier>
- +
- + <!-- PRATA -->
- + <Tier name="prata" titleColor="#c0c0c0" useTitleColor="true" xpRate="1.25" spRate="1.15" useXpSp="true">
- + <!-- Drops -->
- + <DropBonus itemId="57" addPercent="0.6"/>
- +
- + <!-- Enchant: +5 pp no 947 e +10% multiplicativo no 948 -->
- + <EnchantBonus scrollId="947" addPercent="5.0"/>
- + <EnchantBonus scrollId="948" mulRate="1.10"/>
- + </Tier>
- +
- + <!-- OURO -->
- + <Tier name="ouro" titleColor="#ffd700" useTitleColor="true" xpRate="1.35" spRate="1.20" useXpSp="true">
- + <!-- Drops -->
- + <DropBonus itemId="57" addPercent="1.0"/>
- +
- + <!-- Enchant (global): +2 pp e +10% -->
- + <EnchantBonus addPercent="2.0" mulRate="1.10"/>
- + </Tier>
- +
- + <!-- MASTER -->
- + <Tier name="master" titleColor="#9b59b6" useTitleColor="true" xpRate="1.50" spRate="1.30" useXpSp="true">
- + <!-- Drops -->
- + <DropBonus itemId="57" addPercent="1.8"/>
- + <DropBonus itemId="9300" countMul="2.0"/>
- +
- + <!-- Enchant (global mais forte) -->
- + <EnchantBonus addPercent="5.0" mulRate="1.15"/>
- + <!-- Exemplo ainda mais forte para um scroll específico -->
- + <EnchantBonus scrollId="949" addPercent="7.0" mulRate="1.20"/>
- + </Tier>
- +
- + <!-- ===== Tokens ===== -->
- + <Token itemId="9301" tier="bronze" days="3"/>
- + <Token itemId="99001" tier="prata" days="7"/>
- + <Token itemId="99002" tier="ouro" days="15"/>
- + <Token itemId="99003" tier="master" days="30"/>
- +
- +</VipData>
- diff --git a/game/data/xml/items/custom/VipItens.xml b/game/data/xml/items/custom/VipItens.xml
- new file mode 100644
- index 0000000..071021b
- --- /dev/null
- +++ b/game/data/xml/items/custom/VipItens.xml
- @@ -0,0 +1,24 @@
- +<?xml version="1.0" encoding="UTF-8"?>
- +<list>
- + <item id="99000" type="EtcItem" name="VIP Bronze (3 dias)">
- + <set name="material" val="STEEL" />
- + <set name="is_stackable" val="true" />
- + <set name="handler" val="VipToken" />
- + </item>
- + <item id="99001" type="EtcItem" name="VIP Prata (7 dias)">
- + <set name="material" val="STEEL" />
- + <set name="is_stackable" val="true" />
- + <set name="handler" val="VipToken" />
- + </item>
- + <item id="99002" type="EtcItem" name="VIP Ouro (15 dias)">
- + <set name="material" val="STEEL" />
- + <set name="is_stackable" val="true" />
- + <set name="handler" val="VipToken" />
- + </item>
- + <item id="99003" type="EtcItem" name="VIP Master (30 dias)">
- + <set name="material" val="STEEL" />
- + <set name="is_stackable" val="true" />
- + <set name="handler" val="VipToken" />
- + </item>
- +
- +</list>
- diff --git a/java/TioPatinhas/Vip/VipDAO.java b/java/TioPatinhas/Vip/VipDAO.java
- new file mode 100644
- index 0000000..a7e99e4
- --- /dev/null
- +++ b/java/TioPatinhas/Vip/VipDAO.java
- @@ -0,0 +1,72 @@
- +package TioPatinhas.Vip;
- +
- +import java.sql.Connection;
- +import java.sql.PreparedStatement;
- +import java.sql.ResultSet;
- +import java.sql.Timestamp;
- +import java.time.LocalDateTime;
- +
- +import net.sf.l2j.L2DatabaseFactory;
- +
- +/*
- + * @author -= TioPatinhas =-
- + */
- +public final class VipDAO
- +{
- + private static final String SELECT = "SELECT tier, expire_at FROM character_vip_player WHERE charId=?";
- + private static final String UPSERT = "REPLACE INTO character_vip_player (charId, tier, expire_at) VALUES (?,?,?)";
- + private static final String DELETE = "DELETE FROM character_vip_player WHERE charId=?";
- +
- + public static VipStatus load(int charId)
- + {
- + try (Connection con = L2DatabaseFactory.getInstance().getConnection();
- + PreparedStatement ps = con.prepareStatement(SELECT))
- + {
- + ps.setInt(1, charId);
- + try (ResultSet rs = ps.executeQuery())
- + {
- + if (rs.next())
- + {
- + final String tier = rs.getString("tier");
- + final LocalDateTime exp = rs.getTimestamp("expire_at").toLocalDateTime();
- + return new VipStatus(tier, exp);
- + }
- + }
- + }
- + catch (Exception e)
- + {
- + e.printStackTrace();
- + }
- + return null;
- + }
- +
- + public static void save(int charId, String tier, LocalDateTime expireAt)
- + {
- + try (Connection con = L2DatabaseFactory.getInstance().getConnection();
- + PreparedStatement ps = con.prepareStatement(UPSERT))
- + {
- + ps.setInt(1, charId);
- + ps.setString(2, tier);
- + ps.setTimestamp(3, Timestamp.valueOf(expireAt));
- + ps.executeUpdate();
- + }
- + catch (Exception e)
- + {
- + e.printStackTrace();
- + }
- + }
- +
- + public static void delete(int charId)
- + {
- + try (Connection con = L2DatabaseFactory.getInstance().getConnection();
- + PreparedStatement ps = con.prepareStatement(DELETE))
- + {
- + ps.setInt(1, charId);
- + ps.executeUpdate();
- + }
- + catch (Exception e)
- + {
- + e.printStackTrace();
- + }
- + }
- +}
- diff --git a/java/TioPatinhas/Vip/VipData.java b/java/TioPatinhas/Vip/VipData.java
- new file mode 100644
- index 0000000..cf6937c
- --- /dev/null
- +++ b/java/TioPatinhas/Vip/VipData.java
- @@ -0,0 +1,326 @@
- +package TioPatinhas.Vip;
- +
- +import java.io.File;
- +import java.util.Collections;
- +import java.util.HashMap;
- +import java.util.Map;
- +import java.util.logging.Logger;
- +
- +import javax.xml.parsers.DocumentBuilderFactory;
- +
- +import org.w3c.dom.Document;
- +import org.w3c.dom.NamedNodeMap;
- +import org.w3c.dom.Node;
- +
- +/*
- + * @author -= TioPatinhas =-
- + */
- +public final class VipData
- +{
- + private static final Logger _log = Logger.getLogger(VipData.class.getName());
- + private static final VipData INSTANCE = new VipData();
- +
- + public static VipData getInstance()
- + {
- + return INSTANCE;
- + }
- +
- + private boolean _enabled = false;
- +
- + private final Map<String, Map<Integer, Double>> _tierChanceAdd = new HashMap<>();
- + private final Map<String, Map<Integer, Double>> _tierCountMul = new HashMap<>();
- + private final Map<String, String> _tierTitleColors = new HashMap<>();
- + private final Map<String, Boolean> _tierUseTitleColor = new HashMap<>();
- + private final Map<String, Double> _tierXpRate = new HashMap<>();
- + private final Map<String, Double> _tierSpRate = new HashMap<>();
- + private final Map<String, Boolean> _tierUseXpSp = new HashMap<>();
- +
- + private final Map<String, Double> _tierEnchantAddGlobal = new HashMap<>();
- + private final Map<String, Double> _tierEnchantMulGlobal = new HashMap<>();
- +
- + private final Map<String, Map<Integer, Double>> _tierEnchantAddByScroll = new HashMap<>();
- + private final Map<String, Map<Integer, Double>> _tierEnchantMulByScroll = new HashMap<>();
- +
- + public static final class TokenEntry
- + {
- + public final String tier;
- + public final int days;
- +
- + public TokenEntry(String t, int d)
- + {
- + tier = t;
- + days = d;
- + }
- + }
- +
- + private final Map<Integer, TokenEntry> _tokenByItem = new HashMap<>();
- +
- + private VipData()
- + {
- + reload();
- + }
- +
- + public void reload()
- + {
- + _enabled = false;
- + _tierChanceAdd.clear();
- + _tierCountMul.clear();
- + _tierTitleColors.clear();
- + _tierUseTitleColor.clear();
- + _tierXpRate.clear();
- + _tierSpRate.clear();
- + _tierUseXpSp.clear();
- +
- + _tierEnchantAddGlobal.clear();
- + _tierEnchantMulGlobal.clear();
- + _tierEnchantAddByScroll.clear();
- + _tierEnchantMulByScroll.clear();
- +
- + _tokenByItem.clear();
- +
- + try
- + {
- + final File f = new File("./data/xml/Custom/VipManager.xml");
- + final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- + dbf.setIgnoringComments(true);
- + dbf.setExpandEntityReferences(false);
- + final Document doc = dbf.newDocumentBuilder().parse(f);
- + doc.getDocumentElement().normalize();
- +
- + final NamedNodeMap rootAttrs = doc.getDocumentElement().getAttributes();
- + final Node enabledAttr = rootAttrs.getNamedItem("enabled");
- + _enabled = (enabledAttr != null && Boolean.parseBoolean(enabledAttr.getNodeValue()));
- +
- + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling())
- + {
- + if (n.getNodeType() != Node.ELEMENT_NODE)
- + continue;
- +
- + if ("Tier".equalsIgnoreCase(n.getNodeName()))
- + {
- + final NamedNodeMap a = n.getAttributes();
- + final String name = a.getNamedItem("name").getNodeValue().toLowerCase();
- +
- + // titleColor / useTitleColor
- + Node tc = a.getNamedItem("titleColor");
- + if (tc != null)
- + _tierTitleColors.put(name, tc.getNodeValue());
- +
- + Node utc = a.getNamedItem("useTitleColor");
- + final boolean useTitle = (utc != null && Boolean.parseBoolean(utc.getNodeValue()));
- + _tierUseTitleColor.put(name, useTitle);
- +
- + // xpRate / spRate / useXpSp
- + double xpRate = 1.0, spRate = 1.0;
- + Node xr = a.getNamedItem("xpRate");
- + Node sr = a.getNamedItem("spRate");
- + if (xr != null)
- + xpRate = Double.parseDouble(xr.getNodeValue());
- + if (sr != null)
- + spRate = Double.parseDouble(sr.getNodeValue());
- + _tierXpRate.put(name, xpRate);
- + _tierSpRate.put(name, spRate);
- +
- + Node ux = a.getNamedItem("useXpSp");
- + boolean useXpSp = (ux != null && Boolean.parseBoolean(ux.getNodeValue()));
- + _tierUseXpSp.put(name, useXpSp);
- +
- + final Map<Integer, Double> chanceAdd = new HashMap<>();
- + final Map<Integer, Double> countMul = new HashMap<>();
- +
- + // ENCHANT maps locais do tier
- + final Map<Integer, Double> enchAddByScroll = new HashMap<>();
- + final Map<Integer, Double> enchMulByScroll = new HashMap<>();
- + Double enchAddGlobal = null;
- + Double enchMulGlobal = null;
- +
- + for (Node c = n.getFirstChild(); c != null; c = c.getNextSibling())
- + {
- + if (c.getNodeType() != Node.ELEMENT_NODE)
- + continue;
- +
- + final String nodeName = c.getNodeName();
- +
- + // Drops
- + if ("DropBonus".equalsIgnoreCase(nodeName))
- + {
- + final NamedNodeMap ca = c.getAttributes();
- + final int itemId = Integer.parseInt(ca.getNamedItem("itemId").getNodeValue());
- +
- + double addPercent = 0.0;
- + Node ap = ca.getNamedItem("addPercent");
- + if (ap != null)
- + addPercent = Double.parseDouble(ap.getNodeValue());
- + if (addPercent != 0.0)
- + chanceAdd.put(itemId, addPercent);
- +
- + double mul = 1.0;
- + Node cm = ca.getNamedItem("countMul");
- + if (cm != null)
- + mul = Double.parseDouble(cm.getNodeValue());
- + if (mul != 1.0)
- + countMul.put(itemId, mul);
- +
- + continue;
- + }
- +
- + // Enchant
- + if ("EnchantBonus".equalsIgnoreCase(nodeName))
- + {
- + final NamedNodeMap ca = c.getAttributes();
- + Node addN = ca.getNamedItem("addPercent");
- + Node mulN = ca.getNamedItem("mulRate");
- + Node sidN = ca.getNamedItem("scrollId");
- +
- + final Double add = (addN != null) ? Double.parseDouble(addN.getNodeValue()) : null;
- + final Double mul = (mulN != null) ? Double.parseDouble(mulN.getNodeValue()) : null;
- +
- + if (sidN != null)
- + {
- + final int scrollId = Integer.parseInt(sidN.getNodeValue());
- + if (add != null)
- + enchAddByScroll.put(scrollId, add);
- + if (mul != null)
- + enchMulByScroll.put(scrollId, mul);
- + }
- + else
- + {
- + if (add != null)
- + enchAddGlobal = add;
- + if (mul != null)
- + enchMulGlobal = mul;
- + }
- + }
- + }
- +
- + _tierChanceAdd.put(name, Collections.unmodifiableMap(chanceAdd));
- + _tierCountMul.put(name, Collections.unmodifiableMap(countMul));
- +
- + // salva enchant por-tier
- + _tierEnchantAddByScroll.put(name, Collections.unmodifiableMap(enchAddByScroll));
- + _tierEnchantMulByScroll.put(name, Collections.unmodifiableMap(enchMulByScroll));
- + if (enchAddGlobal != null)
- + _tierEnchantAddGlobal.put(name, enchAddGlobal);
- + if (enchMulGlobal != null)
- + _tierEnchantMulGlobal.put(name, enchMulGlobal);
- +
- + continue;
- + }
- +
- + if ("Token".equalsIgnoreCase(n.getNodeName()))
- + {
- + final NamedNodeMap a = n.getAttributes();
- + final int itemId = Integer.parseInt(a.getNamedItem("itemId").getNodeValue());
- + final String tier = a.getNamedItem("tier").getNodeValue().toLowerCase();
- + final int days = Integer.parseInt(a.getNamedItem("days").getNodeValue());
- + _tokenByItem.put(itemId, new TokenEntry(tier, days));
- + }
- + }
- + }
- + catch (Exception e)
- + {
- + e.printStackTrace();
- + }
- +
- + _log.info("VipData: carregado " + _tierChanceAdd.size() + " tiers, " + _tokenByItem.size() + " tokens.");
- + }
- +
- + public boolean isEnabled()
- + {
- + return _enabled;
- + }
- +
- + public double getAddPercent(String tierName, int itemId)
- + {
- + if (!_enabled || tierName == null)
- + return 0.0;
- + final Map<Integer, Double> m = _tierChanceAdd.get(tierName.toLowerCase());
- + return (m == null) ? 0.0 : m.getOrDefault(itemId, 0.0);
- + }
- +
- + public double getCountMul(String tierName, int itemId)
- + {
- + if (!_enabled || tierName == null)
- + return 1.0;
- + final Map<Integer, Double> m = _tierCountMul.get(tierName.toLowerCase());
- + return (m == null) ? 1.0 : m.getOrDefault(itemId, 1.0);
- + }
- +
- + public String getTitleColor(String tierName)
- + {
- + if (!_enabled || tierName == null)
- + return null;
- + return _tierTitleColors.get(tierName.toLowerCase());
- + }
- +
- + public boolean isUseTitleColor(String tierName)
- + {
- + if (!_enabled || tierName == null)
- + return false;
- + return _tierUseTitleColor.getOrDefault(tierName.toLowerCase(), false);
- + }
- +
- + public boolean isUseXpSp(String tierName)
- + {
- + if (!_enabled || tierName == null)
- + return false;
- + return _tierUseXpSp.getOrDefault(tierName.toLowerCase(), false);
- + }
- +
- + public double getXpRate(String tierName)
- + {
- + if (!_enabled || tierName == null)
- + return 1.0;
- + return _tierXpRate.getOrDefault(tierName.toLowerCase(), 1.0);
- + }
- +
- + public double getSpRate(String tierName)
- + {
- + if (!_enabled || tierName == null)
- + return 1.0;
- + return _tierSpRate.getOrDefault(tierName.toLowerCase(), 1.0);
- + }
- +
- + public double getEnchantAddPercent(String tierName, int scrollId)
- + {
- + if (!_enabled || tierName == null)
- + return 0.0;
- + final String t = tierName.toLowerCase();
- + final Map<Integer, Double> byScroll = _tierEnchantAddByScroll.get(t);
- + if (byScroll != null)
- + {
- + final Double v = byScroll.get(scrollId);
- + if (v != null)
- + return v;
- + }
- + return _tierEnchantAddGlobal.getOrDefault(t, 0.0);
- + }
- +
- + public double getEnchantMulRate(String tierName, int scrollId)
- + {
- + if (!_enabled || tierName == null)
- + return 1.0;
- + final String t = tierName.toLowerCase();
- + final Map<Integer, Double> byScroll = _tierEnchantMulByScroll.get(t);
- + if (byScroll != null)
- + {
- + final Double v = byScroll.get(scrollId);
- + if (v != null)
- + return v;
- + }
- + return _tierEnchantMulGlobal.getOrDefault(t, 1.0);
- + }
- +
- + public static int parseColor(String hex)
- + {
- + if (hex == null)
- + return 0xFFFFFF;
- + String clean = hex.replace("#", "");
- + return (int) Long.parseLong(clean, 16);
- + }
- +
- + public TokenEntry getToken(int itemId)
- + {
- + return _tokenByItem.get(itemId);
- + }
- +}
- diff --git a/java/TioPatinhas/Vip/VipManager.java b/java/TioPatinhas/Vip/VipManager.java
- new file mode 100644
- index 0000000..19ac606
- --- /dev/null
- +++ b/java/TioPatinhas/Vip/VipManager.java
- @@ -0,0 +1,205 @@
- +package TioPatinhas.Vip;
- +
- +import java.time.Duration;
- +import java.time.LocalDateTime;
- +
- +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
- +import net.sf.l2j.gameserver.network.clientpackets.Say2;
- +import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
- +
- +/*
- + * @author -= TioPatinhas =-
- + */
- +public final class VipManager
- +{
- + private static final VipManager INSTANCE = new VipManager();
- +
- + public static VipManager getInstance()
- + {
- + return INSTANCE;
- + }
- +
- + private VipManager()
- + {
- + }
- +
- + public void onLogin(L2PcInstance player)
- + {
- + final VipStatus stage = VipDAO.load(player.getObjectId());
- + if (stage != null && stage.isActive())
- + {
- + player.setNewVipTier(stage.tier);
- + player.setNewVipExpire(stage.expire);
- + applyTitleColorFromTier(player, stage.tier);
- +
- + final String left = formatRemaining(LocalDateTime.now(), stage.expire);
- + player.sendPacket(new CreatureSay(0, Say2.CRITICAL_ANNOUNCE, "", "Seu VIP " + stage.tier + " expira em " + left + "."));
- + warnIfLessThanOneDay(player, stage.expire);
- + }
- + else
- + {
- + player.setNewVipTier(null);
- + player.setNewVipExpire(null);
- + if (stage != null)
- + VipDAO.delete(player.getObjectId());
- + resetTitleColorToDefault(player);
- + }
- + }
- +
- + public void setVip(L2PcInstance player, String tier, int days)
- + {
- + LocalDateTime base = LocalDateTime.now();
- + if (player.getNewVipExpire() != null && base.isBefore(player.getNewVipExpire()))
- + base = player.getNewVipExpire();
- +
- + final LocalDateTime exp = base.plusDays(Math.max(1, days));
- + final String normTier = tier.toLowerCase();
- +
- + VipDAO.save(player.getObjectId(), normTier, exp);
- + player.setNewVipTier(normTier);
- + player.setNewVipExpire(exp);
- +
- + applyTitleColorFromTier(player, normTier);
- +
- + final String left = formatRemaining(LocalDateTime.now(), exp);
- + player.sendMessage("VIP " + normTier + " renovado. Expira em " + left + ".");
- + player.sendPacket(new CreatureSay(0, Say2.CRITICAL_ANNOUNCE, "", "VIP " + normTier + " renovado. Expira em " + left + "."));
- + warnIfLessThanOneDay(player, exp);
- + }
- +
- + public void clearVip(L2PcInstance player)
- + {
- + VipDAO.delete(player.getObjectId());
- + player.setNewVipTier(null);
- + player.setNewVipExpire(null);
- + resetTitleColorToDefault(player);
- + player.sendMessage("Seu VIP foi removido.");
- + player.sendPacket(new CreatureSay(0, Say2.CRITICAL_ANNOUNCE, "", "Seu VIP foi removido."));
- + }
- +
- + public double getDropAddPercent(L2PcInstance player, int itemId)
- + {
- + if (player == null || player.getNewVipTier() == null)
- + return 0.0;
- + return VipData.getInstance().getAddPercent(player.getNewVipTier(), itemId);
- + }
- +
- + public double getCountMultiplier(L2PcInstance player, int itemId)
- + {
- + if (player == null || player.getNewVipTier() == null)
- + return 1.0;
- + return VipData.getInstance().getCountMul(player.getNewVipTier(), itemId);
- + }
- +
- + // XP / SP
- + public double getXpRateMultiplier(L2PcInstance player)
- + {
- + if (player == null)
- + return 1.0;
- + final String tier = player.getNewVipTier();
- + if (tier == null)
- + return 1.0;
- + if (!VipData.getInstance().isUseXpSp(tier))
- + return 1.0;
- + return VipData.getInstance().getXpRate(tier);
- + }
- +
- + public double getSpRateMultiplier(L2PcInstance player)
- + {
- + if (player == null)
- + return 1.0;
- + final String tier = player.getNewVipTier();
- + if (tier == null)
- + return 1.0;
- + if (!VipData.getInstance().isUseXpSp(tier))
- + return 1.0;
- + return VipData.getInstance().getSpRate(tier);
- + }
- +
- + public double getEnchantAddPercent(L2PcInstance player, int scrollId)
- + {
- + if (player == null)
- + return 0.0;
- + final String tier = player.getNewVipTier();
- + if (tier == null)
- + return 0.0;
- + return VipData.getInstance().getEnchantAddPercent(tier, scrollId);
- + }
- +
- + public double getEnchantMulRate(L2PcInstance player, int scrollId)
- + {
- + if (player == null)
- + return 1.0;
- + final String tier = player.getNewVipTier();
- + if (tier == null)
- + return 1.0;
- + return VipData.getInstance().getEnchantMulRate(tier, scrollId);
- + }
- +
- + private void applyTitleColorFromTier(L2PcInstance player, String tier)
- + {
- + if (player == null || tier == null)
- + return;
- + if (!VipData.getInstance().isUseTitleColor(tier))
- + return;
- +
- + final String hex = VipData.getInstance().getTitleColor(tier);
- + if (hex == null)
- + return;
- +
- + try
- + {
- + final int rgb = VipData.parseColor(hex); // "#rrggbb" -> 0xRRGGBB
- + player.getAppearance().setTitleColor(rgb);
- + player.broadcastUserInfo();
- + }
- + catch (Exception e)
- + {
- + e.printStackTrace();
- + }
- + }
- +
- + private void resetTitleColorToDefault(L2PcInstance player)
- + {
- + if (player == null)
- + return;
- +
- + final int DEFAULT_TITLE_COLOR = 0xFFFF77;
- + try
- + {
- + player.getAppearance().setTitleColor(DEFAULT_TITLE_COLOR);
- + player.broadcastUserInfo();
- + }
- + catch (Exception e)
- + {
- + e.printStackTrace();
- + }
- + }
- +
- + private static String formatRemaining(LocalDateTime now, LocalDateTime expire)
- + {
- + if (expire == null || !expire.isAfter(now))
- + return "0d 00h 00m";
- +
- + Duration day = Duration.between(now, expire);
- + long totalMin = day.toMinutes();
- + long days = totalMin / (24 * 60);
- + long hours = (totalMin % (24 * 60)) / 60;
- + long mins = totalMin % 60;
- + return String.format("%ddias %02dhoras %02dminutos", days, hours, mins);
- + }
- +
- + private static void warnIfLessThanOneDay(L2PcInstance player, LocalDateTime expire)
- + {
- + if (expire == null)
- + return;
- +
- + Duration days = Duration.between(LocalDateTime.now(), expire);
- + if (!days.isNegative() && days.compareTo(Duration.ofHours(24)) <= 0)
- + {
- + long hours = Math.max(0, days.toHours());
- + player.sendMessage("Aviso: seu VIP expira em menos de 24h (" + hours + "h).");
- + player.sendPacket(new CreatureSay(0, Say2.CRITICAL_ANNOUNCE, "Aviso: ", "seu VIP expira em menos de 24h (" + hours + "h)."));
- + }
- + }
- +}
- diff --git a/java/TioPatinhas/Vip/VipStatus.java b/java/TioPatinhas/Vip/VipStatus.java
- new file mode 100644
- index 0000000..53dfd7a
- --- /dev/null
- +++ b/java/TioPatinhas/Vip/VipStatus.java
- @@ -0,0 +1,23 @@
- +package TioPatinhas.Vip;
- +
- +import java.time.LocalDateTime;
- +
- +/*
- + * @author -= TioPatinhas =-
- + */
- +public final class VipStatus
- +{
- + public final String tier;
- + public final LocalDateTime expire;
- +
- + public VipStatus(String tier, LocalDateTime expire)
- + {
- + this.tier = tier;
- + this.expire = expire;
- + }
- +
- + public boolean isActive()
- + {
- + return tier != null && expire != null && LocalDateTime.now().isBefore(expire);
- + }
- +}
- diff --git a/java/net/sf/l2j/gameserver/GameServer.java b/java/net/sf/l2j/gameserver/GameServer.java
- index 88af6d2..41024a0 100644
- --- a/java/net/sf/l2j/gameserver/GameServer.java
- +++ b/java/net/sf/l2j/gameserver/GameServer.java
- @@ -211,6 +211,7 @@
- import TioPatinhas.Dungeon.DungeonManager;
- import TioPatinhas.Fusion.data.ItemFusionData;
- import TioPatinhas.TerritoryWar.TerritoryWarInit;
- +import TioPatinhas.Vip.VipData;
- import TioPatinhas.WhatsApp.WhatsappBridge;
- import hwid.Hwid;
- import phantom.FakePlayerConfig;
- @@ -576,6 +577,7 @@
- _log.info("Battle Farm Event is disabled");
- ItemFusionData.getInstance();
- + VipData.getInstance();
- Util.printSection("Lotus Dev: Interface");
- TeleportLocationDataLotus.getInstance();
- diff --git a/java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java b/java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java
- index 646ec73..4fc3ad5 100644
- --- a/java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java
- +++ b/java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java
- @@ -66,6 +66,7 @@
- import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminMonsterRace;
- import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminMovieMaker;
- import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminMultiTvT;
- +import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminNewVip;
- import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminOlympiad;
- import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminPCBPoint;
- import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminPForge;
- @@ -184,6 +185,7 @@
- registerAdminCommandHandler(new AdminSearch());
- registerAdminCommandHandler(new AdminScanPlayers());
- registerAdminCommandHandler(new AdminWhatsapp());
- + registerAdminCommandHandler(new AdminNewVip());
- }
- public void registerAdminCommandHandler(IAdminCommandHandler handler)
- diff --git a/java/net/sf/l2j/gameserver/handler/ItemHandler.java b/java/net/sf/l2j/gameserver/handler/ItemHandler.java
- index 7ecd306..edef874 100644
- --- a/java/net/sf/l2j/gameserver/handler/ItemHandler.java
- +++ b/java/net/sf/l2j/gameserver/handler/ItemHandler.java
- @@ -50,6 +50,7 @@
- import net.sf.l2j.gameserver.handler.itemhandlers.SpecialXMas;
- import net.sf.l2j.gameserver.handler.itemhandlers.SpiritShot;
- import net.sf.l2j.gameserver.handler.itemhandlers.SummonItems;
- +import net.sf.l2j.gameserver.handler.itemhandlers.VipToken;
- import net.sf.l2j.gameserver.handler.itemhandlers.clan.ClanLevel;
- import net.sf.l2j.gameserver.handler.itemhandlers.clan.ClanReputation;
- import net.sf.l2j.gameserver.handler.itemhandlers.clan.skills.SkillAegis;
- @@ -144,6 +145,7 @@
- registerItemHandler(new RouletteItem());
- registerItemHandler(new AgationItems());
- registerItemHandler(new CapsuleBox());
- + registerItemHandler(new VipToken());
- if (Config.ALLOW_ITEM_RECOVER)
- diff --git a/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminNewVip.java b/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminNewVip.java
- new file mode 100644
- index 0000000..dca9a8c
- --- /dev/null
- +++ b/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminNewVip.java
- @@ -0,0 +1,93 @@
- +package net.sf.l2j.gameserver.handler.admincommandhandlers;
- +
- +import java.util.StringTokenizer;
- +
- +import net.sf.l2j.gameserver.handler.IAdminCommandHandler;
- +import net.sf.l2j.gameserver.model.L2World;
- +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
- +
- +import TioPatinhas.Vip.VipData;
- +import TioPatinhas.Vip.VipManager;
- +
- +/*
- + * @author -= TioPatinhas =-
- + */
- +public class AdminNewVip implements IAdminCommandHandler
- +{
- +
- + private static final String[] ADMIN_COMMANDS =
- + {
- + "admin_newvip",
- + "admin_clearvip",
- + "admin_reloadvip"
- + };
- +
- + private L2PcInstance resolvePlayer(L2PcInstance admin, String nameOrDot)
- + {
- + if (nameOrDot.equals(".") && admin.getTarget() instanceof L2PcInstance)
- + return (L2PcInstance) admin.getTarget();
- + return L2World.getInstance().getPlayer(nameOrDot);
- + }
- +
- + @Override
- + public boolean useAdminCommand(String command, L2PcInstance activeChar)
- + {
- + final StringTokenizer st = new StringTokenizer(command, " ");
- + final String cmd = st.nextToken();
- +
- + if ("admin_newvip".equalsIgnoreCase(cmd))
- + {
- + if (st.countTokens() < 3)
- + {
- + activeChar.sendMessage("Uso: //newvip <player> <tier> <dias>");
- + return true;
- + }
- + final String playerName = st.nextToken();
- + final String tier = st.nextToken().toLowerCase();
- + final int days = Integer.parseInt(st.nextToken());
- +
- + final L2PcInstance target = resolvePlayer(activeChar, playerName);
- + if (target == null)
- + {
- + activeChar.sendMessage("Player offline.");
- + return true;
- + }
- +
- + VipManager.getInstance().setVip(target, tier, days);
- + activeChar.sendMessage("VIP setado: " + target.getName() + " -> " + tier + " (" + days + "Dia(s))");
- + target.sendMessage("Seu VIP foi ativado: " + tier + " por " + days + " dia(s).");
- + return true;
- + }
- + else if ("admin_clearvip".equalsIgnoreCase(cmd))
- + {
- + if (!st.hasMoreTokens())
- + {
- + activeChar.sendMessage("Uso: //clearvip <player>");
- + return true;
- + }
- + final L2PcInstance target = resolvePlayer(activeChar, st.nextToken());
- + if (target == null)
- + {
- + activeChar.sendMessage("Player offline.");
- + return true;
- + }
- + VipManager.getInstance().clearVip(target);
- + activeChar.sendMessage("VIP removido de " + target.getName());
- + target.sendMessage("Seu VIP foi removido.");
- + return true;
- + }
- + else if ("admin_reloadvip".equalsIgnoreCase(cmd))
- + {
- + VipData.getInstance().reload();
- + activeChar.sendMessage("O VipData e VipItems Foram recarregado.");
- + return true;
- + }
- + return false;
- + }
- +
- + @Override
- + public String[] getAdminCommandList()
- + {
- + return ADMIN_COMMANDS;
- + }
- +}
- diff --git a/java/net/sf/l2j/gameserver/handler/itemhandlers/VipToken.java b/java/net/sf/l2j/gameserver/handler/itemhandlers/VipToken.java
- new file mode 100644
- index 0000000..b962cad
- --- /dev/null
- +++ b/java/net/sf/l2j/gameserver/handler/itemhandlers/VipToken.java
- @@ -0,0 +1,48 @@
- +package net.sf.l2j.gameserver.handler.itemhandlers;
- +
- +import net.sf.l2j.gameserver.handler.IItemHandler;
- +import net.sf.l2j.gameserver.model.actor.L2Playable;
- +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
- +import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
- +import net.sf.l2j.gameserver.network.SystemMessageId;
- +import net.sf.l2j.gameserver.network.clientpackets.Say2;
- +import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
- +import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
- +
- +import TioPatinhas.Vip.VipData;
- +import TioPatinhas.Vip.VipManager;
- +
- +/*
- + * @author -= TioPatinhas =-
- + */
- +public final class VipToken implements IItemHandler
- +{
- +
- + @Override
- + public void useItem(L2Playable playable, ItemInstance item, boolean forceUse)
- + {
- + if (!(playable instanceof L2PcInstance))
- + return;
- +
- + final L2PcInstance player = (L2PcInstance) playable;
- +
- + final VipData.TokenEntry token = VipData.getInstance().getToken(item.getItemId());
- + if (token == null)
- + {
- + player.sendMessage("Token VIP inválido ou não configurado no VipManager.xml.");
- + return;
- + }
- +
- + if (!player.destroyItemByItemId("VipToken", item.getItemId(), 1, player, true))
- + {
- + player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
- + return;
- + }
- +
- + final int days = Math.max(1, token.days);
- + VipManager.getInstance().setVip(player, token.tier, days);
- +
- + player.sendMessage("VIP " + token.tier + " aplicado/renovado por " + days + " dia(s).");
- + player.sendPacket(new CreatureSay(0, Say2.CRITICAL_ANNOUNCE, "", "VIP " + token.tier + " aplicado/renovado por " + days + " dia(s)."));
- + }
- +}
- diff --git a/java/net/sf/l2j/gameserver/model/actor/L2Attackable.java b/java/net/sf/l2j/gameserver/model/actor/L2Attackable.java
- index 02fc312..ff3a8a9 100644
- --- a/java/net/sf/l2j/gameserver/model/actor/L2Attackable.java
- +++ b/java/net/sf/l2j/gameserver/model/actor/L2Attackable.java
- @@ -76,6 +76,8 @@
- import TioPatinhas.BattleFarm.event.AbstractBattleFarm;
- import TioPatinhas.BattleFarm.event.RewardMobRegistry;
- import TioPatinhas.BossEngine.CustomBossManager;
- +import TioPatinhas.Vip.VipData;
- +import TioPatinhas.Vip.VipManager;
- /**
- * This class manages all NPC that can be attacked, such as :
- @@ -643,6 +645,16 @@
- sp *= Config.VIP_XP_SP_RATE;
- }
- + if (attacker != null && attacker.isNewVip() && VipData.getInstance().isUseXpSp(attacker.getNewVipTier()))
- + {
- + final double xpMul = VipManager.getInstance().getXpRateMultiplier(attacker);
- + final double spMul = VipManager.getInstance().getSpRateMultiplier(attacker);
- +
- + exp = Math.round(exp * xpMul);
- + sp = (int) Math.round(sp * spMul);
- + }
- +
- exp *= 1 - penalty;
- if (isOverhit() && _overhitAttacker != null && _overhitAttacker.getActingPlayer() != null && attacker == _overhitAttacker.getActingPlayer())
- @@ -734,6 +746,17 @@
- exp *= Config.VIP_XP_SP_RATE;
- sp *= Config.VIP_XP_SP_RATE;
- }
- +
- + if (attacker != null && attacker.isNewVip() && VipData.getInstance().isUseXpSp(attacker.getNewVipTier()))
- + {
- + final double xpMul = VipManager.getInstance().getXpRateMultiplier(attacker);
- + final double spMul = VipManager.getInstance().getSpRateMultiplier(attacker);
- +
- + exp = Math.round(exp * xpMul);
- + sp = (int) Math.round(sp * spMul);
- + }
- +
- }
- if (isChampion())
- @@ -751,6 +774,15 @@
- exp *= Config.VIP_XP_SP_RATE;
- sp *= Config.VIP_XP_SP_RATE;
- }
- + if (attacker != null && attacker.isNewVip() && VipData.getInstance().isUseXpSp(attacker.getNewVipTier()))
- + {
- + final double xpMul = VipManager.getInstance().getXpRateMultiplier(attacker);
- + final double spMul = VipManager.getInstance().getSpRateMultiplier(attacker);
- +
- + exp = Math.round(exp * xpMul);
- + sp = (int) Math.round(sp * spMul);
- + }
- }
- exp *= partyMul;
- @@ -1069,6 +1101,18 @@
- if (isChampion())
- dropChance *= Config.CHAMPION_REWARDS;
- + if (lastAttacker != null && VipData.getInstance().isEnabled() && lastAttacker.isNewVip())
- + {
- + final double addPercent = VipManager.getInstance().getDropAddPercent(lastAttacker, drop.getItemId());
- +
- + if (addPercent > 0.0)
- + {
- + final double addInChanceUnits = addPercent * (DropData.MAX_CHANCE / 100.0); // MAX_CHANCE = 100%
- + dropChance += addInChanceUnits;
- + }
- + }
- +
- // Set our limits for chance of drop
- if (dropChance < 1)
- dropChance = 1;
- @@ -1104,6 +1148,27 @@
- if (drop.getItemId() >= 6360 && drop.getItemId() <= 6362)
- itemCount *= Config.RATE_DROP_SEAL_STONES;
- + if (itemCount > 0 && lastAttacker != null && VipData.getInstance().isEnabled() && lastAttacker.isNewVip())
- + {
- + final double mul = VipManager.getInstance().getCountMultiplier(lastAttacker, drop.getItemId());
- +
- + if (mul > 1.0)
- + {
- + final int base = itemCount;
- + final int whole = (int) Math.floor(mul);
- + final double frac = mul - whole;
- +
- + long newCount = (long) base * (long) whole;
- + if (frac > 0d && Rnd.nextDouble() < frac)
- + newCount += base;
- +
- + if (newCount < 1 && itemCount > 0)
- + newCount = 1;
- + itemCount = (int) Math.min(Integer.MAX_VALUE, newCount);
- + }
- + }
- +
- if (lastAttacker.isVip())
- {
- if (drop.getItemId() == Config.VIP_DROP_RATE)
- @@ -1187,6 +1252,14 @@
- if (isChampion())
- dropChance *= Config.CHAMPION_REWARDS;
- + if (lastAttacker != null && VipData.getInstance().isEnabled() && lastAttacker.isNewVip())
- + {
- + final double addPercent = VipManager.getInstance().getDropAddPercent(lastAttacker, drop.getItemId());
- + if (addPercent > 0.0)
- + dropChance += (addPercent * (DropData.MAX_CHANCE / 100.0));
- + }
- +
- if (dropChance < DropData.MAX_CHANCE)
- dropChance = DropData.MAX_CHANCE;
- @@ -1232,6 +1305,26 @@
- }
- }
- + if (itemCount > 0 && lastAttacker != null && VipData.getInstance().isEnabled() && lastAttacker.isNewVip())
- + {
- + final double mul = VipManager.getInstance().getCountMultiplier(lastAttacker, drop.getItemId());
- + if (mul > 1.0)
- + {
- + final int base = itemCount;
- + final int whole = (int) Math.floor(mul);
- + final double frac = mul - whole;
- +
- + long newCount = (long) base * (long) whole;
- + if (frac > 0d && Rnd.nextDouble() < frac)
- + newCount += base;
- +
- + if (newCount < 1 && itemCount > 0)
- + newCount = 1;
- + itemCount = (int) Math.min(Integer.MAX_VALUE, newCount);
- + }
- + }
- +
- if (itemCount > 0)
- return new ItemHolder(drop.getItemId(), itemCount, drop.getMinEnchant(), drop.getMaxEnchant(), drop.getEnchantSucess());
- }
- diff --git a/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java b/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java
- index ae7ddc0..cf38913 100644
- --- a/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java
- +++ b/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java
- @@ -17,6 +17,7 @@
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- +import java.time.LocalDateTime;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Calendar;
- @@ -14613,4 +14614,34 @@
- {
- _originalBatlleTitleColor = color;
- }
- +
- + // NewVIP
- + private String _vipTier = null;
- + private LocalDateTime _vipExpire = null;
- +
- + public void setNewVipTier(String t)
- + {
- + _vipTier = t;
- + }
- +
- + public String getNewVipTier()
- + {
- + return _vipTier;
- + }
- +
- + public void setNewVipExpire(LocalDateTime e)
- + {
- + _vipExpire = e;
- + }
- +
- + public LocalDateTime getNewVipExpire()
- + {
- + return _vipExpire;
- + }
- +
- + public boolean isNewVip()
- + {
- + return _vipTier != null && _vipExpire != null && LocalDateTime.now().isBefore(_vipExpire);
- + }
- +
- }
- \ No newline at end of file
- diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java b/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
- index 2ce2d4a..07635f1 100644
- --- a/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
- +++ b/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
- @@ -106,6 +106,7 @@
- import TioPatinhas.BotPrevention.BotsPreventionManager;
- import TioPatinhas.DollSystem.DollsData;
- +import TioPatinhas.Vip.VipManager;
- import hwid.Hwid;
- import phantom.FakePlayer;
- @@ -487,6 +488,8 @@
- L2ClassMasterInstance.showQuestionMark(activeChar);
- + VipManager.getInstance().onLogin(activeChar);
- +
- // VIP Delete
- if (activeChar.isVip())
- {
- diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java b/java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java
- index a1c9d5c..2e836f8 100644
- --- a/java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java
- +++ b/java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java
- @@ -29,6 +29,8 @@
- import net.sf.l2j.gameserver.util.Broadcast;
- import net.sf.l2j.util.Rnd;
- +import TioPatinhas.Vip.VipManager;
- +
- public final class RequestEnchantItem extends L2GameClientPacket
- {
- private int _objectId;
- @@ -104,6 +106,28 @@
- synchronized (item)
- {
- +
- + double chance = enchant.getChance(item);
- +
- + // if (player != null && player.isNewVip())
- + if (player.isNewVip())
- + {
- + final int scrollId = scroll.getItemId();
- + final double mul = VipManager.getInstance().getEnchantMulRate(player, scrollId);
- + final double add = VipManager.getInstance().getEnchantAddPercent(player, scrollId);
- +
- + if (mul != 1.0)
- + chance *= mul;
- + if (add != 0.0)
- + chance += add;
- +
- + if (chance < 0.0)
- + chance = 0.0;
- + if (chance > 100.0)
- + chance = 100.0;
- + }
- +
- if (Rnd.get(100) < enchant.getChance(item)) // success
- {
- // announce the success
- //================================== SQL ===========
- SET NAMES utf8mb4;
- SET FOREIGN_KEY_CHECKS = 0;
- -- ----------------------------
- -- Table structure for character_vip_player
- -- ----------------------------
- DROP TABLE IF EXISTS `character_vip_player`;
- CREATE TABLE `character_vip_player` (
- `charId` int(11) NOT NULL,
- `tier` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
- `expire_at` datetime NOT NULL,
- `updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`charId`) USING BTREE,
- INDEX `idx_character_vip_expire`(`expire_at` ASC) USING BTREE
- ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
- -- ----------------------------
- -- Records of character_vip_player
- -- ----------------------------
- SET FOREIGN_KEY_CHECKS = 1;
Advertisement
Add Comment
Please, Sign In to add comment