Noticias:

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

Menú Principal

Premium Account system

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

Tema anterior - Siguiente tema

Swarlog

CitarCORE:

### Eclipse Workspace Patch 1.0
#P L2J_Server
diff --git dist/game/config/Custom.properties dist/game/config/Custom.properties
new file mode 100644
index 0000000..d32f5c6
--- /dev/null
+++ dist/game/config/Custom.properties
@@ -0,0 +1,33 @@
+# ---------------------------------------------------------------------------
+# Premium System (VIP)
+# ---------------------------------------------------------------------------
+# -Admins can manage subscriptions from main admin menu.
+# -Players can use .premium to view account related info.
+# -Caution: Premium rates multiply existing server rates.
+
+# Enable premium system.
+# Default: False
+EnablePremiumSystem = False
+
+# Xp rate for premium players.
+PremiumRateXp = 2
+
+# Sp rate for premium players.
+PremiumRateSp = 2
+
+# Drop chance for premium players.
+PremiumDeathDropChanceMultiplier = 2
+
+# Drop amount for premium players.
+PremiumDeathDropAmountMultiplier = 1
+
+# Spoil chance for premium players.
+PremiumCorpseDropChanceMultiplier = 2
+
+# Spoil amount for premium players.
+PremiumCorpseDropAmountMultiplier = 1
+
+# List of items affected by custom drop rate by id, used now for Adena rate too.
+# Usage: itemId1,multiplier1;itemId2,multiplier2;...
+PremiumDropChanceMultiplierByItemId = 57,2
+PremiumDropAmountMultiplierByItemId = 57,1
\ No newline at end of file
diff --git java/com/l2jserver/Config.java java/com/l2jserver/Config.java
index 796d027..0c68e8e 100644
--- java/com/l2jserver/Config.java
+++ java/com/l2jserver/Config.java
@@ -107,6 +107,7 @@
  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 CUSTOM_FILE = "./config/Custom.properties";
  // --------------------------------------------------
  // L2J Variable Definitions
  // --------------------------------------------------
@@ -416,6 +417,19 @@
  public static int CLAN_LEVEL_11_REQUIREMENT;
  public static boolean ALLOW_WYVERN_ALWAYS;
  public static boolean ALLOW_WYVERN_DURING_SIEGE;
+
+ // --------------------------------------------------
+ // Premium Account Settings
+ // --------------------------------------------------
+ public static boolean PREMIUM_SYSTEM_ENABLED;
+ public static float PREMIUM_RATE_XP;
+ public static float PREMIUM_RATE_SP;
+ public static float PREMIUM_RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
+ public static float PREMIUM_RATE_CORPSE_DROP_AMOUNT_MULTIPLIER;
+ public static float PREMIUM_RATE_DEATH_DROP_CHANCE_MULTIPLIER;
+ public static float PREMIUM_RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
+ public static Map<Integer, Float> PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER;
+ public static Map<Integer, Float> PREMIUM_RATE_DROP_CHANCE_MULTIPLIER;
 
  // --------------------------------------------------
  // General Settings
@@ -2496,6 +2510,71 @@
  }
  L2JMOD_ALLOW_CHANGE_PASSWORD = L2JModSettings.getBoolean("AllowChangePassword", false);
 
+ // Load Custom Properties file (if exists)
+ final PropertiesParser CustomSettings = new PropertiesParser(CUSTOM_FILE);
+ PREMIUM_SYSTEM_ENABLED = CustomSettings.getBoolean("EnablePremiumSystem", false);
+ PREMIUM_RATE_XP = CustomSettings.getFloat("PremiumRateXp", 2);
+ PREMIUM_RATE_SP = CustomSettings.getFloat("PremiumRateSp", 2);
+ PREMIUM_RATE_DEATH_DROP_AMOUNT_MULTIPLIER = CustomSettings.getFloat("PremiumDeathDropAmountMultiplier", 1);
+ PREMIUM_RATE_CORPSE_DROP_AMOUNT_MULTIPLIER = CustomSettings.getFloat("PremiumCorpseDropAmountMultiplier", 1);
+ PREMIUM_RATE_DEATH_DROP_CHANCE_MULTIPLIER = CustomSettings.getFloat("PremiumDeathDropChanceMultiplier", 1);
+ PREMIUM_RATE_CORPSE_DROP_CHANCE_MULTIPLIER = CustomSettings.getFloat("PremiumCorpseDropChanceMultiplier", 1);
+ String[] premiumdropAmountMultiplier = CustomSettings.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.warning(StringUtil.concat("Config.load(): invalid config property -> PremiumRateDropItemsById \"", item, "\""));
+ }
+ else
+ {
+ try
+ {
+ PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.put(Integer.valueOf(itemSplit[0]), Float.valueOf(itemSplit[1]));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!item.isEmpty())
+ {
+ _log.warning(StringUtil.concat("Config.load(): invalid config property -> PremiumRateDropItemsById \"", item, "\""));
+ }
+ }
+ }
+ }
+ }
+
+ String[] premiumdropChanceMultiplier = CustomSettings.getString("PremiumDropChanceMultiplierByItemId", "").split(";");
+ PREMIUM_RATE_DROP_CHANCE_MULTIPLIER = new HashMap<>(premiumdropChanceMultiplier.length);
+ if (!dropChanceMultiplier[0].isEmpty())
+ {
+ for (String item : premiumdropChanceMultiplier)
+ {
+ String[] itemSplit = item.split(",");
+ if (itemSplit.length != 2)
+ {
+ _log.warning(StringUtil.concat("Config.load(): invalid config property -> PremiumRateDropItemsById \"", item, "\""));
+ }
+ else
+ {
+ try
+ {
+ PREMIUM_RATE_DROP_CHANCE_MULTIPLIER.put(Integer.valueOf(itemSplit[0]), Float.valueOf(itemSplit[1]));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!item.isEmpty())
+ {
+ _log.warning(StringUtil.concat("Config.load(): invalid config property -> PremiumRateDropItemsById \"", item, "\""));
+ }
+ }
+ }
+ }
+ }
+
  // Load PvP L2Properties file (if exists)
  final PropertiesParser PVPSettings = new PropertiesParser(PVP_CONFIG_FILE);
 
diff --git java/com/l2jserver/gameserver/GameServer.java java/com/l2jserver/gameserver/GameServer.java
index 25de90c..d82feaf 100644
--- java/com/l2jserver/gameserver/GameServer.java
+++ java/com/l2jserver/gameserver/GameServer.java
@@ -112,6 +112,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;
@@ -243,6 +244,11 @@
  RaidBossPointsManager.getInstance();
  PetDataTable.getInstance();
  CharSummonTable.getInstance().init();
+ if (Config.PREMIUM_SYSTEM_ENABLED)
+ {
+ _log.info("PremiumManager: Premium system is enabled.");
+ PremiumManager.getInstance();
+ }
 
  printSection("Clans");
  ClanTable.getInstance();
diff --git java/com/l2jserver/gameserver/instancemanager/PremiumManager.java java/com/l2jserver/gameserver/instancemanager/PremiumManager.java
new file mode 100644
index 0000000..3815641
--- /dev/null
+++ java/com/l2jserver/gameserver/instancemanager/PremiumManager.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2004-2015 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.L2DatabaseFactory;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+public class PremiumManager
+{
+ private long endDate = 0;
+
+ public long getPremiumEndDate(String accountName)
+ {
+ try (Connection con = L2DatabaseFactory.getInstance().getConnection())
+ {
+ PreparedStatement statement = con.prepareStatement("SELECT premium_service,enddate FROM account_premium WHERE account_name=?");
+ 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 = L2DatabaseFactory.getInstance().getConnection())
+ {
+ Calendar endDate = Calendar.getInstance();
+ endDate.setTimeInMillis(System.currentTimeMillis() + remainingTime);
+ endDate.set(Calendar.SECOND, 0);
+ endDate.add(Calendar.MONTH, months);
+
+ PreparedStatement statement = con.prepareStatement("UPDATE account_premium SET premium_service=?,enddate=? WHERE account_name=?");
+ 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 = L2DatabaseFactory.getInstance().getConnection())
+ {
+ PreparedStatement statement = con.prepareStatement("INSERT INTO account_premium (account_name,premium_service,enddate) values(?,?,?) ON DUPLICATE KEY UPDATE premium_service = ?, enddate = ?");
+ 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 java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
index 8762730..c13a577 100644
--- java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
+++ java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
@@ -108,6 +108,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;
@@ -354,6 +355,9 @@
  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=?";
 
+ // Character Premium System String Definitions:
+ 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 (?,?,?,?,?,?,?,?)";
  private static final String UPDATE_TP_BOOKMARK = "UPDATE character_tpbookmark SET icon=?,tag=?,name=? where charId=? AND Id=?";
@@ -554,6 +558,9 @@
 
  private boolean _noble = false;
  private boolean _hero = false;
+
+ /** Premium System */
+ private boolean _premiumStatus = false;
 
  /** The L2FolkInstance corresponding to the last Folk which one the player talked. */
  private L2Npc _lastFolkNpc = null;
@@ -6774,6 +6781,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"));
@@ -13966,6 +13974,58 @@
  return 0;
  }
 
+ public void setPremiumStatus(boolean premiumStatus)
+ {
+ _premiumStatus = premiumStatus;
+ }
+
+ public boolean hasPremiumStatus()
+ {
+ return _premiumStatus;
+ }
+
+ private static void restorePremiumSystemData(L2PcInstance player, String account)
+ {
+ boolean success = false;
+ try (Connection con = L2DatabaseFactory.getInstance().getConnection())
+ {
+ PreparedStatement statement = con.prepareStatement(RESTORE_PREMIUMSERVICE);
+ statement.setString(1, account);
+ ResultSet rset = statement.executeQuery();
+ while (rset.next())
+ {
+ success = true;
+ if (Config.PREMIUM_SYSTEM_ENABLED)
+ {
+ if (rset.getLong("enddate") <= System.currentTimeMillis())
+ {
+ PremiumManager.getInstance().removePremiumStatus(account);
+ player.setPremiumStatus(false);
+ }
+ else
+ {
+ player.setPremiumStatus(rset.getBoolean("premium_service"));
+ }
+ }
+ else
+ {
+ player.setPremiumStatus(false);
+ }
+ }
+ statement.close();
+ }
+ catch (Exception e)
+ {
+ _log.warning("Premium System: Could not restore premium system data for " + account + "." + e);
+ e.printStackTrace();
+ }
+ if (success == false)
+ {
+ PremiumManager.getInstance().removePremiumStatus(player.getAccountName());
+ player.setPremiumStatus(false);
+ }
+ }
+
  public void setLastPetitionGmName(String gmName)
  {
  _lastPetitionGmName = gmName;
diff --git java/com/l2jserver/gameserver/model/actor/stat/PcStat.java java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
index 1f80731..1c4f46f 100644
--- java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
+++ java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
@@ -139,6 +139,12 @@
  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 java/com/l2jserver/gameserver/model/drops/CorpseDropItem.java java/com/l2jserver/gameserver/model/drops/CorpseDropItem.java
index a338f5a..d73f233 100644
--- java/com/l2jserver/gameserver/model/drops/CorpseDropItem.java
+++ java/com/l2jserver/gameserver/model/drops/CorpseDropItem.java
@@ -41,9 +41,9 @@
  * @see com.l2jserver.gameserver.model.drops.GeneralDropItem#getGlobalAmountMultiplier()
  */
  @Override
- protected double getGlobalAmountMultiplier()
+ protected double getGlobalAmountMultiplier(boolean isPremium)
  {
- return Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER;
+ return isPremium ? Config.PREMIUM_RATE_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER : Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER;
  }
 
  /*
@@ -51,8 +51,8 @@
  * @see com.l2jserver.gameserver.model.drops.GeneralDropItem#getGlobalChanceMultiplier()
  */
  @Override
- protected double getGlobalChanceMultiplier()
+ protected double getGlobalChanceMultiplier(boolean isPremium)
  {
- return Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
+ return isPremium ? Config.PREMIUM_RATE_CORPSE_DROP_CHANCE_MULTIPLIER * Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER : Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
  }
 }
diff --git java/com/l2jserver/gameserver/model/drops/DeathDropItem.java java/com/l2jserver/gameserver/model/drops/DeathDropItem.java
index 5ffee75..c85a9e8 100644
--- java/com/l2jserver/gameserver/model/drops/DeathDropItem.java
+++ java/com/l2jserver/gameserver/model/drops/DeathDropItem.java
@@ -41,9 +41,9 @@
  * @see com.l2jserver.gameserver.model.drops.GeneralDropItem#getGlobalAmountMultiplier()
  */
  @Override
- protected double getGlobalAmountMultiplier()
+ protected double getGlobalAmountMultiplier(boolean isPremium)
  {
- return Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
+ return isPremium ? Config.PREMIUM_RATE_DEATH_DROP_AMOUNT_MULTIPLIER * Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER : Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
  }
 
  /*
@@ -51,8 +51,8 @@
  * @see com.l2jserver.gameserver.model.drops.GeneralDropItem#getGlobalChanceMultiplier()
  */
  @Override
- protected double getGlobalChanceMultiplier()
+ protected double getGlobalChanceMultiplier(boolean isPremium)
  {
- return Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
+ return isPremium ? Config.PREMIUM_RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER : Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
  }
 }
diff --git java/com/l2jserver/gameserver/model/drops/GeneralDropItem.java java/com/l2jserver/gameserver/model/drops/GeneralDropItem.java
index 34638ce..5e837e0 100644
--- java/com/l2jserver/gameserver/model/drops/GeneralDropItem.java
+++ java/com/l2jserver/gameserver/model/drops/GeneralDropItem.java
@@ -54,12 +54,12 @@
  _chance = chance;
  }
 
- protected double getGlobalChanceMultiplier()
+ protected double getGlobalChanceMultiplier(boolean isPremium)
  {
  return 1.;
  }
 
- protected double getGlobalAmountMultiplier()
+ protected double getGlobalAmountMultiplier(boolean isPremium)
  {
  return 1.;
  }
@@ -69,7 +69,29 @@
  double multiplier = 1;
 
  // individual drop amount
- Float individualDropAmountMultiplier = Config.RATE_DROP_AMOUNT_MULTIPLIER.get(getItemId());
+ Float individualDropAmountMultiplier = null;
+ if (killer.getActingPlayer().hasPremiumStatus())
+ {
+ final Float normalMultiplier = Config.RATE_DROP_AMOUNT_MULTIPLIER.get(getItemId());
+ final Float premiumMultiplier = Config.PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.get(getItemId());
+ if ((normalMultiplier != null) && (premiumMultiplier != null))
+ {
+ individualDropAmountMultiplier = normalMultiplier * premiumMultiplier;
+ }
+ else if (normalMultiplier != null)
+ {
+ individualDropAmountMultiplier = normalMultiplier;
+ }
+ else if (premiumMultiplier != null)
+ {
+ individualDropAmountMultiplier = premiumMultiplier;
+ }
+ }
+ else
+ {
+ individualDropAmountMultiplier = Config.RATE_DROP_AMOUNT_MULTIPLIER.get(getItemId());
+ }
+
  if (individualDropAmountMultiplier != null)
  {
  // individual amount list multiplier
@@ -87,7 +109,7 @@
  else
  {
  // drop type specific amount multiplier
- multiplier *= getGlobalAmountMultiplier();
+ multiplier *= getGlobalAmountMultiplier(killer.getActingPlayer().hasPremiumStatus());
  }
  }
 
@@ -169,7 +191,29 @@
  double multiplier = 1;
 
  // individual drop chance
- Float individualDropChanceMultiplier = Config.RATE_DROP_CHANCE_MULTIPLIER.get(getItemId());
+ Float individualDropChanceMultiplier = null;
+ if (killer.getActingPlayer().hasPremiumStatus())
+ {
+ final Float normalMultiplier = Config.RATE_DROP_CHANCE_MULTIPLIER.get(getItemId());
+ final Float premiumMultiplier = Config.PREMIUM_RATE_DROP_CHANCE_MULTIPLIER.get(getItemId());
+ if ((normalMultiplier != null) && (premiumMultiplier != null))
+ {
+ individualDropChanceMultiplier = normalMultiplier * premiumMultiplier;
+ }
+ else if (normalMultiplier != null)
+ {
+ individualDropChanceMultiplier = normalMultiplier;
+ }
+ else if (premiumMultiplier != null)
+ {
+ individualDropChanceMultiplier = premiumMultiplier;
+ }
+ }
+ else
+ {
+ individualDropChanceMultiplier = Config.RATE_DROP_CHANCE_MULTIPLIER.get(getItemId());
+ }
+
  if (individualDropChanceMultiplier != null)
  {
  multiplier *= individualDropChanceMultiplier;
@@ -183,7 +227,7 @@
  }
  else
  {
- multiplier *= getGlobalChanceMultiplier();
+ multiplier *= getGlobalChanceMultiplier(killer.getActingPlayer().hasPremiumStatus());
  }
  }
 
diff --git java/com/l2jserver/gameserver/model/drops/GroupedCorpseDropItem.java java/com/l2jserver/gameserver/model/drops/GroupedCorpseDropItem.java
index 9e8df87..fe23b6b 100644
--- java/com/l2jserver/gameserver/model/drops/GroupedCorpseDropItem.java
+++ java/com/l2jserver/gameserver/model/drops/GroupedCorpseDropItem.java
@@ -38,8 +38,8 @@
  * @see com.l2jserver.gameserver.model.drops.GroupedGeneralDropItem#getGlobalChanceMultiplier()
  */
  @Override
- protected double getGlobalChanceMultiplier()
+ protected double getGlobalChanceMultiplier(boolean isPremium)
  {
- return Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
+ return isPremium ? Config.PREMIUM_RATE_CORPSE_DROP_CHANCE_MULTIPLIER * Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER : Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
  }
 }
diff --git java/com/l2jserver/gameserver/model/drops/GroupedDeathDropItem.java java/com/l2jserver/gameserver/model/drops/GroupedDeathDropItem.java
index cb7f4bb..728f276 100644
--- java/com/l2jserver/gameserver/model/drops/GroupedDeathDropItem.java
+++ java/com/l2jserver/gameserver/model/drops/GroupedDeathDropItem.java
@@ -38,8 +38,8 @@
  * @see com.l2jserver.gameserver.model.drops.GroupedGeneralDropItem#getGlobalChanceMultiplier()
  */
  @Override
- protected double getGlobalChanceMultiplier()
+ protected double getGlobalChanceMultiplier(boolean isPremium)
  {
- return Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
+ return isPremium ? Config.PREMIUM_RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER : Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
  }
 }
diff --git java/com/l2jserver/gameserver/model/drops/GroupedGeneralDropItem.java java/com/l2jserver/gameserver/model/drops/GroupedGeneralDropItem.java
index 79e9f78..044e85f 100644
--- java/com/l2jserver/gameserver/model/drops/GroupedGeneralDropItem.java
+++ java/com/l2jserver/gameserver/model/drops/GroupedGeneralDropItem.java
@@ -48,7 +48,7 @@
  _chance = chance;
  }
 
- protected double getGlobalChanceMultiplier()
+ protected double getGlobalChanceMultiplier(boolean isPremium)
  {
  return 1.;
  }
@@ -75,7 +75,7 @@
  final L2Item item = ItemTable.getInstance().getTemplate(gdi.getItemId());
  if ((item == null) || !item.hasExImmediateEffect())
  {
- return getChance() * getGlobalChanceMultiplier();
+ return getChance() * getGlobalChanceMultiplier(killer.getActingPlayer().hasPremiumStatus());
  }
  }
 
diff --git java/com/l2jserver/gameserver/model/itemcontainer/ItemContainer.java java/com/l2jserver/gameserver/model/itemcontainer/ItemContainer.java
index d4f7fcb..7a5632c 100644
--- java/com/l2jserver/gameserver/model/itemcontainer/ItemContainer.java
+++ java/com/l2jserver/gameserver/model/itemcontainer/ItemContainer.java
@@ -239,6 +239,10 @@
 
  // Updates database
  float adenaRate = Config.RATE_DROP_AMOUNT_MULTIPLIER.getOrDefault(Inventory.ADENA_ID, 1f);
+ if (actor.hasPremiumStatus() && Config.PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.containsKey(Inventory.ADENA_ID))
+ {
+ adenaRate *= Config.PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.get(Inventory.ADENA_ID);
+ }
  if ((item.getId() == Inventory.ADENA_ID) && (count < (10000 * adenaRate)))
  {
  // Small adena changes won't be saved to database all the time
@@ -291,6 +295,10 @@
  // Updates database
  // If Adena drop rate is not present it will be x1.
  float adenaRate = Config.RATE_DROP_AMOUNT_MULTIPLIER.getOrDefault(Inventory.ADENA_ID, 1f);
+ if (actor.hasPremiumStatus() && Config.PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.containsKey(Inventory.ADENA_ID))
+ {
+ adenaRate *= Config.PREMIUM_RATE_DROP_AMOUNT_MULTIPLIER.get(Inventory.ADENA_ID);
+ }
  if ((itemId == Inventory.ADENA_ID) && (count < (10000 * adenaRate)))
  {
  // Small adena changes won't be saved to database all the time

CitarDATA:

### Eclipse Workspace Patch 1.0
#P L2J_DataPack
diff --git dist/game/config/adminCommands.xml dist/game/config/adminCommands.xml
index d4fe593..69f2c4a 100644
--- dist/game/config/adminCommands.xml
+++ dist/game/config/adminCommands.xml
@@ -420,6 +420,14 @@
  <admin command="admin_untransform" accessLevel="7" />
  <admin command="admin_transform_menu" 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 QUEST -->
  <admin command="admin_quest_reload" accessLevel="7" />
  <admin command="admin_script_load" accessLevel="7" />
diff --git dist/game/data/html/admin/main_menu.htm dist/game/data/html/admin/main_menu.htm
index 1807a16..714f9fc 100644
--- dist/game/data/html/admin/main_menu.htm
+++ dist/game/data/html/admin/main_menu.htm
@@ -28,6 +28,7 @@
 <td><button value="goSpawn" action="bypass -h admin_list_spawns $qbox 1" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
 </tr><tr>
 <td><button value="Scan" action="bypass -h admin_scan $qbox" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+<td><button value="Premium" action="bypass -h admin_premium_menu" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
 </tr>
 </table>
 <br>
diff --git dist/game/data/html/admin/premium_menu.htm dist/game/data/html/admin/premium_menu.htm
new file mode 100644
index 0000000..ce256c6
--- /dev/null
+++ dist/game/data/html/admin/premium_menu.htm
@@ -0,0 +1,16 @@
+<html><title>Premium Service Menu</title><body>
+<center>
+<br>
+<font color="LEVEL">Premium Service Menu</font><br>
+<br>
+Enter Account Name:<br>
+<edit var="acc_name" width=200>
+<br>
+<button value="Add 1 month Premium" action="bypass -h admin_premium_add1 $acc_name" width=200 height=25 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df">
+<button value="Add 2 months Premium" action="bypass -h admin_premium_add2 $acc_name" width=200 height=25 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df">
+<button value="Add 3 months Premium" action="bypass -h admin_premium_add3 $acc_name" width=200 height=25 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df">
+<br>
+<button value="View Premium Info" action="bypass -h admin_premium_info $acc_name" width=200 height=25 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df">
+<button value="Remove Premium" action="bypass -h admin_premium_remove $acc_name" width=200 height=25 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df">
+</center>
+</body></html>
\ No newline at end of file
diff --git dist/game/data/scripts/handlers/MasterHandler.java dist/game/data/scripts/handlers/MasterHandler.java
index 38a3e91..70dbca6 100644
--- dist/game/data/scripts/handlers/MasterHandler.java
+++ dist/game/data/scripts/handlers/MasterHandler.java
@@ -83,6 +83,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;
@@ -253,6 +254,7 @@
 import handlers.voicedcommandhandlers.ChatAdmin;
 import handlers.voicedcommandhandlers.Debug;
 import handlers.voicedcommandhandlers.Lang;
+import handlers.voicedcommandhandlers.Premium;
 import handlers.voicedcommandhandlers.StatsVCmd;
 import handlers.voicedcommandhandlers.Wedding;
 
@@ -377,6 +379,7 @@
  AdminPForge.class,
  AdminPledge.class,
  AdminPolymorph.class,
+ AdminPremium.class,
  AdminPunishment.class,
  AdminQuest.class,
  AdminReload.class,
@@ -532,6 +535,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 dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java
new file mode 100644
index 0000000..8a0c1ce
--- /dev/null
+++ dist/game/data/scripts/handlers/admincommandhandlers/AdminPremium.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2004-2015 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 <http://www.gnu.org/licenses/>.
+ */
+package handlers.admincommandhandlers;
+
+import java.text.SimpleDateFormat;
+
+import com.l2jserver.gameserver.handler.IAdminCommandHandler;
+import com.l2jserver.gameserver.instancemanager.PremiumManager;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+public class AdminPremium implements IAdminCommandHandler
+{
+ private static final String[] ADMIN_COMMANDS =
+ {
+ "admin_premium_menu",
+ "admin_premium_add1",
+ "admin_premium_add2",
+ "admin_premium_add3",
+ "admin_premium_info",
+ "admin_premium_remove"
+ };
+
+ @Override
+ public boolean useAdminCommand(String command, L2PcInstance activeChar)
+ {
+ if (command.equals("admin_premium_menu"))
+ {
+ AdminHtml.showAdminHtml(activeChar, "premium_menu.htm");
+ }
+ else if (command.startsWith("admin_premium_add1"))
+ {
+ try
+ {
+ String val = command.substring(19);
+ addPremiumStatus(activeChar, 1, val);
+ }
+ catch (StringIndexOutOfBoundsException e)
+ {
+ activeChar.sendMessage("Error.");
+ }
+ }
+ else if (command.startsWith("admin_premium_add2"))
+ {
+ try
+ {
+ String val = command.substring(19);
+ addPremiumStatus(activeChar, 2, val);
+ }
+ catch (StringIndexOutOfBoundsException e)
+ {
+ activeChar.sendMessage("Error.");
+ }
+ }
+ else if (command.startsWith("admin_premium_add3"))
+ {
+ try
+ {
+ String val = command.substring(19);
+ addPremiumStatus(activeChar, 3, val);
+ }
+ catch (StringIndexOutOfBoundsException e)
+ {
+ activeChar.sendMessage("Error.");
+ }
+ }
+ else if (command.startsWith("admin_premium_info"))
+ {
+ try
+ {
+ String val = command.substring(19);
+ viewPremiumInfo(activeChar, val);
+ }
+ catch (StringIndexOutOfBoundsException e)
+ {
+ activeChar.sendMessage("Error.");
+ }
+ }
+ else if (command.startsWith("admin_premium_remove"))
+ {
+ try
+ {
+ String val = command.substring(21);
+ removePremium(activeChar, val);
+ }
+ catch (StringIndexOutOfBoundsException e)
+ {
+ activeChar.sendMessage("Error.");
+ }
+ }
+ return true;
+ }
+
+ private void addPremiumStatus(L2PcInstance admin, int months, String accountName)
+ {
+ // TODO: Add check if account exists XD
+ PremiumManager.getInstance().updatePremiumData(months, accountName);
+ final SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm");
+ final long endDate = PremiumManager.getInstance().getPremiumEndDate(accountName);
+ admin.sendMessage("Account " + accountName + " will now have premium status until " + String.valueOf(format.format(endDate)) + ".");
+ }
+
+ private void viewPremiumInfo(L2PcInstance admin, String accountName)
+ {
+ if (PremiumManager.getInstance().getPremiumEndDate(accountName) > 0)
+ {
+ final SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm");
+ final long endDate = PremiumManager.getInstance().getPremiumEndDate(accountName);
+ admin.sendMessage("Account " + accountName + " has premium status until " + String.valueOf(format.format(endDate)) + ".");
+ }
+ else
+ {
+ admin.sendMessage("Account " + accountName + " has no premium status.");
+ }
+ }
+
+ private void removePremium(L2PcInstance admin, String accountName)
+ {
+ if (PremiumManager.getInstance().getPremiumEndDate(accountName) > 0)
+ {
+ PremiumManager.getInstance().removePremiumStatus(accountName);
+ admin.sendMessage("Account " + accountName + " has no longer premium status.");
+ }
+ else
+ {
+ admin.sendMessage("Account " + accountName + " has no premium status.");
+ }
+ }
+
+ @Override
+ public String[] getAdminCommandList()
+ {
+ return ADMIN_COMMANDS;
+ }
+}
\ No newline at end of file
diff --git dist/game/data/scripts/handlers/voicedcommandhandlers/Premium.java dist/game/data/scripts/handlers/voicedcommandhandlers/Premium.java
new file mode 100644
index 0000000..f5ae68d
--- /dev/null
+++ dist/game/data/scripts/handlers/voicedcommandhandlers/Premium.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2004-2015 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 <http://www.gnu.org/licenses/>.
+ */
+package handlers.voicedcommandhandlers;
+
+import java.text.SimpleDateFormat;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.handler.IVoicedCommandHandler;
+import com.l2jserver.gameserver.instancemanager.PremiumManager;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+
+public class Premium implements IVoicedCommandHandler
+{
+ private static final String[] VOICED_COMMANDS =
+ {
+ "premium"
+ };
+
+ @Override
+ public boolean useVoicedCommand(String command, L2PcInstance activeChar, String target)
+ {
+ if (command.startsWith("premium") && Config.PREMIUM_SYSTEM_ENABLED)
+ {
+ SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm");
+ long endDate = PremiumManager.getInstance().getPremiumEndDate(activeChar.getAccountName());
+ if (endDate == 0)
+ {
+ NpcHtmlMessage msg = new NpcHtmlMessage(5);
+ StringBuilder html = new StringBuilder("<html><body><title>Account Details</title><center>");
+ html.append("<table>");
+ html.append("<tr><td><center>Account Status: <font color=\"LEVEL\">Normal<br></font></td></tr>");
+ html.append("<tr><td>Rate XP: <font color=\"LEVEL\"> x" + Config.RATE_XP + "<br1></font></td></tr>");
+ html.append("<tr><td>Rate SP: <font color=\"LEVEL\"> x" + Config.RATE_SP + "<br1></font></td></tr>");
+ html.append("<tr><td>Drop Chance: <font color=\"LEVEL\"> x" + Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER + "<br1></font></td></tr><br>");
+ html.append("<tr><td>Drop Amount: <font color=\"LEVEL\"> x" + Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER + "<br1></font></td></tr><br>");
+ html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER + "<br1></font></td></tr><br>");
+ html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER + "<br><br></font></td></tr><br>");
+ html.append("<tr><td><center>Premium Info & Rules<br></td></tr>");
+ html.append("<tr><td>Rate XP: <font color=\"LEVEL\"> x" + (Config.RATE_XP * Config.PREMIUM_RATE_XP) + "<br1></font></td></tr>");
+ html.append("<tr><td>Rate SP: <font color=\"LEVEL\"> x" + (Config.RATE_SP * Config.PREMIUM_RATE_SP) + "<br1></font></td></tr>");
+ html.append("<tr><td>Drop Chance: <font color=\"LEVEL\"> x" + (Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_DEATH_DROP_CHANCE_MULTIPLIER) + "<br1></font></td></tr>");
+ html.append("<tr><td>Drop Amount: <font color=\"LEVEL\"> x" + (Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_DEATH_DROP_AMOUNT_MULTIPLIER) + "<br1></font></td></tr>");
+ html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + (Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_CORPSE_DROP_CHANCE_MULTIPLIER) + "<br1></font></td></tr>");
+ html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + (Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_CORPSE_DROP_AMOUNT_MULTIPLIER) + "<br1></font></td></tr>");
+ html.append("<tr><td> <font color=\"70FFCA\">1. Premium benefits CAN NOT BE TRANSFERED.<br1></font></td></tr>");
+ html.append("<tr><td> <font color=\"70FFCA\">2. Premium does not effect party members.<br1></font></td></tr>");
+ html.append("<tr><td> <font color=\"70FFCA\">3. Premium benefits effect ALL characters in same account.</font></td></tr>");
+ html.append("</table>");
+ html.append("</center></body></html>");
+ msg.setHtml(html.toString());
+ activeChar.sendPacket(msg);
+ }
+ else
+ {
+ NpcHtmlMessage msg = new NpcHtmlMessage(5);
+ StringBuilder html = new StringBuilder("<html><body><title>Premium Account Details</title><center>");
+ html.append("<table>");
+ html.append("<tr><td><center>Account Status: <font color=\"LEVEL\">Premium<br></font></td></tr>");
+ html.append("<tr><td>Rate XP: <font color=\"LEVEL\">x" + (Config.RATE_XP * Config.PREMIUM_RATE_XP) + " <br1></font></td></tr>");
+ html.append("<tr><td>Rate SP: <font color=\"LEVEL\">x" + (Config.RATE_SP * Config.PREMIUM_RATE_SP) + "  <br1></font></td></tr>");
+ html.append("<tr><td>Drop Chance: <font color=\"LEVEL\">x" + (Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_DEATH_DROP_CHANCE_MULTIPLIER) + " <br1></font></td></tr>");
+ html.append("<tr><td>Drop Amount: <font color=\"LEVEL\">x" + (Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_DEATH_DROP_AMOUNT_MULTIPLIER) + " <br1></font></td></tr>");
+ html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\">x" + (Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_CORPSE_DROP_CHANCE_MULTIPLIER) + " <br1></font></td></tr>");
+ html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\">x" + (Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_CORPSE_DROP_AMOUNT_MULTIPLIER) + " <br1></font></td></tr>");
+ html.append("<tr><td>Expires: <font color=\"00A5FF\">" + String.valueOf(format.format(endDate)) + "</font></td></tr>");
+ html.append("<tr><td>Current Date: <font color=\"70FFCA\">" + String.valueOf(format.format(System.currentTimeMillis())) + "<br><br></font></td></tr>");
+ html.append("<tr><td><center>Premium Info & Rules<br></center></td></tr>");
+ html.append("<tr><td><font color=\"70FFCA\">1. Premium accounts CAN NOT BE TRANSFERED.<br1></font></td></tr>");
+ html.append("<tr><td><font color=\"70FFCA\">2. Premium does not effect party members.<br1></font></td></tr>");
+ html.append("<tr><td><font color=\"70FFCA\">3. Premium account effects ALL characters in same account.<br><br><br></font></td></tr>");
+ html.append("<tr><td><center>Thank you for supporting our server.</td></tr>");
+ html.append("</table>");
+ html.append("</center></body></html>");
+ msg.setHtml(html.toString());
+ activeChar.sendPacket(msg);
+ }
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String[] getVoicedCommandList()
+ {
+ return VOICED_COMMANDS;
+ }
+}
\ No newline at end of file
diff --git dist/sql/game/account_premium.sql dist/sql/game/account_premium.sql
new file mode 100644
index 0000000..ce5aa62
--- /dev/null
+++ dist/sql/game/account_premium.sql
@@ -0,0 +1,7 @@
+DROP TABLE IF EXISTS `account_premium`;
+CREATE TABLE `account_premium` (
+  `account_name` varchar(45) NOT NULL DEFAULT '',
+  `premium_service` int(1) NOT NULL DEFAULT '0',
+  `enddate` decimal(20,0) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`account_name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
\ No newline at end of file
diff --git dist/tools/gs_cleanup.sql dist/tools/gs_cleanup.sql
index 7e29166..844a143 100644
--- dist/tools/gs_cleanup.sql
+++ dist/tools/gs_cleanup.sql
@@ -8,6 +8,7 @@
 
 DROP TABLE IF EXISTS
 account_gsdata,
+account_premium,
 airships,
 auction,
 auction_bid,

Creditos: NetVirus , sam.jr , Annu.
Actualizado: PoRnosJH y maneco2