Noticias:

Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate

Menú Principal

Premium Service (Last Rev)

Iniciado por Swarlog, Sep 01, 2022, 12:38 AM

Tema anterior - Siguiente tema

Swarlog

CitarCORE:

diff --git a/dist/game/config/Premium.ini b/dist/game/config/Premium.ini
new file mode 100644
index 0000000..bf635ba
--- /dev/null
+++ b/dist/game/config/Premium.ini
@@ -0,0 +1,18 @@
+EnablePremiumSystem = True
+
+# Premium Exp Rates
+PremiumRateXp = 2
+
+# Premium SP Rates
+PremiumRateSp = 2
+
+# Premium Drop Chance Rates
+PremiumRateDropChance = 1
+
+# Premium Drop Amount Rates
+PremiumRateDropAmount = 2
+
+# List of items affected by premium drop rate by id, used now for Adena rate too.
+# Usage: itemId1,multiplier1;itemId2,multiplier2;...
+PremiumDropChanceMultiplierByItemId = 57,1
+PremiumDropAmountMultiplierByItemId = 57,2
diff --git a/src/main/java/com/l2jserver/Config.java b/src/main/java/com/l2jserver/Config.java
index cbc9f0b..a9824a0 100644
--- a/src/main/java/com/l2jserver/Config.java
+++ b/src/main/java/com/l2jserver/Config.java
@@ -108,6 +108,8 @@
    public static final String EMAIL_CONFIG_FILE = "./config/Email.properties";
    public static final String CH_SIEGE_FILE = "./config/ConquerableHallSiege.properties";
    public static final String GEODATA_FILE = "./config/GeoData.properties";
+   public static final String PREMIUM_CONFIG_FILE = "./config/Premium.ini";
+   
    // --------------------------------------------------
    // L2J Variable Definitions
    // --------------------------------------------------
@@ -774,6 +780,18 @@
    public static int L2JMOD_DUALBOX_CHECK_MAX_L2EVENT_PARTICIPANTS_PER_IP;
    public static Map<Integer, Integer> L2JMOD_DUALBOX_CHECK_WHITELIST;
    public static boolean L2JMOD_ALLOW_CHANGE_PASSWORD;
+   
+   // --------------------------------------------------
+   // Premium Settings
+   // --------------------------------------------------
+   public static boolean PREMIUM_SYSTEM_ENABLED;
+   public static float PREMIUM_RATE_XP;
+   public static float PREMIUM_RATE_SP;
+   public static float PREMIUM_RATE_DROP_CHANCE;
+   public static float PREMIUM_RATE_DROP_AMOUNT;
+   public static Map<Integer, Float> PREMIUM_RATE_DROP_CHANCE_MULTIPLIER;
+   public static Map<Integer, Float> PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER;
+   
    // --------------------------------------------------
    // NPC Settings
    // --------------------------------------------------
@@ -2042,6 +2065,68 @@
          DROP_ITEM_MAX_LEVEL_DIFFERENCE = NPC.getInt("DropItemMaxLevelDifference", 10);
          DROP_ITEM_MIN_LEVEL_GAP_CHANCE = NPC.getDouble("DropItemMinLevelGapChance", 10);
         
+         // Premium
+         final PropertiesParser PremiumSettings = new PropertiesParser(PREMIUM_CONFIG_FILE);
+         PREMIUM_SYSTEM_ENABLED = PremiumSettings.getBoolean("EnablePremiumSystem", false);
+         PREMIUM_RATE_XP = PremiumSettings.getFloat("PremiumRateXp", 2);
+         PREMIUM_RATE_SP = PremiumSettings.getFloat("PremiumRateSp", 2);
+         PREMIUM_RATE_DROP_CHANCE = PremiumSettings.getFloat("PremiumRateDropChance", 1);
+         PREMIUM_RATE_DROP_AMOUNT = PremiumSettings.getFloat("PremiumRateDropAmount", 2);
+         String[] premiumDropChanceMultiplier = PremiumSettings.getString("PremiumDropChanceMultiplierByItemId", "").split(";");
+         PREMIUM_RATE_DROP_CHANCE_MULTIPLIER = new HashMap<>(premiumDropChanceMultiplier.length);
+         if (!premiumDropChanceMultiplier[0].isEmpty())
+         {
+            for (String item : premiumDropChanceMultiplier)
+            {
+               String[] itemSplit = item.split(",");
+               if (itemSplit.length != 2)
+               {
+                  _log.warn(StringUtil.concat("Config.load(): invalid config property -> PremiumDropChanceMultiplierByItemId \"", item, "\""));
+               }
+               else
+               {
+                  try
+                  {
+                     PREMIUM_RATE_DROP_CHANCE_MULTIPLIER.put(Integer.valueOf(itemSplit[0]), Float.valueOf(itemSplit[1]));
+                  }
+                  catch (NumberFormatException nfe)
+                  {
+                     if (!item.isEmpty())
+                     {
+                        _log.warn(StringUtil.concat("Config.load(): invalid config property -> PremiumDropChanceMultiplierByItemId \"", item, "\""));
+                     }
+                  }
+               }
+            }
+         }
+         String[] premiumDropAmountMultiplier = PremiumSettings.getString("PremiumDropAmountMultiplierByItemId", "").split(";");
+         PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER = new HashMap<>(premiumDropAmountMultiplier.length);
+         if (!premiumDropAmountMultiplier[0].isEmpty())
+         {
+            for (String item : premiumDropAmountMultiplier)
+            {
+               String[] itemSplit = item.split(",");
+               if (itemSplit.length != 2)
+               {
+                  _log.warn(StringUtil.concat("Config.load(): invalid config property -> PremiumDropAmountMultiplierByItemId \"", item, "\""));
+               }
+               else
+               {
+                  try
+                  {
+                     PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.put(Integer.valueOf(itemSplit[0]), Float.valueOf(itemSplit[1]));
+                  }
+                  catch (NumberFormatException nfe)
+                  {
+                     if (!item.isEmpty())
+                     {
+                        _log.warn(StringUtil.concat("Config.load(): invalid config property -> PremiumDropAmountMultiplierByItemId \"", item, "\""));
+                     }
+                  }
+               }
+            }
+         }
+         
          // Load Rates L2Properties file (if exists)
          final PropertiesParser RatesSettings = new PropertiesParser(RATES_CONFIG_FILE);
         
diff --git a/src/main/java/com/l2jserver/gameserver/GameServer.java b/src/main/java/com/l2jserver/gameserver/GameServer.java
index c29f23e..2a7d04d 100644
--- a/src/main/java/com/l2jserver/gameserver/GameServer.java
+++ b/src/main/java/com/l2jserver/gameserver/GameServer.java
@@ -114,6 +115,7 @@
 import com.l2jserver.gameserver.instancemanager.MapRegionManager;
 import com.l2jserver.gameserver.instancemanager.MercTicketManager;
 import com.l2jserver.gameserver.instancemanager.PetitionManager;
+import com.l2jserver.gameserver.instancemanager.PremiumManager;
 import com.l2jserver.gameserver.instancemanager.PunishmentManager;
 import com.l2jserver.gameserver.instancemanager.QuestManager;
 import com.l2jserver.gameserver.instancemanager.RaidBossPointsManager;
@@ -231,6 +234,12 @@
       PetDataTable.getInstance();
       CharSummonTable.getInstance().init();
       
+      if (Config.PREMIUM_SYSTEM_ENABLED)
+      {
+         _log.info("Premium System: Premium System is turned ON");
+         PremiumManager.getInstance();
+      }
+     
       printSection("Clans");
       ClanTable.getInstance();
       CHSiegeManager.getInstance();
diff --git a/src/main/java/com/l2jserver/gameserver/engines/DocumentParser.java b/src/main/java/com/l2jserver/gameserver/engines/DocumentParser.java
new file mode 100644
index 0000000..213d0e6
--- /dev/null
+++ b/src/main/java/com/l2jserver/gameserver/engines/DocumentParser.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.engines;
+
+import java.io.File;
+import java.io.FileFilter;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXParseException;
+
+import com.l2jserver.Config;
+import com.l2jserver.util.file.filter.XMLFilter;
+
+/**
+ * Abstract class for XML parsers.<br>
+ * It's in <i>beta</i> state, so it's expected to change over time.
+ * @author Zoey76
+ */
+public abstract class DocumentParser
+{
+   protected final Logger _log = LoggerFactory.getLogger(getClass().getName());
+   
+   private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+   private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
+   
+   private static final XMLFilter xmlFilter = new XMLFilter();
+   
+   private File _currentFile;
+   
+   private Document _currentDocument;
+   
+   private FileFilter _currentFilter = null;
+   
+   /**
+    * This method can be used to load/reload the data.<br>
+    * It's highly recommended to clear the data storage, either the list or map.
+    */
+   public abstract void load();
+   
+   /**
+    * Wrapper for {@link #parseFile(File)} method.
+    * @param path the relative path to the datapack root of the XML file to parse.
+    */
+   protected void parseDatapackFile(String path)
+   {
+      parseFile(new File(Config.DATAPACK_ROOT, path));
+   }
+   
+   /**
+    * Parses a single XML file.<br>
+    * If the file was successfully parsed, call {@link #parseDocument(Document)} for the parsed document.<br>
+    * <b>Validation is enforced.</b>
+    * @param f the XML file to parse.
+    */
+   protected void parseFile(File f)
+   {
+      if (!getCurrentFileFilter().accept(f))
+      {
+         _log.warn(getClass().getSimpleName() + ": Could not parse " + f.getName() + " is not a file or it doesn't exist!");
+         return;
+      }
+     
+      final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+      dbf.setNamespaceAware(true);
+      dbf.setValidating(true);
+      dbf.setIgnoringComments(true);
+      _currentDocument = null;
+      _currentFile = f;
+      try
+      {
+         dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
+         final DocumentBuilder db = dbf.newDocumentBuilder();
+         db.setErrorHandler(new XMLErrorHandler());
+         _currentDocument = db.parse(f);
+      }
+      catch (Exception e)
+      {
+         _log.warn(getClass().getSimpleName() + ": Could not parse " + f.getName() + " file: " + e.getMessage());
+         return;
+      }
+      parseDocument();
+   }
+   
+   /**
+    * Gets the current file.
+    * @return the current file
+    */
+   public File getCurrentFile()
+   {
+      return _currentFile;
+   }
+   
+   /**
+    * Gets the current document.
+    * @return the current document
+    */
+   protected Document getCurrentDocument()
+   {
+      return _currentDocument;
+   }
+   
+   /**
+    * Wrapper for {@link #parseDirectory(File, boolean)}.
+    * @param file the path to the directory where the XML files are.
+    * @return {@code false} if it fails to find the directory, {@code true} otherwise.
+    */
+   protected boolean parseDirectory(File file)
+   {
+      return parseDirectory(file, false);
+   }
+   
+   /**
+    * Wrapper for {@link #parseDirectory(File, boolean)}.
+    * @param path the path to the directory where the XML files are.
+    * @return {@code false} if it fails to find the directory, {@code true} otherwise.
+    */
+   protected boolean parseDirectory(String path)
+   {
+      return parseDirectory(new File(path), false);
+   }
+   
+   /**
+    * Wrapper for {@link #parseDirectory(File, boolean)}.
+    * @param path the path to the directory where the XML files are.
+    * @param recursive parses all sub folders if there is.
+    * @return {@code false} if it fails to find the directory, {@code true} otherwise.
+    */
+   protected boolean parseDirectory(String path, boolean recursive)
+   {
+      return parseDirectory(new File(path), recursive);
+   }
+   
+   /**
+    * Loads all XML files from {@code path} and calls {@link #parseFile(File)} for each one of them.
+    * @param dir the directory object to scan.
+    * @param recursive parses all sub folders if there is.
+    * @return {@code false} if it fails to find the directory, {@code true} otherwise.
+    */
+   protected boolean parseDirectory(File dir, boolean recursive)
+   {
+      if (!dir.exists())
+      {
+         _log.warn(getClass().getSimpleName() + ": Folder " + dir.getAbsolutePath() + " doesn't exist!");
+         return false;
+      }
+     
+      final File[] listOfFiles = dir.listFiles();
+      for (File f : listOfFiles)
+      {
+         if (recursive && f.isDirectory())
+         {
+            parseDirectory(f, recursive);
+         }
+         else if (getCurrentFileFilter().accept(f))
+         {
+            parseFile(f);
+         }
+      }
+      return true;
+   }
+   
+   /**
+    * Wrapper for {@link #parseDirectory(File, boolean)}.
+    * @param path the path to the directory where the XML files are
+    * @param recursive parses all sub folders if there is
+    * @return {@code false} if it fails to find the directory, {@code true} otherwise
+    */
+   protected boolean parseDatapackDirectory(String path, boolean recursive)
+   {
+      return parseDirectory(new File(Config.DATAPACK_ROOT, path), recursive);
+   }
+   
+   /**
+    * Overridable method that could parse a custom document.<br>
+    * @param doc the document to parse.
+    */
+   protected void parseDocument(Document doc)
+   {
+      // Do nothing, to be overridden in sub-classes.
+   }
+   
+   /**
+    * Abstract method that when implemented will parse the current document.<br>
+    * Is expected to be call from {@link #parseFile(File)}.
+    */
+   protected abstract void parseDocument();
+   
+   protected Boolean parseBoolean(Node node, Boolean defaultValue)
+   {
+      return node != null ? Boolean.valueOf(node.getNodeValue()) : defaultValue;
+   }
+   
+   protected Boolean parseBoolean(Node node)
+   {
+      return parseBoolean(node, null);
+   }
+   
+   protected Boolean parseBoolean(NamedNodeMap attrs, String name)
+   {
+      return parseBoolean(attrs.getNamedItem(name));
+   }
+   
+   protected Boolean parseBoolean(NamedNodeMap attrs, String name, Boolean defaultValue)
+   {
+      return parseBoolean(attrs.getNamedItem(name), defaultValue);
+   }
+   
+   protected Byte parseByte(Node node, Byte defaultValue)
+   {
+      return node != null ? Byte.valueOf(node.getNodeValue()) : defaultValue;
+   }
+   
+   protected Byte parseByte(Node node)
+   {
+      return parseByte(node, null);
+   }
+   
+   protected Byte parseByte(NamedNodeMap attrs, String name)
+   {
+      return parseByte(attrs.getNamedItem(name));
+   }
+   
+   protected Byte parseByte(NamedNodeMap attrs, String name, Byte defaultValue)
+   {
+      return parseByte(attrs.getNamedItem(name), defaultValue);
+   }
+   
+   protected Short parseShort(Node node, Short defaultValue)
+   {
+      return node != null ? Short.valueOf(node.getNodeValue()) : defaultValue;
+   }
+   
+   protected Short parseShort(Node node)
+   {
+      return parseShort(node, null);
+   }
+   
+   protected Short parseShort(NamedNodeMap attrs, String name)
+   {
+      return parseShort(attrs.getNamedItem(name));
+   }
+   
+   protected Short parseShort(NamedNodeMap attrs, String name, Short defaultValue)
+   {
+      return parseShort(attrs.getNamedItem(name), defaultValue);
+   }
+   
+   protected Integer parseInteger(Node node, Integer defaultValue)
+   {
+      return node != null ? Integer.valueOf(node.getNodeValue()) : defaultValue;
+   }
+   
+   protected Integer parseInteger(Node node)
+   {
+      return parseInteger(node, null);
+   }
+   
+   protected Integer parseInteger(NamedNodeMap attrs, String name)
+   {
+      return parseInteger(attrs.getNamedItem(name));
+   }
+   
+   protected Integer parseInteger(NamedNodeMap attrs, String name, Integer defaultValue)
+   {
+      return parseInteger(attrs.getNamedItem(name), defaultValue);
+   }
+   
+   protected Long parseLong(Node node, Long defaultValue)
+   {
+      return node != null ? Long.valueOf(node.getNodeValue()) : defaultValue;
+   }
+   
+   protected Long parseLong(Node node)
+   {
+      return parseLong(node, null);
+   }
+   
+   protected Long parseLong(NamedNodeMap attrs, String name)
+   {
+      return parseLong(attrs.getNamedItem(name));
+   }
+   
+   protected Long parseLong(NamedNodeMap attrs, String name, Long defaultValue)
+   {
+      return parseLong(attrs.getNamedItem(name), defaultValue);
+   }
+   
+   protected Float parseFloat(Node node, Float defaultValue)
+   {
+      return node != null ? Float.valueOf(node.getNodeValue()) : defaultValue;
+   }
+   
+   protected Float parseFloat(Node node)
+   {
+      return parseFloat(node, null);
+   }
+   
+   protected Float parseFloat(NamedNodeMap attrs, String name)
+   {
+      return parseFloat(attrs.getNamedItem(name));
+   }
+   
+   protected Float parseFloat(NamedNodeMap attrs, String name, Float defaultValue)
+   {
+      return parseFloat(attrs.getNamedItem(name), defaultValue);
+   }
+   
+   protected Double parseDouble(Node node, Double defaultValue)
+   {
+      return node != null ? Double.valueOf(node.getNodeValue()) : defaultValue;
+   }
+   
+   protected Double parseDouble(Node node)
+   {
+      return parseDouble(node, null);
+   }
+   
+   protected Double parseDouble(NamedNodeMap attrs, String name)
+   {
+      return parseDouble(attrs.getNamedItem(name));
+   }
+   
+   protected Double parseDouble(NamedNodeMap attrs, String name, Double defaultValue)
+   {
+      return parseDouble(attrs.getNamedItem(name), defaultValue);
+   }
+   
+   protected String parseString(Node node, String defaultValue)
+   {
+      return node != null ? node.getNodeValue() : defaultValue;
+   }
+   
+   protected String parseString(Node node)
+   {
+      return parseString(node, null);
+   }
+   
+   protected String parseString(NamedNodeMap attrs, String name)
+   {
+      return parseString(attrs.getNamedItem(name));
+   }
+   
+   protected String parseString(NamedNodeMap attrs, String name, String defaultValue)
+   {
+      return parseString(attrs.getNamedItem(name), defaultValue);
+   }
+   
+   protected <T extends Enum<T>> T parseEnum(Node node, Class<T> clazz, T defaultValue)
+   {
+      if (node == null)
+      {
+         return defaultValue;
+      }
+     
+      try
+      {
+         return Enum.valueOf(clazz, node.getNodeValue());
+      }
+      catch (IllegalArgumentException e)
+      {
+         _log.warn("[" + getCurrentFile().getName() + "] Invalid value specified for node: " + node.getNodeName() + " specified value: " + node.getNodeValue() + " should be enum value of \"" + clazz.getSimpleName() + "\" using default value: " + defaultValue);
+         return defaultValue;
+      }
+   }
+   
+   protected <T extends Enum<T>> T parseEnum(Node node, Class<T> clazz)
+   {
+      return parseEnum(node, clazz, null);
+   }
+   
+   protected <T extends Enum<T>> T parseEnum(NamedNodeMap attrs, Class<T> clazz, String name)
+   {
+      return parseEnum(attrs.getNamedItem(name), clazz);
+   }
+   
+   protected <T extends Enum<T>> T parseEnum(NamedNodeMap attrs, Class<T> clazz, String name, T defaultValue)
+   {
+      return parseEnum(attrs.getNamedItem(name), clazz, defaultValue);
+   }
+   
+   public void setCurrentFileFilter(FileFilter filter)
+   {
+      _currentFilter = filter;
+   }
+   
+   public FileFilter getCurrentFileFilter()
+   {
+      return _currentFilter != null ? _currentFilter : xmlFilter;
+   }
+   
+   /**
+    * Simple XML error handler.
+    * @author Zoey76
+    */
+   protected class XMLErrorHandler implements ErrorHandler
+   {
+      @Override
+      public void warning(SAXParseException e) throws SAXParseException
+      {
+         throw e;
+      }
+     
+      @Override
+      public void error(SAXParseException e) throws SAXParseException
+      {
+         throw e;
+      }
+     
+      @Override
+      public void fatalError(SAXParseException e) throws SAXParseException
+      {
+         throw e;
+      }
+   }
+}
diff --git a/src/main/java/com/l2jserver/gameserver/instancemanager/PremiumManager.java b/src/main/java/com/l2jserver/gameserver/instancemanager/PremiumManager.java
new file mode 100644
index 0000000..6118e24
--- /dev/null
+++ b/src/main/java/com/l2jserver/gameserver/instancemanager/PremiumManager.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2004-2016 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.instancemanager;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Calendar;
+
+import com.l2jserver.Config;
+import com.l2jserver.commons.database.pool.impl.ConnectionFactory;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+public class PremiumManager
+{
+   private long endDate = 0;
+   
+   private static final String GETPREM = "SELECT premium_service,enddate FROM account_premium WHERE account_name=?";
+   private static final String UPDATEPREM = "UPDATE account_premium SET premium_service=?,enddate=? WHERE account_name=?";
+   private static final String REMOVEPREM = "INSERT INTO account_premium (account_name,premium_service,enddate) values(?,?,?) ON DUPLICATE KEY UPDATE premium_service = ?, enddate = ?";
+   
+   public long getPremiumEndDate(String accountName)
+   {
+      try (Connection con = ConnectionFactory.getInstance().getConnection();
+         PreparedStatement statement = con.prepareStatement(GETPREM))
+      {
+         statement.setString(1, accountName);
+         ResultSet rset = statement.executeQuery();
+         while (rset.next())
+         {
+            if (Config.PREMIUM_SYSTEM_ENABLED)
+            {
+               endDate = rset.getLong("enddate");
+               if (endDate <= System.currentTimeMillis())
+               {
+                  endDate = 0;
+                  removePremiumStatus(accountName);
+               }
+            }
+         }
+         statement.close();
+      }
+      catch (Exception e)
+      {
+      }
+     
+      return endDate;
+   }
+   
+   public void updatePremiumData(int months, String accountName)
+   {
+      long remainingTime = getPremiumEndDate(accountName);
+      if (remainingTime > 0)
+      {
+         remainingTime -= System.currentTimeMillis();
+      }
+     
+      try (Connection con = ConnectionFactory.getInstance().getConnection();
+         PreparedStatement statement = con.prepareStatement(UPDATEPREM))
+         
+      {
+         Calendar endDate = Calendar.getInstance();
+         endDate.setTimeInMillis(System.currentTimeMillis() + remainingTime);
+         endDate.set(Calendar.SECOND, 0);
+         endDate.add(Calendar.MONTH, months);
+         
+         statement.setInt(1, 1);
+         statement.setLong(2, endDate.getTimeInMillis());
+         statement.setString(3, accountName);
+         statement.execute();
+         statement.close();
+      }
+      catch (SQLException e)
+      {
+      }
+     
+      for (L2PcInstance player : L2World.getInstance().getPlayers())
+      {
+         if (player.getAccountNamePlayer().equalsIgnoreCase(accountName))
+         {
+            player.setPremiumStatus(getPremiumEndDate(accountName) > 0 ? true : false);
+         }
+      }
+   }
+   
+   public void removePremiumStatus(String accountName)
+   {
+      // TODO: Add check if account exists. XD
+      try (Connection con = ConnectionFactory.getInstance().getConnection();
+         PreparedStatement statement = con.prepareStatement(REMOVEPREM))
+      {
+         statement.setString(1, accountName);
+         statement.setInt(2, 0);
+         statement.setLong(3, 0);
+         statement.setInt(4, 0);
+         statement.setLong(5, 0);
+         statement.execute();
+         statement.close();
+      }
+      catch (SQLException e)
+      {
+      }
+     
+      for (L2PcInstance player : L2World.getInstance().getPlayers())
+      {
+         if (player.getAccountNamePlayer().equalsIgnoreCase(accountName))
+         {
+            player.setPremiumStatus(false);
+         }
+      }
+   }
+   
+   public static final PremiumManager getInstance()
+   {
+      return SingletonHolder._instance;
+   }
+   
+   private static class SingletonHolder
+   {
+      protected static final PremiumManager _instance = new PremiumManager();
+   }
+}
\ No newline at end of file
diff --git a/src/main/java/com/l2jserver/gameserver/model/L2World.java b/src/main/java/com/l2jserver/gameserver/model/L2World.java
index 4aa6c2e..7f94cf6 100644
--- a/src/main/java/com/l2jserver/gameserver/model/L2World.java
+++ b/src/main/java/com/l2jserver/gameserver/model/L2World.java
@@ -340,9 +340,10 @@
       
       // Goes through all surrounding world region's creatures.
       // And removes the object from their known lists.
-      for (L2WorldRegion worldRegion : oldWorldRegion.getSurroundingRegions())
+      for (L2WorldRegion reg : oldWorldRegion.getSurroundingRegions())
       {
-         for (L2Object obj : worldRegion.getVisibleObjects().values())
+         final Collection<L2Object> vObj = reg.getVisibleObjects().values();
+         for (L2Object obj : vObj)
          {
             if (obj != null)
             {
diff --git a/src/main/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java b/src/main/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
index f4151eb..595b92e 100644
--- a/src/main/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
+++ b/src/main/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
@@ -112,6 +112,7 @@
 import com.l2jserver.gameserver.instancemanager.HandysBlockCheckerManager;
 import com.l2jserver.gameserver.instancemanager.InstanceManager;
 import com.l2jserver.gameserver.instancemanager.ItemsOnGroundManager;
+import com.l2jserver.gameserver.instancemanager.PremiumManager;
 import com.l2jserver.gameserver.instancemanager.PunishmentManager;
 import com.l2jserver.gameserver.instancemanager.QuestManager;
 import com.l2jserver.gameserver.instancemanager.SiegeManager;
@@ -360,6 +362,8 @@
    private static final String INSERT_CHARACTER = "INSERT INTO characters (account_name,charId,char_name,level,maxHp,curHp,maxCp,curCp,maxMp,curMp,face,hairStyle,hairColor,sex,exp,sp,karma,fame,pvpkills,pkkills,clanid,race,classid,deletetime,cancraft,title,title_color,accesslevel,online,isin7sdungeon,clan_privs,wantspeace,base_class,newbie,nobless,power_grade,createDate) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,face=?,hairStyle=?,hairColor=?,sex=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,fame=?,pvpkills=?,pkkills=?,clanid=?,race=?,classid=?,deletetime=?,title=?,title_color=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,newbie=?,nobless=?,power_grade=?,subpledge=?,lvl_joined_academy=?,apprentice=?,sponsor=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=?,bookmarkslot=?,vitality_points=?,language=? WHERE charId=?";
    private static final String RESTORE_CHARACTER = "SELECT * FROM characters WHERE charId=?";
+   
+   private static final String RESTORE_PREMIUMSERVICE = "SELECT premium_service,enddate FROM account_premium WHERE account_name=?";
   
    // Character Teleport Bookmark:
    private static final String INSERT_TP_BOOKMARK = "INSERT INTO character_tpbookmark (charId,Id,x,y,z,icon,tag,name) values (?,?,?,?,?,?,?,?)";
@@ -559,6 +568,8 @@
   
    private boolean _noble = false;
    private boolean _hero = false;
+   
+   private boolean _premiumStatus = false;
   
    /** The L2FolkInstance corresponding to the last Folk which one the player talked. */
    private L2Npc _lastFolkNpc = null;
@@ -6769,6 +6788,7 @@
               
                player = new L2PcInstance(objectId, template, rset.getString("account_name"), app);
                player.setName(rset.getString("char_name"));
+               restorePremiumSystemData(player, rset.getString("account_name"));
                player._lastAccess = rset.getLong("lastAccess");
               
                player.getStat().setExp(rset.getLong("exp"));
@@ -13907,6 +13931,62 @@
       _recoTwoHoursGiven = val;
    }
   
+   public void setPremiumStatus(boolean premiumStatus)
+   {
+      _premiumStatus = premiumStatus;
+   }
+   
+   public boolean hasPremiumStatus()
+   {
+      if (!Config.PREMIUM_SYSTEM_ENABLED)
+      {
+         return false;
+      }
+      return _premiumStatus;
+   }
+   
+   private static void restorePremiumSystemData(L2PcInstance player, String account)
+   {
+      boolean success = false;
+      try (Connection con = ConnectionFactory.getInstance().getConnection();
+         PreparedStatement ps = con.prepareStatement(RESTORE_PREMIUMSERVICE))
+      {
+         ps.setString(1, account);
+         ResultSet rs = ps.executeQuery();
+         while (rs.next())
+         {
+            success = true;
+            if (Config.PREMIUM_SYSTEM_ENABLED)
+            {
+               if (rs.getLong("enddate") <= System.currentTimeMillis())
+               {
+                  PremiumManager.getInstance().removePremiumStatus(account);
+                  player.setPremiumStatus(false);
+               }
+               else
+               {
+                  player.setPremiumStatus(rs.getBoolean("premium_service"));
+               }
+            }
+            else
+            {
+               player.setPremiumStatus(false);
+            }
+         }
+         ps.close();
+      }
+      catch (Exception e)
+      {
+         LOG.warn("Premium System: Could not restore premium system data for " + account + "." + e);
+         e.printStackTrace();
+      }
+      if (!success)
+      {
+         PremiumManager.getInstance().removePremiumStatus(player.getAccountName());
+         player.setPremiumStatus(false);
+      }
+   }
+   
    public int getRecomBonusTime()
    {
       if (_recoBonusTask != null)
@@ -14145,6 +14225,16 @@
    }
   
    /**
+    * Sets player level.
+    * @param lvl
+    */
+   public void setExpOfLevel(int lvl)
+   {
+      long exp = ExperienceData.getInstance().getExpForLevel(lvl);
+      setExp(exp);
+   }
+   
+   /**
     * Adds a event listener.
     * @param listener
     */
diff --git a/src/main/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java b/src/main/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
index 578a843..c91e788 100644
--- a/src/main/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
+++ b/src/main/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
@@ -137,9 +137,14 @@
          bonusSp = getSpBonusMultiplier();
       }
       
       addToExp *= bonusExp;
       addToSp *= bonusSp;
       
+      if (activeChar.hasPremiumStatus())
+      {
+         addToExp *= Config.PREMIUM_RATE_XP;
+         addToSp *= Config.PREMIUM_RATE_SP;
+      }
       float ratioTakenByPlayer = 0;
       
       // if this player has a pet and it is in his range he takes from the owner's Exp, give the pet Exp now
diff --git a/src/main/java/com/l2jserver/gameserver/model/drops/GeneralDropItem.java b/src/main/java/com/l2jserver/gameserver/model/drops/GeneralDropItem.java
index be83697..248f0a8 100644
--- a/src/main/java/com/l2jserver/gameserver/model/drops/GeneralDropItem.java
+++ b/src/main/java/com/l2jserver/gameserver/model/drops/GeneralDropItem.java
@@ -20,6 +20,7 @@
 
 import java.util.List;
 
+import com.l2jserver.Config;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.drops.strategy.IAmountMultiplierStrategy;
 import com.l2jserver.gameserver.model.drops.strategy.IChanceMultiplierStrategy;
@@ -146,10 +147,19 @@
    /**
     * Gets the min drop count modified by server rates
     * @param victim the victim who drops the item
+    * @param killer
     * @return the min modified by any rates.
     */
-   public final long getMin(L2Character victim)
+   public final long getMin(L2Character victim, L2Character killer)
    {
+      if (Config.PREMIUM_SYSTEM_ENABLED && killer.isPlayer() && killer.getActingPlayer().hasPremiumStatus())
+      {
+         if (Config.PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.get(_itemId) != null)
+         {
+            return (long) (getMin() * getAmountMultiplier(victim) * Config.PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.get(_itemId));
+         }
+         return (long) (getMin() * getAmountMultiplier(victim) * Config.PREMIUM_RATE_DROP_AMOUNT);
+      }
       return (long) (getMin() * getAmountMultiplier(victim));
    }
   
@@ -165,10 +175,19 @@
    /**
     * Gets the max drop count modified by server rates
     * @param victim the victim who drops the item
+    * @param killer
     * @return the max modified by any rates.
     */
-   public final long getMax(L2Character victim)
+   public final long getMax(L2Character victim, L2Character killer)
    {
+      if (Config.PREMIUM_SYSTEM_ENABLED && killer.isPlayer() && killer.getActingPlayer().hasPremiumStatus())
+      {
+         if (Config.PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.get(_itemId) != null)
+         {
+            return (long) (getMax() * getAmountMultiplier(victim) * Config.PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.get(_itemId));
+         }
+         return (long) (getMax() * getAmountMultiplier(victim) * Config.PREMIUM_RATE_DROP_AMOUNT);
+      }
       return (long) (getMax() * getAmountMultiplier(victim));
    }
   
@@ -201,7 +220,15 @@
     */
    public final double getChance(L2Character victim, L2Character killer)
    {
-      return (getKillerChanceModifier(victim, killer) * getChance(victim));
+      if (Config.PREMIUM_SYSTEM_ENABLED && killer.isPlayer() && killer.getActingPlayer().hasPremiumStatus())
+      {
+         if (Config.PREMIUM_RATE_DROP_CHANCE_MULTIPLIER.get(_itemId) != null)
+         {
+            return getKillerChanceModifier(victim, killer) * getChance(victim) * Config.PREMIUM_RATE_DROP_CHANCE_MULTIPLIER.get(_itemId);
+         }
+         return getKillerChanceModifier(victim, killer) * getChance(victim) * Config.PREMIUM_RATE_DROP_CHANCE;
+      }
+      return getKillerChanceModifier(victim, killer) * getChance(victim);
    }
   
    @Override
diff --git a/src/main/java/com/l2jserver/gameserver/model/drops/GroupedGeneralDropItem.java b/src/main/java/com/l2jserver/gameserver/model/drops/GroupedGeneralDropItem.java
index f248c5f..3d90419 100644
--- a/src/main/java/com/l2jserver/gameserver/model/drops/GroupedGeneralDropItem.java
+++ b/src/main/java/com/l2jserver/gameserver/model/drops/GroupedGeneralDropItem.java
@@ -214,14 +214,14 @@
       double sumchance = 0;
       for (GeneralDropItem item : getItems())
       {
-         sumchance += (item.getChance(victim) * getChance() * chanceModifier) / 100;
+         sumchance += (item.getChance(victim, killer) * getChance() * chanceModifier) / 100;
       }
       GroupedGeneralDropItem group = new GroupedGeneralDropItem(sumchance, getDropCalculationStrategy(), IKillerChanceModifierStrategy.NO_RULES, getPreciseStrategy()); // to discard further deep blue calculations
       List<GeneralDropItem> items = new ArrayList<>();
       for (GeneralDropItem item : getItems())
       {
          // the item is made almost "static"
-         items.add(new GeneralDropItem(item.getItemId(), item.getMin(victim), item.getMax(victim), (item.getChance(victim) * getChance() * chanceModifier) / sumchance, IAmountMultiplierStrategy.STATIC, IChanceMultiplierStrategy.STATIC, getPreciseStrategy(), IKillerChanceModifierStrategy.NO_RULES, item.getDropCalculationStrategy()));
+         items.add(new GeneralDropItem(item.getItemId(), item.getMin(victim, killer), item.getMax(victim, killer), (item.getChance(victim, killer) * getChance() * chanceModifier) / sumchance, IAmountMultiplierStrategy.STATIC, IChanceMultiplierStrategy.STATIC, getPreciseStrategy(), IKillerChanceModifierStrategy.NO_RULES, item.getDropCalculationStrategy()));
       }
       group.setItems(items);
       return group;
diff --git a/src/main/java/com/l2jserver/gameserver/model/drops/strategy/IDropCalculationStrategy.java b/src/main/java/com/l2jserver/gameserver/model/drops/strategy/IDropCalculationStrategy.java
index ad8c9ec..75dacdd 100644
--- a/src/main/java/com/l2jserver/gameserver/model/drops/strategy/IDropCalculationStrategy.java
+++ b/src/main/java/com/l2jserver/gameserver/model/drops/strategy/IDropCalculationStrategy.java
@@ -46,7 +46,7 @@
             }
          }
         
-         return Collections.singletonList(new ItemHolder(item.getItemId(), Rnd.get(item.getMin(victim), item.getMax(victim)) * amountMultiply));
+         return Collections.singletonList(new ItemHolder(item.getItemId(), Rnd.get(item.getMin(victim, killer), item.getMax(victim, killer)) * amountMultiply));
       }
       
       return null;
diff --git a/src/main/java/com/l2jserver/gameserver/model/drops/strategy/IGroupedItemDropCalculationStrategy.java b/src/main/java/com/l2jserver/gameserver/model/drops/strategy/IGroupedItemDropCalculationStrategy.java
index 1d39b24..f02ed01 100644
--- a/src/main/java/com/l2jserver/gameserver/model/drops/strategy/IGroupedItemDropCalculationStrategy.java
+++ b/src/main/java/com/l2jserver/gameserver/model/drops/strategy/IGroupedItemDropCalculationStrategy.java
@@ -46,7 +46,8 @@
       private GeneralDropItem getSingleItem(GroupedGeneralDropItem dropItem)
       {
          final GeneralDropItem item1 = dropItem.getItems().iterator().next();
-         singleItemCache.putIfAbsent(dropItem, new GeneralDropItem(item1.getItemId(), item1.getMin(), item1.getMax(), (item1.getChance() * dropItem.getChance()) / 100, item1.getAmountStrategy(), item1.getChanceStrategy(), dropItem.getPreciseStrategy(), dropItem.getKillerChanceModifierStrategy(), item1.getDropCalculationStrategy()));
+         singleItemCache.putIfAbsent(dropItem, new GeneralDropItem(item1.getItemId(), item1.getMin(), item1.getMax(), (item1.getChance() * dropItem.getChance())
+            / 100, item1.getAmountStrategy(), item1.getChanceStrategy(), dropItem.getPreciseStrategy(), dropItem.getKillerChanceModifierStrategy(), item1.getDropCalculationStrategy()));
          return singleItemCache.get(dropItem);
       }
       
@@ -79,7 +80,7 @@
                      }
                   }
                   
-                  return Collections.singletonList(new ItemHolder(item2.getItemId(), Rnd.get(item2.getMin(victim), item2.getMax(victim)) * amountMultiply));
+                  return Collections.singletonList(new ItemHolder(item2.getItemId(), Rnd.get(item2.getMin(victim, killer), item2.getMax(victim, killer)) * amountMultiply));
                }
             }
          }
diff --git a/src/main/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java b/src/main/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java
index 6d728ac..46ef637 100644
--- a/src/main/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java
+++ b/src/main/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java
@@ -65,9 +65,10 @@
 import com.l2jserver.gameserver.network.serverpackets.Die;
 import com.l2jserver.gameserver.network.serverpackets.EtcStatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.ExBasicActionList;
+import com.l2jserver.gameserver.network.serverpackets.ExBrPremiumState;
 import com.l2jserver.gameserver.network.serverpackets.ExGetBookMarkInfoPacket;
 import com.l2jserver.gameserver.network.serverpackets.ExNevitAdventPointInfoPacket;
 import com.l2jserver.gameserver.network.serverpackets.ExNevitAdventTimeChange;
 import com.l2jserver.gameserver.network.serverpackets.ExNoticePostArrived;
 import com.l2jserver.gameserver.network.serverpackets.ExNotifyPremiumItem;
 import com.l2jserver.gameserver.network.serverpackets.ExShowContactList;
@@ -128,7 +127,7 @@
    @Override
    protected void runImpl()
    {
-      final L2PcInstance activeChar = getActiveChar();
+      final L2PcInstance activeChar = getClient().getActiveChar();
       if (activeChar == null)
       {
          _log.warning("EnterWorld failed! activeChar returned 'null'.");
@@ -167,7 +166,15 @@
             _log.warning("User already exists in Object ID map! User " + activeChar.getName() + " is a character clone.");
          }
       }
-     
+      if (activeChar.hasPremiumStatus())
+      {
+         activeChar.sendMessage("Premium service activated");
+         activeChar.sendPacket(new ExBrPremiumState(activeChar.getObjectId(), 1));
+      }
+      else
+      {
+         activeChar.sendPacket(new ExBrPremiumState(activeChar.getObjectId(), 0));
+      }
       // Apply special GM properties to the GM when entering
       if (activeChar.isGM())
       {


CitarDATA:

[code]diff --git a/dist/game/config/adminCommands.xml b/dist/game/config/adminCommands.xml
index d4fe593..bb1bf3a 100644
--- a/dist/game/config/adminCommands.xml
+++ b/dist/game/config/adminCommands.xml
@@ -28,6 +28,14 @@
    <admin command="admin_config_server" accessLevel="7" />
    <admin command="admin_gmon" accessLevel="7" />
 
+   <!-- PREMIUM SYSTEM -->
+   <admin command="admin_premium_menu" accessLevel="7" />
+   <admin command="admin_premium_add1" accessLevel="7" confirmDlg="true" />
+   <admin command="admin_premium_add2" accessLevel="7" confirmDlg="true" />
+   <admin command="admin_premium_add3" accessLevel="7" confirmDlg="true" />
+   <admin command="admin_premium_info" accessLevel="7" />
+   <admin command="admin_premium_remove" accessLevel="7" confirmDlg="true" />
+
    <!-- ADMIN ANNOUNCEMENTS -->
    <admin command="admin_announce" accessLevel="7" />
    <admin command="admin_announce_crit" accessLevel="7" />
diff --git a/dist/game/data/html/admin/premium_menu.htm b/dist/game/data/html/admin/premium_menu.htm
new file mode 100644
index 0000000..0cdfbff
--- /dev/null
+++ b/dist/game/data/html/admin/premium_menu.htm
@@ -0,0 +1,23 @@
+<html><title>L2JServer</title><body>
+<center>
+<table width=270>
+<tr>
+<td width=45><button value="Home" action="bypass admin_admin" width=45 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+<td width=180><center>Premium Menu</center></td>
+<td width=45><button value="Return" action="bypass -h admin_admin6" width=45 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+</tr>
+</table>
+<br>
+<font color="LEVEL">Please enter the account name</font><br>
+<edit var="acc_name" width=200>
+<br>
+<br><button value="Add 1 Mounth" action="bypass -h admin_premium_add1 $acc_name" width=200 height=30 back="L2UI_CT1.OlympiadWnd_DF_Reward_Down" fore="L2UI_CT1.OlympiadWnd_DF_Reward">
+<button value="Add 2 Mounth" action="bypass -h admin_premium_add2 $acc_name" width=200 height=30 back="L2UI_CT1.OlympiadWnd_DF_Reward_Down" fore="L2UI_CT1.OlympiadWnd_DF_Reward">
+<button value="Add 3 Mounth" action="bypass -h admin_premium_add3 $acc_name" width=200 height=30 back="L2UI_CT1.OlympiadWnd_DF_Reward_Down" fore="L2UI_CT1.OlympiadWnd_DF_Reward">
+<br>
+<button value="View Premium Status" action="bypass -h admin_premium_info $acc_name" width=200 height=30 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF">
+<button value="Remove Premium Status" action="bypass -h admin_premium_remove $acc_name" width=200 height=30  back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF">
+<br>
+<font color="FF0000">Players can use the command .premium</font>
+</center>
+</body></html>
\ No newline at end of file
diff --git a/dist/game/data/scripts/handlers/MasterHandler.java b/dist/game/data/scripts/handlers/MasterHandler.java
index 6c7f2b9..4929a70 100644
--- a/dist/game/data/scripts/handlers/MasterHandler.java
+++ b/dist/game/data/scripts/handlers/MasterHandler.java
@@ -105,6 +105,7 @@
 import handlers.admincommandhandlers.AdminPetition;
 import handlers.admincommandhandlers.AdminPledge;
 import handlers.admincommandhandlers.AdminPolymorph;
+import handlers.admincommandhandlers.AdminPremium;
 import handlers.admincommandhandlers.AdminPunishment;
 import handlers.admincommandhandlers.AdminQuest;
 import handlers.admincommandhandlers.AdminReload;
@@ -276,6 +277,7 @@
 import handlers.voicedcommandhandlers.ChatAdmin;
 import handlers.voicedcommandhandlers.Debug;
 import handlers.voicedcommandhandlers.Lang;
+import handlers.voicedcommandhandlers.Premium;
 import handlers.voicedcommandhandlers.StatsVCmd;
 import Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate;
 
@@ -378,6 +380,7 @@
          AdminPForge.class,
          AdminPledge.class,
          AdminPolymorph.class,
+         AdminPremium.class,
          AdminPunishment.class,
          AdminQuest.class,
          AdminReload.class,
@@ -533,6 +536,7 @@
          (Config.L2JMOD_MULTILANG_ENABLE && Config.L2JMOD_MULTILANG_VOICED_ALLOW ? Lang.class : null),
          (Config.L2JMOD_DEBUG_VOICE_COMMAND ? Debug.class : null),
          (Config.L2JMOD_ALLOW_CHANGE_PASSWORD ? ChangePassword.class : null),
+         (Config.PREMIUM_SYSTEM_ENABLED ? Premium.class : null),
       },
       {
          // Target Handlers
diff --git a/dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java b/dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java
new file mode 100644
index 0000000..6d40059
--- /dev/null
+++ b/dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2004-2016 L2J DataPack
+ *
+ * This file is part of L2J DataPack.
+ *
+ * L2J DataPack 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.
+ *
+ * L2J DataPack 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 <Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate>.
+ */
+package handlers.admincommandhandlers;
+
+import java.text.SimpleDateFormat;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.handler.IAdminCommandHandler;
+import com.l2jserver.gameserver.instancemanager.PremiumManager;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate.