diff --git a/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java b/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java
index 631c05202..223b31351 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java
@@ -7,6 +7,9 @@ import mineplex.core.common.util.NautHashMap;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
+import mineplex.core.lifetimes.Lifetime;
+import mineplex.core.lifetimes.Lifetimed;
+import mineplex.core.lifetimes.SimpleLifetime;
import mineplex.core.thread.ThreadPool;
import org.bukkit.Bukkit;
@@ -27,12 +30,16 @@ import org.bukkit.scheduler.BukkitTask;
*
* This way, we can reflectively create them during {@link #require} when they do not exist, leading to much cleaner code
*/
-public abstract class MiniPlugin implements Listener
+public abstract class MiniPlugin implements Listener, Lifetimed
{
+ // As MiniPlugins can technically be disabled at any time, each
+ // has its own unique Lifetime. If MiniPlugins are declared
+ // to never be able to be disabled, then a "Singleton" Lifetime
+ // could be shared between all of them.
+ private final SimpleLifetime _lifetime = new SimpleLifetime();
protected String _moduleName = "Default";
protected JavaPlugin _plugin;
- protected NautHashMap _commands;
-
+
protected long _initializedTime;
public MiniPlugin(String moduleName)
@@ -47,8 +54,7 @@ public abstract class MiniPlugin implements Listener
_initializedTime = System.currentTimeMillis();
- _commands = new NautHashMap<>();
-
+ _lifetime.start();
onEnable();
registerEvents(this);
@@ -146,7 +152,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
- throw new RuntimeException(exception);
+ exception.initCause(t);
+ throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
});
}
@@ -163,7 +170,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
- throw new RuntimeException(exception);
+ exception.initCause(t);
+ throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
}, time);
}
@@ -180,7 +188,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
- throw new RuntimeException(exception);
+ exception.initCause(t);
+ throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
}, time, period);
}
@@ -197,7 +206,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
- throw new RuntimeException(exception);
+ exception.initCause(t);
+ throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
});
}
@@ -214,7 +224,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
- throw new RuntimeException(exception);
+ exception.initCause(t);
+ throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
}, delay);
}
@@ -236,7 +247,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
- throw new RuntimeException(exception);
+ exception.initCause(t);
+ throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
}, delay, period);
}
@@ -250,4 +262,10 @@ public abstract class MiniPlugin implements Listener
{
return Managers.require(clazz);
}
+
+ @Override
+ public Lifetime getLifetime()
+ {
+ return _lifetime;
+ }
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java
index 7afa65772..379dc217d 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java
@@ -68,12 +68,6 @@ public class CoreClient
return _accountId;
}
- public void Delete()
- {
- _name = null;
- _player = null;
- }
-
public void setAccountId(int accountId)
{
_accountId = accountId;
@@ -214,4 +208,16 @@ public class CoreClient
return getDisguisedAs();
return getName();
}
+
+ @Override
+ public String toString()
+ {
+ return "CoreClient{" +
+ "_accountId=" + _accountId +
+ ", _name='" + _name + '\'' +
+ ", _uuid=" + _uuid +
+ ", _player=" + _player +
+ ", _rank=" + _rank +
+ '}';
+ }
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java
index d6414e463..13828828f 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java
@@ -8,6 +8,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -26,6 +27,7 @@ import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
+import com.google.common.collect.Sets;
import com.google.gson.Gson;
import mineplex.cache.player.PlayerCache;
@@ -65,17 +67,19 @@ public class CoreClientManager extends MiniPlugin
private final Rank WHITELIST_BYPASS;
- public CoreClientManager(JavaPlugin plugin, String webServer)
+ private final Set _reservedSlots = Sets.newConcurrentHashSet();
+
+ public CoreClientManager(JavaPlugin plugin)
{
- this(plugin, webServer, Rank.MODERATOR);
+ this(plugin, Rank.MODERATOR);
}
- public CoreClientManager(JavaPlugin plugin, String webServer, Rank whitelistBypass)
+ public CoreClientManager(JavaPlugin plugin, Rank whitelistBypass)
{
super("Client Manager", plugin);
_plugin = plugin;
- _repository = new AccountRepository(plugin, webServer);
+ _repository = new AccountRepository();
WHITELIST_BYPASS = whitelistBypass;
}
@@ -102,11 +106,6 @@ public class CoreClientManager extends MiniPlugin
oldClient = _clientList.put(uuid, newClient);
}
- if (oldClient != null)
- {
- oldClient.Delete();
- }
-
return newClient;
}
@@ -259,7 +258,9 @@ public class CoreClientManager extends MiniPlugin
if (uuid == null)
{
- uuid = UtilGameProfile.getProfileByName(playerName, false, profile -> {}).get().getId();
+ uuid = UtilGameProfile.getProfileByName(playerName, false, profile ->
+ {
+ }).get().getId();
}
String response = "";
@@ -481,8 +482,10 @@ public class CoreClientManager extends MiniPlugin
client.SetPlayer(event.getPlayer());
+ _reservedSlots.remove(event.getPlayer().getUniqueId());
+
// Reserved Slot Check
- if (Bukkit.getOnlinePlayers().size() >= Bukkit.getServer().getMaxPlayers())
+ if (Bukkit.getOnlinePlayers().size() + _reservedSlots.size() >= Bukkit.getServer().getMaxPlayers())
{
if (client.GetRank().has(event.getPlayer(), Rank.ULTRA, false))
{
@@ -495,6 +498,16 @@ public class CoreClientManager extends MiniPlugin
}
}
+ public void reserveFor(UUID player)
+ {
+ this._reservedSlots.add(player);
+ }
+
+ public void unreserve(UUID uuid)
+ {
+ _reservedSlots.remove(uuid);
+ }
+
@EventHandler
public void Kick(PlayerKickEvent event)
{
@@ -689,4 +702,4 @@ public class CoreClientManager extends MiniPlugin
return client.GetRank().has(rank);
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/command/TestRank.java b/Plugins/Mineplex.Core/src/mineplex/core/account/command/TestRank.java
index 9387b2cf2..e4ab7147e 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/command/TestRank.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/command/TestRank.java
@@ -7,6 +7,7 @@ import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.common.util.UtilServer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -27,10 +28,8 @@ public class TestRank extends CommandBase
UtilPlayer.message(caller, F.main("Permissions", "This requires Permission Rank [" + Rank.SNR_MODERATOR.getTag(false, true) + C.cGray + "]."));
return;
}
-
- boolean testServer = Plugin.getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
- if (!testServer)
+ if (!UtilServer.isTestServer())
{
UtilPlayer.message(caller, F.main(Plugin.getName(), F.elem("This command can only be used on test servers!")));
return;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java
index 2db750b6c..ac5d9bba0 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java
@@ -4,7 +4,6 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
-import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -13,45 +12,39 @@ import java.util.stream.Collectors;
import org.apache.commons.dbcp2.BasicDataSource;
import org.bukkit.Bukkit;
-import com.google.gson.reflect.TypeToken;
import org.bukkit.plugin.java.JavaPlugin;
+import com.google.gson.reflect.TypeToken;
+
import mineplex.cache.player.PlayerCache;
import mineplex.core.account.ILoginProcessor;
import mineplex.core.account.repository.token.LoginToken;
import mineplex.core.account.repository.token.RankUpdateToken;
import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback;
+import mineplex.core.common.util.UtilServer;
import mineplex.core.database.MinecraftRepository;
-import mineplex.core.server.remotecall.JsonWebCall;
import mineplex.serverdata.database.DBPool;
-import mineplex.serverdata.database.DatabaseRunnable;
import mineplex.serverdata.database.ResultSetCallable;
-import mineplex.serverdata.database.column.ColumnBoolean;
-import mineplex.serverdata.database.column.ColumnTimestamp;
import mineplex.serverdata.database.column.ColumnVarChar;
public class AccountRepository extends MinecraftRepository
-{
+{
private static String CREATE_ACCOUNT_TABLE = "CREATE TABLE IF NOT EXISTS accounts (id INT NOT NULL AUTO_INCREMENT, uuid VARCHAR(100), name VARCHAR(40), gems INT, rank VARCHAR(40), rankPerm BOOL, rankExpire LONG, lastLogin LONG, totalPlayTime LONG, PRIMARY KEY (id), UNIQUE INDEX uuidIndex (uuid), UNIQUE INDEX nameIndex (name), INDEX rankIndex (rank));";
- private static String ACCOUNT_LOGIN_NEW = "INSERT INTO accounts (uuid, name, lastLogin) values(?, ?, now());";
+ private static String ACCOUNT_LOGIN_NEW = "INSERT INTO accounts (uuid, name, lastLogin) values(?, ?, now());";
private static String UPDATE_ACCOUNT_RANK = "UPDATE accounts SET rank=?, rankPerm=false, rankExpire=now() + INTERVAL 1 MONTH WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_RANK_DONOR = "UPDATE accounts SET rank=?, donorRank=?, rankPerm=false, rankExpire=now() + INTERVAL 1 MONTH WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_RANK_PERM = "UPDATE accounts SET rank=?, rankPerm=true WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_RANK_DONOR_PERM = "UPDATE accounts SET rank=?, donorRank=?, rankPerm=true WHERE uuid = ?;";
-
+
private static String SELECT_ACCOUNT_UUID_BY_NAME = "SELECT uuid FROM accounts WHERE name = ? ORDER BY lastLogin DESC;";
private static String SELECT_ACCOUNT_ID_BY_UUID = "SELECT id FROM accounts WHERE accounts.uuid = ? LIMIT 1";
-
- private String _webAddress;
-
- public AccountRepository(JavaPlugin plugin, String webAddress)
+
+ public AccountRepository()
{
super(DBPool.getAccount());
-
- _webAddress = webAddress;
}
-
+
public int login(final List loginProcessors, final UUID uuid, final String name) throws SQLException
{
// First we try to grab the account id from cache - this saves an extra trip to database
@@ -105,7 +98,7 @@ public class AccountRepository extends MinecraftRepository
statement.execute(loginString);
System.out.println("EXECUTE COMPLETE - " + accountId);
-
+
statement.getUpdateCount();
statement.getMoreResults();
@@ -126,20 +119,21 @@ public class AccountRepository extends MinecraftRepository
}
}
}
-
-
+
+
return accountId;
}
public void getAccountId(UUID uuid, Callback callback)
{
- executeQuery(SELECT_ACCOUNT_ID_BY_UUID, resultSet -> {
+ executeQuery(SELECT_ACCOUNT_ID_BY_UUID, resultSet ->
+ {
int accountId = -1;
while (resultSet.next()) accountId = resultSet.getInt(1);
callback.run(accountId);
}, new ColumnVarChar("uuid", 100, uuid.toString()));
}
-
+
public String GetClient(String name, UUID uuid, String ipAddress)
{
LoginToken token = new LoginToken();
@@ -147,18 +141,18 @@ public class AccountRepository extends MinecraftRepository
token.Uuid = uuid.toString();
token.IpAddress = ipAddress;
- return new JsonWebCall(_webAddress + "PlayerAccount/Login").ExecuteReturnStream(token);
+ return handleSyncMSSQLCallStream("PlayerAccount/Login", token);
}
-
+
public String getClientByUUID(UUID uuid)
{
- return new JsonWebCall(_webAddress + "PlayerAccount/GetAccountByUUID").ExecuteReturnStream(uuid.toString());
+ return handleSyncMSSQLCallStream("PlayerAccount/GetAccountByUUID", uuid.toString());
}
public UUID getClientUUID(String name)
{
final List uuids = new ArrayList();
-
+
executeQuery(SELECT_ACCOUNT_UUID_BY_NAME, new ResultSetCallable()
{
@Override
@@ -170,20 +164,20 @@ public class AccountRepository extends MinecraftRepository
}
}
}, new ColumnVarChar("name", 100, name));
-
+
if (uuids.size() > 0)
return uuids.get(0);
else
return null;
}
-
+
public void saveRank(final Callback callback, final String name, final UUID uuid, final Rank rank, final boolean perm)
{
final RankUpdateToken token = new RankUpdateToken();
token.Name = name;
token.Rank = rank.toString();
token.Perm = perm;
-
+
final Consumer extraCallback = response ->
{
if (rank == Rank.ULTRA || rank == Rank.HERO || rank == Rank.LEGEND || rank == Rank.TITAN)
@@ -208,36 +202,23 @@ public class AccountRepository extends MinecraftRepository
executeUpdate(UPDATE_ACCOUNT_RANK, new ColumnVarChar("rank", 100, rank.toString()), new ColumnVarChar("uuid", 100, uuid.toString()));
}
- Bukkit.getServer().getScheduler().runTask(getPlugin(), new Runnable()
+ UtilServer.runSync(() ->
{
- @Override
- public void run()
- {
- if (callback != null)
- callback.run(response);
- }
+ if (callback != null)
+ callback.run(response);
});
};
handleMSSQLCall("PlayerAccount/RankUpdate", String.format("Error saving %s's rank: ", token.Name), token, Rank.class, extraCallback);
}
-
+
public void matchPlayerName(final Callback> callback, final String userName)
{
- Thread asyncThread = new Thread(new Runnable()
- {
- public void run()
- {
- List tokenList = new JsonWebCall(_webAddress + "PlayerAccount/GetMatches").Execute(new TypeToken>(){}.getType(), userName);
- callback.run(tokenList);
- }
- });
-
- asyncThread.start();
+ handleMSSQLCall("PlayerAccount/GetMatches", userName, new TypeToken>(){}.getType(), callback::run);
}
public String getClientByName(String playerName)
{
- return new JsonWebCall(_webAddress + "PlayerAccount/GetAccount").ExecuteReturnStream(playerName);
+ return handleSyncMSSQLCallStream("PlayerAccount/GetAccount", playerName);
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java
index baf39fe4e..6e987061f 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java
@@ -3,11 +3,12 @@ package mineplex.core.antihack.banwave;
import mineplex.core.common.util.Callback;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnLong;
import mineplex.serverdata.database.column.ColumnVarChar;
-public class BanWaveRepository extends MinecraftRepository
+public class BanWaveRepository extends RepositoryBase
{
private static final String INITIALIZE_PENDING_TABLE = "CREATE TABLE IF NOT EXISTS banwavePending (" +
"accountId INT(11) NOT NULL, " +
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/AnticheatDatabase.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/AnticheatDatabase.java
index d366a548a..e89dd893c 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/AnticheatDatabase.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/AnticheatDatabase.java
@@ -6,8 +6,9 @@ import java.sql.SQLException;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
-public class AnticheatDatabase extends MinecraftRepository
+public class AnticheatDatabase extends RepositoryBase
{
/*
CREATE TABLE IF NOT EXISTS anticheat_ban_metadata (id INT NOT NULL AUTO_INCREMENT, accountId INT, banId CHAR(10) NOT NULL, data MEDIUMTEXT NOT NULL, PRIMARY KEY(id));
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/AntihackLogger.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/AntihackLogger.java
index b5dafd513..3c3cc03ef 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/AntihackLogger.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/AntihackLogger.java
@@ -60,7 +60,6 @@ public class AntihackLogger extends MiniPlugin
registerMetadata(new PlayerInfoMetadata());
}
- @EventHandler
public void addCommands()
{
if (UtilServer.isTestServer())
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/builtin/PartyInfoMetadata.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/builtin/PartyInfoMetadata.java
index 9ffba8361..5b56687d8 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/builtin/PartyInfoMetadata.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/logging/builtin/PartyInfoMetadata.java
@@ -28,14 +28,14 @@ public class PartyInfoMetadata extends AnticheatMetadata
@Override
public JsonElement build(UUID player)
{
- Party party = require(PartyManager.class).getPlayerParties().get(player);
+ Party party = require(PartyManager.class).getPartyByPlayer(player);
if (party != null)
{
JsonObject partyData = new JsonObject();
- partyData.addProperty(KEY_OWNER, party.getOwner());
+ partyData.addProperty(KEY_OWNER, party.getOwnerName());
JsonArray members = new JsonArray();
- party.getMembers().forEach(m -> members.add(new JsonPrimitive(m)));
+ party.getMembers().forEach(m -> members.add(new JsonPrimitive(m.getName())));
partyData.add(KEY_MEMBERS, members);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/PlayerInputActionMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/PlayerInputActionMenu.java
index 2976e2b00..8d3dc55bf 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/PlayerInputActionMenu.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/PlayerInputActionMenu.java
@@ -34,13 +34,11 @@ public abstract class PlayerInputActionMenu implements Listener
protected Inventory _currentInventory;
protected String _itemName = "";
protected boolean _searching;
- protected Party _party;
- public PlayerInputActionMenu(MiniPlugin plugin, Player player, Party party)
+ public PlayerInputActionMenu(MiniPlugin plugin, Player player)
{
_player = player;
_plugin = plugin;
- _party = party;
player.closeInventory();
_plugin.registerEvents(this);
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/player/PlayerNameMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/player/PlayerNameMenu.java
index ab4999c54..dd6762645 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/player/PlayerNameMenu.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/player/PlayerNameMenu.java
@@ -11,8 +11,6 @@ import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
-import static net.minecraft.server.v1_8_R3.PotionBrewer.n;
-
/**
* A wrapped menu that handles looking for players specifically.
*/
@@ -21,9 +19,9 @@ public abstract class PlayerNameMenu extends PlayerInputActionMenu
protected CoreClientManager _clientManager;
- public PlayerNameMenu(MiniPlugin plugin, CoreClientManager clientManager, Player player, Party party)
+ public PlayerNameMenu(MiniPlugin plugin, CoreClientManager clientManager, Player player)
{
- super(plugin, player, party);
+ super(plugin, player);
_clientManager = clientManager;
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManagerRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManagerRepository.java
index 163648792..bcb93096c 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManagerRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManagerRepository.java
@@ -5,12 +5,13 @@ import java.sql.SQLException;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
import org.bukkit.plugin.java.JavaPlugin;
-public class BenefitManagerRepository extends MinecraftRepository
+public class BenefitManagerRepository extends RepositoryBase
{
private static String CREATE_BENEFIT_TABLE = "CREATE TABLE IF NOT EXISTS rankBenefits (id INT NOT NULL AUTO_INCREMENT, accountId INT, benefit VARCHAR(100), PRIMARY KEY (id), FOREIGN KEY (accountId) REFERENCES accounts(id));";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java
index 125fcead9..241544a1d 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java
@@ -12,6 +12,7 @@ import mineplex.core.common.Pair;
import mineplex.core.common.util.Callback;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.core.donation.DonationManager;
import mineplex.core.recharge.Recharge;
@@ -28,7 +29,7 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
-public class BonusRepository extends MinecraftRepository
+public class BonusRepository extends RepositoryBase
{
private static String CREATE_BONUS_TABLE = "CREATE TABLE IF NOT EXISTS bonus (accountId INT NOT NULL AUTO_INCREMENT, dailytime TIMESTAMP NULL DEFAULT NULL, ranktime DATE NULL DEFAULT NULL, PRIMARY KEY (accountId), FOREIGN KEY (accountId) REFERENCES accounts(id));";
private BonusManager _manager;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankRepository.java
index a8674e464..c2f02d7d3 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankRepository.java
@@ -3,13 +3,14 @@ package mineplex.core.boosters.tips;
import mineplex.core.database.MinecraftRepository;
import mineplex.database.routines.CheckAmplifierThank;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import org.bukkit.plugin.java.JavaPlugin;
/**
* @author Shaun Bennett
*/
-public class BoosterThankRepository extends MinecraftRepository
+public class BoosterThankRepository extends RepositoryBase
{
public BoosterThankRepository(JavaPlugin plugin)
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/botspam/repository/BotSpamRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/botspam/repository/BotSpamRepository.java
index 2d9c227c8..cdaede58c 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/botspam/repository/BotSpamRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/botspam/repository/BotSpamRepository.java
@@ -9,11 +9,12 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.serverdata.database.DBPool;
import mineplex.core.botspam.SpamText;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
-public class BotSpamRepository extends MinecraftRepository
+public class BotSpamRepository extends RepositoryBase
{
private static final String GET_SPAM_TEXT = "SELECT * FROM botSpam";
private static final String ADD_SPAM_TEXT = "INSERT INTO botSpam (text, createdBy, enabledBy) VALUES (?, ?, ?)";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/command/ICommand.java b/Plugins/Mineplex.Core/src/mineplex/core/command/ICommand.java
index 463a7631f..becbdfee5 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/command/ICommand.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/command/ICommand.java
@@ -5,10 +5,11 @@ import java.util.List;
import mineplex.core.common.Rank;
+import mineplex.core.lifetimes.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-public interface ICommand
+public interface ICommand extends Component
{
void SetCommandCenter(CommandCenter commandCenter);
void Execute(Player caller, String[] args);
@@ -21,4 +22,16 @@ public interface ICommand
Rank[] GetSpecificRanks();
List onTabComplete(CommandSender sender, String commandLabel, String[] args);
+
+ @Override
+ default void activate()
+ {
+ CommandCenter.Instance.addCommand(this);
+ }
+
+ @Override
+ default void deactivate()
+ {
+ CommandCenter.Instance.removeCommand(this);
+ }
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/communities/storage/CommunityRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/communities/storage/CommunityRepository.java
index 0e4844cf3..abba4f955 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/communities/storage/CommunityRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/communities/storage/CommunityRepository.java
@@ -23,11 +23,12 @@ import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.data.PlayerStatus;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnBoolean;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
-public class CommunityRepository extends MinecraftRepository
+public class CommunityRepository extends RepositoryBase
{
private static final String GET_ALL_COMMUNITIES = "SELECT * FROM communities WHERE region=?;";
private static final String GET_COMMUNITY_BY_ID = "SELECT * FROM communities WHERE id=?;";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/open/OpenBalloons.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/open/OpenBalloons.java
index ed816cf42..e34616825 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/open/OpenBalloons.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/open/OpenBalloons.java
@@ -1,9 +1,11 @@
package mineplex.core.cosmetic.ui.button.open;
-import mineplex.core.cosmetic.ui.page.BalloonsPage;
+import org.bukkit.entity.Player;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilPlayer;
import mineplex.core.cosmetic.ui.page.Menu;
import mineplex.core.gadget.types.Gadget;
-import org.bukkit.entity.Player;
public class OpenBalloons extends OpenPageButton
{
@@ -16,7 +18,8 @@ public class OpenBalloons extends OpenPageButton
@Override
protected void leftClick(Player player)
{
- getMenu().getShop().openPageForPlayer(player, new BalloonsPage(getMenu().getPlugin(), getMenu().getShop(), getMenu().getClientManager(), getMenu().getDonationManager(), "Win Effects", player));
+ UtilPlayer.message(player, F.main("Balloons", "Coming Soon!"));
+ //getMenu().getShop().openPageForPlayer(player, new BalloonsPage(getMenu().getPlugin(), getMenu().getShop(), getMenu().getClientManager(), getMenu().getDonationManager(), "Balloons", player));
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/BalloonsPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/BalloonsPage.java
index 4d7b0276c..fd0b3cf08 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/BalloonsPage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/BalloonsPage.java
@@ -31,7 +31,7 @@ public class BalloonsPage extends GadgetPage
{
addGadget(gadget, slot);
- if (getPlugin().getGadgetManager().getActive(getPlayer(), GadgetType.BALLOON) == gadget)
+ if (gadget.isActive(getPlayer()))
addGlow(slot);
slot++;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/Menu.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/Menu.java
index ef27ea645..2c77e6441 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/Menu.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/Menu.java
@@ -14,9 +14,11 @@ import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilText;
+import mineplex.core.common.util.UtilUI;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.cosmetic.ui.CosmeticShop;
import mineplex.core.cosmetic.ui.button.open.OpenArrowTrails;
+import mineplex.core.cosmetic.ui.button.open.OpenBalloons;
import mineplex.core.cosmetic.ui.button.open.OpenCostumes;
import mineplex.core.cosmetic.ui.button.open.OpenDeathAnimations;
import mineplex.core.cosmetic.ui.button.open.OpenDoubleJump;
@@ -40,6 +42,11 @@ import mineplex.core.shop.page.ShopPageBase;
public class Menu extends ShopPageBase
{
+
+ private static final String VISIBILITY_HUB = "Usable in Lobbies";
+ private static final String VISIBILITY_EVERYWHERE = "Visible Everywhere";
+ private static final String VISIBILITY_GAMES = "Visible in Games";
+
public Menu(CosmeticManager plugin, CosmeticShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player)
{
super(plugin, shop, clientManager, donationManager, "Inventory", player);
@@ -62,11 +69,11 @@ public class Menu extends ShopPageBase
addItem(4, shards);
// Cosmetic Items
-// int[] slots = UtilUI.getIndicesFor(12, 2);
- int particleSlot = 10;//slots[0];
- int arrowSlot = 12;//slots[1];
- int jumpSlot = 14;//slots[2];
- int deathSlot = 16;//slots[3];
+ int[] slots = UtilUI.getIndicesFor(15, 1, 5, 1);
+ /*int particleSlot = 9;//slots[0];
+ int arrowSlot = 11;//slots[1];
+ int jumpSlot = 13;//slots[2];
+ int deathSlot = 15;//slots[3];
int gadgetSlot = 27;//slots[4];
int morphSlot = 29;//slots[5];
int mountSlot = 31;//slots[6];
@@ -76,7 +83,12 @@ public class Menu extends ShopPageBase
int musicSlot = 47;//slots[10];
int tauntSlot = 49;//slots[11];
int winEffectSlot = 51;
- int gameModifierSlot = 53;
+ int gameModifierSlot = 53;*/
+ int particleSlot = slots[0], arrowSlot = slots[1], jumpSlot = slots[2],
+ deathSlot = slots[3], gadgetSlot = slots[4], morphSlot = slots[5],
+ mountSlot = slots[6], petSlot = slots[7], hatSlot = slots[8],
+ costumeSlot = slots[9], musicSlot = slots[10], tauntSlot = slots[11],
+ winEffectSlot = slots[12], gameModifierSlot = slots[13], balloonsSlot = slots[14];
EnumMap ownedCount = new EnumMap(GadgetType.class);
EnumMap maxCount = new EnumMap(GadgetType.class);
@@ -133,74 +145,79 @@ public class Menu extends ShopPageBase
Creature petActive = getPlugin().getPetManager().getPet(getPlayer());
GadgetType type = GadgetType.PARTICLE;
- String[] lore = getLore(ownedCount.get(type), maxCount.get(type), "Show everyone how cool you are with swirly particles that follow you when you walk!", "Visible Everywhere", enabled.get(type));
+ String[] lore = getLore(ownedCount.get(type), maxCount.get(type), "Show everyone how cool you are with swirly particles that follow you when you walk!", VISIBILITY_EVERYWHERE, enabled.get(type));
addButton(particleSlot, new ShopItem(Material.NETHER_STAR, "Particle Effects", lore, 1, false), new OpenParticles(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(particleSlot);
type = GadgetType.ARROW_TRAIL;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "Your arrows will now leave particle trails as they soar through the air.", "Visible in Games", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "Your arrows will now leave particle trails as they soar through the air.", VISIBILITY_GAMES, enabled.get(type));
addButton(arrowSlot, new ShopItem(Material.ARROW, "Arrow Effects", lore, 1, false), new OpenArrowTrails(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(arrowSlot);
type = GadgetType.DOUBLE_JUMP;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "Demonstrate your parkour prowess with sweet particles when you double jump.", "Visible Everywhere", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "Demonstrate your parkour prowess with sweet particles when you double jump.", VISIBILITY_EVERYWHERE, enabled.get(type));
addButton(jumpSlot, new ShopItem(Material.GOLD_BOOTS, "Double Jump Effects", lore, 1, false), new OpenDoubleJump(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(jumpSlot);
type = GadgetType.DEATH;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "Your death will now be mourned with a wonderful particle tribute.", "Visible in Games", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "Your death will now be mourned with a wonderful particle tribute.", VISIBILITY_GAMES, enabled.get(type));
addButton(deathSlot, new ShopItem(Material.SKULL_ITEM, "Death Animations", lore, 1, false), new OpenDeathAnimations(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(deathSlot);
type = GadgetType.ITEM;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "All sorts of zany contraptions to use on your friends and foes.", "Usable in Lobbies", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "All sorts of zany contraptions to use on your friends and foes.", VISIBILITY_HUB, enabled.get(type));
addButton(gadgetSlot, new ShopItem(Material.MELON_BLOCK, "Gadgets", lore, 1, false), new OpenGadgets(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(gadgetSlot);
type = GadgetType.MORPH;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "Have you ever wanted to be a tiger? Well, you can't be a tiger! That's silly! But you can be many other things!", "Usable in Lobbies", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "Have you ever wanted to be a tiger? Well, you can't be a tiger! That's silly! But you can be many other things!", VISIBILITY_HUB, enabled.get(type));
addButton(morphSlot, new ShopItem(Material.LEATHER, "Morphs", lore, 1, false), new OpenMorphs(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(morphSlot);
- lore = getLore(mountOwned, mountMax, "Why walk when you can ride? Summon fancy mounts to help you move in style.", "Usable in Lobbies", mountActive == null ? null : mountActive.getName());
+ lore = getLore(mountOwned, mountMax, "Why walk when you can ride? Summon fancy mounts to help you move in style.", VISIBILITY_HUB, mountActive == null ? null : mountActive.getName());
addButton(mountSlot, new ShopItem(Material.IRON_BARDING, "Mounts", lore, 1, false), new OpenMounts(this, mountActive));
if (mountActive != null) addGlow(mountSlot);
- lore = getLore(petOwned, petMax, "Life on a server can get lonely sometimes. Summon an adorable pet to follow you around and cheer you up!", "Usable in Lobbies", petActive == null ? null : petActive.getCustomName());
+ lore = getLore(petOwned, petMax, "Life on a server can get lonely sometimes. Summon an adorable pet to follow you around and cheer you up!", VISIBILITY_HUB, petActive == null ? null : petActive.getCustomName());
addButton(petSlot, new ShopItem(Material.BONE, "Pets", lore, 1, false), new OpenPets(this));
if (petActive != null) addGlow(petSlot);
type = GadgetType.HAT;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "Hats are in this year. Wear them on your head to impress the ladies.", "Usable in Lobbies", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "Hats are in this year. Wear them on your head to impress the ladies.", VISIBILITY_HUB, enabled.get(type));
addButton(hatSlot, new ShopItem(Material.GOLD_HELMET, "Hats", lore, 1, false), new OpenHats(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(hatSlot);
type = GadgetType.COSTUME;
- // Fixes more than 8 costumes being counted, even without the WindUp
- lore = getLore((ownedCount.get(type) > 8) ? 8 : ownedCount.get(type), /*maxCount.get(type)*/ 8, "Sometimes going out calls for special clothes! Gain bonus effects for matching outfit.", "Usable in Lobbies", enabled.get(type));
+ // -4 Fixes more than the real costumes being counted (Happens because of the hub games costumes
+ lore = getLore(ownedCount.get(type) - 4, maxCount.get(type) - 4, "Sometimes going out calls for special clothes! Gain bonus effects for matching outfit.", VISIBILITY_HUB, enabled.get(type));
addButton(costumeSlot, new ShopItem(Material.DIAMOND_CHESTPLATE, "Costumes", lore, 1, false), new OpenCostumes(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(costumeSlot);
type = GadgetType.MUSIC_DISC;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "I JUST WANT TO DANCE WITH YOU!", "Usable in Lobbies", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "I JUST WANT TO DANCE WITH YOU!", VISIBILITY_HUB, enabled.get(type));
addButton(musicSlot, new ShopItem(Material.GREEN_RECORD, "Music", lore, 1, false), new OpenMusic(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(musicSlot);
type = GadgetType.TAUNT;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "Taunt your enemies or just show off. Use /taunt to have a good time!", "Visible in Games", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "Taunt your enemies or just show off. Use /taunt to have a good time!", VISIBILITY_GAMES, enabled.get(type));
addButton(tauntSlot, new ShopItem(Material.NAME_TAG, "Taunts", lore, 1, false), new OpenTaunts(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(tauntSlot);
type = GadgetType.WIN_EFFECT;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "Winning a game with your friends all good and dandy, but then being able to also show off awesome effects is even more fun!", "Usable in Lobbies", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "Winning a game with your friends all good and dandy, but then being able to also show off awesome effects is even more fun!", VISIBILITY_GAMES, enabled.get(type));
addButton(winEffectSlot, new ShopItem(Material.CAKE, "Win Effects", lore, 1, false), new OpenWinEffect(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(winEffectSlot);
type = GadgetType.GAME_MODIFIER;
- lore = getLore(ownedCount.get(type), maxCount.get(type), "Cosmetic effects which changes appearances of objects in game", "Visible in Games", enabled.get(type));
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "Cosmetic effects which changes appearances of objects in game", VISIBILITY_GAMES, enabled.get(type));
addButton(gameModifierSlot, new ShopItem(Material.TORCH, "Game Modifiers", lore, 1, false), new OpenGameModifiers(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(gameModifierSlot);
+
+ type = GadgetType.BALLOON;
+ lore = getLore(ownedCount.get(type), maxCount.get(type), "Coming Soon...", VISIBILITY_HUB, enabled.get(type));
+ addButton(balloonsSlot, new ShopItem(Material.LEASH, "Balloons", lore, 1, false), new OpenBalloons(this, enabled.get(type)));
+ if (enabled.containsKey(type)) addGlow(balloonsSlot);
}
private String[] getLore(int ownedCount, int maxCount, String info, String visibility, Gadget enabled)
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/customdata/repository/CustomDataRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/customdata/repository/CustomDataRepository.java
index a26974964..2a0a1d4be 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/customdata/repository/CustomDataRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/customdata/repository/CustomDataRepository.java
@@ -14,6 +14,7 @@ import mineplex.core.customdata.CustomData;
import mineplex.core.customdata.CustomDataManager;
import mineplex.core.customdata.PlayerCustomData;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
@@ -22,7 +23,7 @@ import mineplex.serverdata.database.column.ColumnVarChar;
* Created by William (WilliamTiger).
* 16/12/15
*/
-public class CustomDataRepository extends MinecraftRepository
+public class CustomDataRepository extends RepositoryBase
{
private static final String SELECT_KEYS = "SELECT id, name FROM customData;";
private static final String INSERT_KEY = "INSERT INTO customData (name) VALUES (?);";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/database/BasicMSSQLProvider.java b/Plugins/Mineplex.Core/src/mineplex/core/database/BasicMSSQLProvider.java
new file mode 100644
index 000000000..45f4b7b03
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/database/BasicMSSQLProvider.java
@@ -0,0 +1,131 @@
+package mineplex.core.database;
+
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Consumer;
+
+import org.bukkit.scheduler.BukkitTask;
+
+import mineplex.core.common.util.UtilServer;
+import mineplex.core.server.remotecall.JsonWebCall;
+import mineplex.core.thread.ThreadPool;
+import mineplex.core.updater.UpdateType;
+import mineplex.core.utils.UtilScheduler;
+import mineplex.serverdata.database.DatabaseRunnable;
+
+@Deprecated
+public class BasicMSSQLProvider implements MSSQLProvider
+{
+ private final String _webAddress = UtilServer.getWebServerURL();
+
+ // Queue for failed processes
+ private final Object QUEUE_LOCK = new Object();
+ private Set _failedQueue = new HashSet<>();
+
+ private final BukkitTask _task;
+ private volatile boolean _shutdown = false;
+
+ public BasicMSSQLProvider()
+ {
+ _task = UtilScheduler.runEvery(UpdateType.MIN_01, this::processDatabaseQueue);
+ }
+
+ public T handleSyncMSSQLCall(String uri, Object param, Type responseType)
+ {
+ return new JsonWebCall(_webAddress + uri).Execute(responseType, param);
+ }
+
+ public String handleSyncMSSQLCallStream(String uri, Object param)
+ {
+ return new JsonWebCall(_webAddress + uri).ExecuteReturnStream(param);
+ }
+
+ public void handleMSSQLCall(String uri, String error, Object param, Class responseType, Consumer consumer)
+ {
+ handleDatabaseCall(new DatabaseRunnable(() ->
+ {
+ new JsonWebCall(_webAddress + uri).Execute(responseType, consumer::accept, param);
+ }, error));
+ }
+
+ public void handleMSSQLCall(String uri, Object param, Class responseType, Consumer consumer)
+ {
+ handleDatabaseCall(new DatabaseRunnable(() ->
+ {
+ new JsonWebCall(_webAddress + uri).Execute(responseType, consumer::accept, param);
+ }, "Handling MSSQL Call " + uri));
+ }
+
+ public void handleMSSQLCall(String uri, Object param, Type responseType, Consumer consumer)
+ {
+ handleDatabaseCall(new DatabaseRunnable(() ->
+ {
+ T t = new JsonWebCall(_webAddress + uri).Execute(responseType, param);
+ consumer.accept(t);
+ }, "Handling MSSQL Call " + uri));
+ }
+
+ public void handleMSSQLCall(String uri, Object param)
+ {
+ handleDatabaseCall(new DatabaseRunnable(() ->
+ {
+ new JsonWebCall(_webAddress + uri).Execute(param);
+ }, "Handling MSSQL Call " + uri));
+ }
+
+ @Override
+ public void deregister()
+ {
+ _shutdown = true;
+ }
+
+ private void handleDatabaseCall(DatabaseRunnable databaseRunnable)
+ {
+ ThreadPool.ASYNC.submit(() ->
+ {
+ try
+ {
+ databaseRunnable.run();
+ }
+ catch (Exception exception)
+ {
+ processFailedDatabaseCall(databaseRunnable, exception);
+ }
+ });
+ }
+
+ private void processFailedDatabaseCall(DatabaseRunnable databaseRunnable, Exception exception)
+ {
+ System.err.println(databaseRunnable.getErrorMessage());
+ exception.printStackTrace();
+
+ if (databaseRunnable.getFailedCounts() < 4)
+ {
+ databaseRunnable.incrementFailCount();
+
+ synchronized (QUEUE_LOCK)
+ {
+ _failedQueue.add(databaseRunnable);
+ }
+ }
+ }
+
+ private void processDatabaseQueue()
+ {
+ Set clone;
+
+ synchronized (QUEUE_LOCK)
+ {
+ clone = new HashSet<>(_failedQueue);
+ _failedQueue.clear();
+ }
+
+ clone.forEach(this::handleDatabaseCall);
+
+ if (_shutdown && _failedQueue.isEmpty())
+ {
+ _task.cancel();
+ }
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/database/MSSQLProvider.java b/Plugins/Mineplex.Core/src/mineplex/core/database/MSSQLProvider.java
new file mode 100644
index 000000000..e3f5c35a9
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/database/MSSQLProvider.java
@@ -0,0 +1,22 @@
+package mineplex.core.database;
+
+import java.lang.reflect.Type;
+import java.util.function.Consumer;
+
+@Deprecated
+public interface MSSQLProvider
+{
+ T handleSyncMSSQLCall(String uri, Object param, Type responseType);
+
+ String handleSyncMSSQLCallStream(String uri, Object param);
+
+ void handleMSSQLCall(String uri, String error, Object param, Class responseType, Consumer consumer);
+
+ void handleMSSQLCall(String uri, Object param, Class responseType, Consumer consumer);
+
+ void handleMSSQLCall(String uri, Object param, Type responseType, Consumer consumer);
+
+ void handleMSSQLCall(String uri, Object param);
+
+ void deregister();
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/database/MinecraftRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/database/MinecraftRepository.java
index 22523a1a8..60a8d39c3 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/database/MinecraftRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/database/MinecraftRepository.java
@@ -1,136 +1,69 @@
package mineplex.core.database;
-import java.util.HashSet;
-import java.util.Set;
+import javax.sql.DataSource;
+import java.lang.reflect.Type;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
-import javax.rmi.CORBA.Util;
-import javax.sql.DataSource;
-
-import mineplex.core.common.util.UtilServer;
-import mineplex.core.server.remotecall.AsyncJsonWebCall;
-import mineplex.core.server.remotecall.JsonWebCall;
-import mineplex.core.thread.ThreadPool;
-import mineplex.core.utils.UtilScheduler;
-import mineplex.serverdata.database.DBPool;
-import mineplex.serverdata.database.DatabaseRunnable;
-import mineplex.serverdata.database.RepositoryBase;
-import mineplex.core.updater.UpdateType;
-
+import org.bukkit.event.Listener;
import org.jooq.DSLContext;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
-import org.bukkit.event.Listener;
-import org.bukkit.plugin.java.JavaPlugin;
+import mineplex.core.common.util.UtilServer;
+import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
+/**
+ * Do not extend this class unless you are doing MSSQL calls (which you shouldn't be)
+ *
+ * @deprecated don't use mssql thx
+ */
+@Deprecated
public abstract class MinecraftRepository extends RepositoryBase implements Listener
{
- // Queue for failed processes
- private final Object QUEUE_LOCK = new Object();
- private Set _failedQueue = new HashSet<>();
+ private static AtomicReference PROVIDER = new AtomicReference<>(new BasicMSSQLProvider());
- protected JavaPlugin _plugin; // Plugin responsible for this repository
+ public static void setMSSQLProvider(MSSQLProvider provider)
+ {
+ MSSQLProvider oldProvider = PROVIDER.getAndSet(provider);
+ oldProvider.deregister();
+ }
- private final String _webAddress = UtilServer.getWebServerURL();
-
- /**
- * Constructor
- *
- * @param dataSource - the {@link DataSource} responsible for providing the connection pool to this repository.
- */
public MinecraftRepository(DataSource dataSource)
{
super(dataSource);
- _plugin = UtilServer.getPlugin();
-
UtilServer.RegisterEvents(this);
-
- UtilScheduler.runEvery(UpdateType.MIN_01, this::processDatabaseQueue);
}
- protected DSLContext jooq()
+ protected T handleSyncMSSQLCall(String uri, Object param, Type responseType)
{
- return DSL.using(DBPool.getAccount(), SQLDialect.MYSQL);
+ return PROVIDER.get().handleSyncMSSQLCall(uri, param, responseType);
+ }
+
+ protected String handleSyncMSSQLCallStream(String uri, Object param)
+ {
+ return PROVIDER.get().handleSyncMSSQLCallStream(uri, param);
}
- /**
- * One day, the stars will align, and we can get rid of this
- */
- @Deprecated
protected void handleMSSQLCall(String uri, String error, Object param, Class responseType, Consumer consumer)
{
- handleDatabaseCall(new DatabaseRunnable(() ->
- {
- new JsonWebCall(_webAddress + uri).Execute(responseType, consumer::accept, param);
- }, error));
+ PROVIDER.get().handleMSSQLCall(uri, error, param, responseType, consumer);
}
- /**
- * One day, the stars will align, and we can get rid of this
- */
- @Deprecated
- protected void handleAsyncMSSQLCall(String uri, Object param, Class responseType, Consumer consumer)
+ protected void handleMSSQLCall(String uri, Object param, Class responseType, Consumer consumer)
{
- new AsyncJsonWebCall(_webAddress + uri).Execute(responseType, consumer::accept, param);
+ PROVIDER.get().handleMSSQLCall(uri, param, responseType, consumer);
+ }
+
+ protected void handleMSSQLCall(String uri, Object param, Type responseType, Consumer consumer)
+ {
+ PROVIDER.get().handleMSSQLCall(uri, param, responseType, consumer);
}
- /**
- * One day, the stars will align, and we can get rid of this
- */
- @Deprecated
protected void handleAsyncMSSQLCall(String uri, Object param)
{
- new AsyncJsonWebCall(_webAddress + uri).Execute(param);
- }
-
- private void handleDatabaseCall(DatabaseRunnable databaseRunnable)
- {
- ThreadPool.ASYNC.submit(() ->
- {
- try
- {
- databaseRunnable.run();
- }
- catch (Exception exception)
- {
- processFailedDatabaseCall(databaseRunnable, exception);
- }
- });
- }
-
- private void processFailedDatabaseCall(DatabaseRunnable databaseRunnable, Exception exception)
- {
- System.err.println(databaseRunnable.getErrorMessage());
- exception.printStackTrace();
-
- if (databaseRunnable.getFailedCounts() < 4)
- {
- databaseRunnable.incrementFailCount();
-
- synchronized (QUEUE_LOCK)
- {
- _failedQueue.add(databaseRunnable);
- }
- }
- }
-
- private void processDatabaseQueue()
- {
- Set clone;
-
- synchronized (QUEUE_LOCK)
- {
- clone = new HashSet<>(_failedQueue);
- _failedQueue.clear();
- }
-
- clone.forEach(this::handleDatabaseCall);
- }
-
- public JavaPlugin getPlugin()
- {
- return _plugin;
+ PROVIDER.get().handleMSSQLCall(uri, param);
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/donation/repository/DonationRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/donation/repository/DonationRepository.java
index 6363d018b..834d6cb10 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/donation/repository/DonationRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/donation/repository/DonationRepository.java
@@ -11,13 +11,8 @@ import mineplex.core.database.MinecraftRepository;
import mineplex.core.donation.repository.token.GemRewardToken;
import mineplex.core.donation.repository.token.PurchaseToken;
import mineplex.core.donation.repository.token.UnknownPurchaseToken;
-import mineplex.core.server.remotecall.AsyncJsonWebCall;
-import mineplex.core.server.remotecall.JsonWebCall;
import mineplex.core.server.util.TransactionResponse;
import mineplex.serverdata.database.DBPool;
-import mineplex.serverdata.database.DatabaseRunnable;
-
-import org.bukkit.plugin.java.JavaPlugin;
public class DonationRepository extends MinecraftRepository
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRepository.java
index 7f622784e..5d8617a4a 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRepository.java
@@ -9,10 +9,12 @@ import java.util.LinkedList;
import java.util.List;
import mineplex.core.common.util.Callback;
+import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnLong;
@@ -22,7 +24,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import com.google.common.collect.Lists;
-public class EloRepository extends MinecraftRepository
+public class EloRepository extends RepositoryBase
{
private static String INSERT_ELO = "INSERT INTO eloRating (accountId, gameType, elo) VALUES (?, ?, ?);";
@@ -43,7 +45,7 @@ public class EloRepository extends MinecraftRepository
public boolean saveElo(int accountId, int gameType, int oldElo, int elo) throws SQLException
{
List ret = Lists.newArrayList();
- Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> {
+ UtilServer.runAsync(() -> {
boolean updateSucceeded = false;
// If we're increasing in elo we verify the server version matches the database version (prevent d/c and double wins with concurrent matches)
@@ -60,7 +62,7 @@ public class EloRepository extends MinecraftRepository
updateSucceeded = true;
}
}
-
+
ret.add(updateSucceeded);
});
@@ -86,14 +88,14 @@ public class EloRepository extends MinecraftRepository
public void getStrikeExpiry(int accountId, Callback call)
{
- Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeQuery(GRAB_STRIKE_EXPIRY, resultSet -> {
+ UtilServer.runAsync(() -> executeQuery(GRAB_STRIKE_EXPIRY, resultSet -> {
boolean called = false;
while (resultSet.next())
{
called = true;
call.run(resultSet.getLong(1));
}
-
+
if (!called)
{
call.run(0L);
@@ -103,21 +105,21 @@ public class EloRepository extends MinecraftRepository
public void getBanExpiryAsync(int accountId, Callback call)
{
- Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeQuery(GRAB_BAN_EXPIRY, resultSet -> {
+ UtilServer.runAsync(() -> executeQuery(GRAB_BAN_EXPIRY, resultSet -> {
boolean called = false;
while (resultSet.next())
{
called = true;
call.run(resultSet.getLong(1));
}
-
+
if (!called)
{
call.run(0L);
}
}, new ColumnInt("accountId", accountId)));
}
-
+
public long getBanExpiry(int accountId)
{
List expiry = new ArrayList();
@@ -127,23 +129,23 @@ public class EloRepository extends MinecraftRepository
expiry.add(resultSet.getLong(1));
}
}, new ColumnInt("accountId", accountId));
-
+
if (expiry.isEmpty())
expiry.add(System.currentTimeMillis() - 5000);
-
+
return expiry.get(0);
}
public void getStrikes(int accountId, Callback call)
{
- Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeQuery(GRAB_STRIKES, resultSet -> {
+ UtilServer.runAsync(() -> executeQuery(GRAB_STRIKES, resultSet -> {
boolean called = false;
while (resultSet.next())
{
called = true;
call.run(resultSet.getInt(1));
}
-
+
if (!called)
{
call.run(0);
@@ -188,14 +190,14 @@ public class EloRepository extends MinecraftRepository
long banEnd = System.currentTimeMillis() + UtilTime.convert(minutes, TimeUnit.MINUTES, TimeUnit.MILLISECONDS);
long strikesExpire = System.currentTimeMillis() + UtilTime.convert(1, TimeUnit.DAYS, TimeUnit.MILLISECONDS);
int newStrikes = Math.min(strikes + 1, 8);
-
- Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeUpdate(UPDATE_BAN, new ColumnInt("accountId", accountId), new ColumnInt("strikes", newStrikes), new ColumnLong("strikesExpire", strikesExpire), new ColumnLong("banEnd", banEnd)));
+
+ UtilServer.runAsync(() -> executeUpdate(UPDATE_BAN, new ColumnInt("accountId", accountId), new ColumnInt("strikes", newStrikes), new ColumnLong("strikesExpire", strikesExpire), new ColumnLong("banEnd", banEnd)));
});
}
public void resetStrikes(int accountId)
{
- Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeUpdate(DELETE_STRIKES, new ColumnInt("accountId", accountId)));
+ UtilServer.runAsync(() -> executeUpdate(DELETE_STRIKES, new ColumnInt("accountId", accountId)));
}
public void getTopElo(int limit, Callback> callback)
@@ -255,6 +257,6 @@ public class EloRepository extends MinecraftRepository
}
}
}
- }.runTaskAsynchronously(_plugin);
+ }.runTaskAsynchronously(UtilServer.getPlugin());
}
}
\ No newline at end of file
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/facebook/FacebookRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/facebook/FacebookRepository.java
index 1a9f32c25..19674d595 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/facebook/FacebookRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/facebook/FacebookRepository.java
@@ -8,11 +8,12 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.util.Callback;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
-public class FacebookRepository extends MinecraftRepository
+public class FacebookRepository extends RepositoryBase
{
private static final String GET_CODE = "SELECT code, activated FROM facebook WHERE code = ?";
private static final String ACTIVATE_CODE = "UPDATE facebook SET activated = 1, accountId = ?, activationTime = NOW() WHERE code = ?";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java
index 12432b50e..c2bc5b608 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java
@@ -15,6 +15,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.util.NautHashMap;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnVarChar;
import mineplex.core.friend.FriendStatusType;
@@ -24,7 +25,7 @@ import mineplex.serverdata.data.PlayerStatus;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ServerManager;
-public class FriendRepository extends MinecraftRepository
+public class FriendRepository extends RepositoryBase
{
private static String CREATE_FRIEND_TABLE = "CREATE TABLE IF NOT EXISTS accountFriend (id INT NOT NULL AUTO_INCREMENT, uuidSource VARCHAR(100), uuidTarget VARCHAR(100), status VARCHAR(100), PRIMARY KEY (id), UNIQUE INDEX uuidIndex (uuidSource, uuidTarget));";
private static String RETRIEVE_MULTIPLE_FRIEND_RECORDS = "SELECT uuidSource, tA.Name, status, tA.lastLogin, now(), uuidTarget FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget WHERE uuidSource IN ";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/friend/ui/FriendsGUI.java b/Plugins/Mineplex.Core/src/mineplex/core/friend/ui/FriendsGUI.java
index 0fa3e4051..c94c5ff98 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/friend/ui/FriendsGUI.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/friend/ui/FriendsGUI.java
@@ -34,6 +34,7 @@ import mineplex.core.friend.data.FriendData;
import mineplex.core.friend.data.FriendStatus;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.itemstack.ItemLayout;
+import mineplex.core.portal.Intent;
import mineplex.core.shop.item.IButton;
public class FriendsGUI implements Listener
@@ -302,7 +303,7 @@ public class FriendsGUI implements Listener
@Override
public void onClick(Player player, ClickType clickType)
{
- _plugin.getPortal().sendPlayerToServer(player, serverName);
+ _plugin.getPortal().sendPlayerToServer(player, serverName, Intent.PLAYER_REQUEST);
}
});
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java
index bb0c257d6..ced422b4f 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java
@@ -57,6 +57,7 @@ import mineplex.core.gadget.gadgets.arrowtrail.shadow.ArrowTrailShadow;
import mineplex.core.gadget.gadgets.arrowtrail.titan.ArrowTrailTitan;
import mineplex.core.gadget.gadgets.arrowtrail.vampire.ArrowTrailBlood;
import mineplex.core.gadget.gadgets.arrowtrail.wisdom.ArrowTrailEnchant;
+import mineplex.core.gadget.gadgets.balloons.BalloonType;
import mineplex.core.gadget.gadgets.death.candycane.DeathCandyCane;
import mineplex.core.gadget.gadgets.death.christmas.DeathPresentDanger;
import mineplex.core.gadget.gadgets.death.cupidslove.DeathCupidsBrokenHeart;
@@ -198,6 +199,7 @@ import mineplex.core.gadget.set.suits.SetFreezeSuit;
import mineplex.core.gadget.set.suits.SetRaveSuit;
import mineplex.core.gadget.set.suits.SetSpaceSuit;
import mineplex.core.gadget.types.ArrowEffectGadget;
+import mineplex.core.gadget.types.BalloonGadget;
import mineplex.core.gadget.types.DeathEffectGadget;
import mineplex.core.gadget.types.DoubleJumpEffectGadget;
import mineplex.core.gadget.types.Gadget;
@@ -502,7 +504,7 @@ public class GadgetManager extends MiniPlugin
// Game Modifiers
// MineStrike
- addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.P250_Muertos, -2));
+ /*addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.P250_Muertos, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.CZ75_Auto_Tigris, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Desert_Eagle_Blaze, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Nova_Koi, -2));
@@ -513,6 +515,7 @@ public class GadgetManager extends MiniPlugin
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.AWP_Asiimov, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Knife_M9_Bayonette_Fade, -2));
+ addGadget(new GameModifierMineStrikeSkin(this, ));
//Blue only
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.P2000_Fire_Elemental, -2));
@@ -523,7 +526,11 @@ public class GadgetManager extends MiniPlugin
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Glock_18_Fade, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Galil_AR_Eco, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.AK_47_Vulcan, -2));
- addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.SG553_Pulse, -2));
+ addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.SG553_Pulse, -2));*/
+ for (MineStrikeSkin mineStrikeSkin : MineStrikeSkin.values())
+ {
+ addGadget(new GameModifierMineStrikeSkin(this, mineStrikeSkin, -2));
+ }
// Survival Games
@@ -532,8 +539,12 @@ public class GadgetManager extends MiniPlugin
addGadget(new KitGameModifier(this, kitModifier));
}*/
+ // ONLY NEXT WEEK!
// Balloons
- //addGadget(new BabyCowBalloon(this));
+ /*for (BalloonType balloonType : BalloonType.values())
+ {
+ addGadget(new BalloonItem(this, balloonType));
+ }*/
// TAUNTS!!!
addGadget(new EternalTaunt(this));
@@ -709,6 +720,20 @@ public class GadgetManager extends MiniPlugin
}
return null;
}
+
+ public BalloonGadget getBalloonGadget(BalloonType balloonType)
+ {
+ for (Gadget gadget : getGadgets(GadgetType.BALLOON))
+ {
+ if (gadget instanceof BalloonGadget)
+ {
+ BalloonGadget balloonGadget = (BalloonGadget) gadget;
+ if (balloonGadget.getBalloonType().equals(balloonType))
+ return balloonGadget;
+ }
+ }
+ return null;
+ }
// Disallows two armor gadgets in same slot.
public void removeOutfit(Player player, ArmorSlot slot)
@@ -1322,4 +1347,5 @@ public class GadgetManager extends MiniPlugin
taunt.start(player);
}
+
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/commands/UnlockCosmeticsCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/commands/UnlockCosmeticsCommand.java
index 18afaab78..0da39bfe2 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/commands/UnlockCosmeticsCommand.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/commands/UnlockCosmeticsCommand.java
@@ -22,7 +22,7 @@ public class UnlockCosmeticsCommand extends CommandBase
public UnlockCosmeticsCommand(GadgetManager plugin)
{
- super(plugin, Rank.JNR_DEV, "unlockCosmetics");
+ super(plugin, Rank.SNR_MODERATOR, "unlockCosmetics");
_plugin = plugin;
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/balloons/BabyCowBalloon.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/balloons/BabyCowBalloon.java
deleted file mode 100644
index 4b1e7e23f..000000000
--- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/balloons/BabyCowBalloon.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package mineplex.core.gadget.gadgets.balloons;
-
-import mineplex.core.common.util.UtilEnt;
-import mineplex.core.gadget.GadgetManager;
-import mineplex.core.gadget.types.BalloonGadget;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.entity.*;
-
-public class BabyCowBalloon extends BalloonGadget
-{
-
- private ArmorStand _entityStand, _playerStand;
- private Entity _balloonEntity;
-
- public BabyCowBalloon(GadgetManager manager)
- {
- super(manager, "Baby Cow Balloon", new String[]{"placeholder"}, 0, Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.COW));
- }
-
- @Override
- public void enableCustom(Player player, boolean message)
- {
- if (!canSpawnBalloon(player))
- {
- // TODO MESSAGE
- return;
- }
- addPlayerBalloon(player);
- _entityStand = player.getWorld().spawn(player.getLocation(), ArmorStand.class);
- _entityStand.setGravity(false);
- _entityStand.setVisible(false);
- Cow babyCow = player.getWorld().spawn(player.getLocation(), Cow.class);
- babyCow.setBaby();
- _balloonEntity = babyCow;
- _entityStand.setPassenger(babyCow);
- Location balloonLocation = player.getLocation().add(_random.nextDouble(), getNewHeight(player), _random.nextDouble());
- _entityStand.teleport(balloonLocation);
- babyCow.setLeashHolder(player);
- // TODO UPDATE BALLOONS
- }
-
- @Override
- public void disableCustom(Player player, boolean message)
- {
- _entityStand.remove();
- _balloonEntity.remove();
- removePlayerBalloon(player);
- // TODO UPDATE PLAYER HEIGHT
- }
-
-}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/balloons/BalloonItem.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/balloons/BalloonItem.java
new file mode 100644
index 000000000..24c92c722
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/balloons/BalloonItem.java
@@ -0,0 +1,92 @@
+package mineplex.core.gadget.gadgets.balloons;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.bukkit.entity.Ageable;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Zombie;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+import mineplex.core.common.util.UtilEnt;
+import mineplex.core.gadget.GadgetManager;
+import mineplex.core.gadget.types.BalloonGadget;
+
+public class BalloonItem extends BalloonGadget
+{
+
+ private BalloonType _balloonType;
+ private Map> _entities = new HashMap<>();
+
+ public BalloonItem(GadgetManager manager, BalloonType balloonType)
+ {
+ super(manager, balloonType.getName(), balloonType.getLore(), balloonType.getCost(),
+ balloonType.getDisplayItem().getType(),
+ balloonType.getDisplayItem().getData().getData(), balloonType,
+ balloonType.getEntityType());
+ setDisplayItem(balloonType.getDisplayItem());
+ _balloonType = balloonType;
+ }
+
+ @Override
+ public Entity[] spawnEntity(Player player)
+ {
+ Entity[] ents = new Entity[2];
+ if (_balloonType.getEntityType().equals(EntityType.ARMOR_STAND))
+ {
+ Zombie zombie = player.getWorld().spawn(player.getLocation(), Zombie.class);
+ zombie.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 1, false, false));
+ zombie.getEquipment().setHelmet(_balloonType.getDisplayItem());
+ UtilEnt.silence(zombie, true);
+ UtilEnt.vegetate(zombie);
+ addEntity(player, zombie);
+
+ ents[0] = zombie;
+
+ return ents;
+ }
+ else if (_balloonType.equals(BalloonType.BABY_ZOMBIE))
+ {
+ Zombie zombie = player.getWorld().spawn(player.getLocation(), Zombie.class);
+ zombie.setBaby(true);
+ UtilEnt.vegetate(zombie);
+ addEntity(player, zombie);
+ ents[0] = zombie;
+ return ents;
+ }
+
+
+ Entity entity = player.getWorld().spawnEntity(player.getLocation(), _balloonType.getEntityType());
+ if (_balloonType.isBaby() && entity instanceof Ageable)
+ ((Ageable) entity).setBaby();
+ UtilEnt.vegetate(entity);
+ addEntity(player, entity);
+ ents[0] = entity;
+ return ents;
+ }
+
+ private void addEntity(Player player, Entity entity)
+ {
+ _entities.computeIfAbsent(player.getUniqueId(), list -> new ArrayList<>());
+ List entities = _entities.get(player.getUniqueId());
+ entities.add(entity);
+ _entities.put(player.getUniqueId(), entities);
+ }
+
+ @Override
+ public void removeEntities(Player player)
+ {
+ for (Entity entity : _entities.get(player.getUniqueId()))
+ {
+ entity.remove();
+ }
+ _entities.remove(player.getUniqueId());
+ }
+
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/balloons/BalloonType.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/balloons/BalloonType.java
new file mode 100644
index 000000000..1fbf94fc2
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/balloons/BalloonType.java
@@ -0,0 +1,95 @@
+package mineplex.core.gadget.gadgets.balloons;
+
+import org.bukkit.Material;
+import org.bukkit.entity.EntityType;
+import org.bukkit.inventory.ItemStack;
+
+import mineplex.core.common.util.C;
+import mineplex.core.common.util.LineFormat;
+import mineplex.core.common.util.UtilText;
+
+public enum BalloonType
+{
+
+ // BABY
+ BABY_COW (EntityType.COW, true, "Baby Cow Balloon", 0, new ItemStack(Material.COOKED_BEEF)),
+ BABY_PIG (EntityType.PIG, true, "Baby Pig Balloon", 0, new ItemStack(Material.GRILLED_PORK)),
+ BABY_ZOMBIE (EntityType.ZOMBIE, true, "Baby Zombie Balloon", 0, new ItemStack(Material.ROTTEN_FLESH)),
+ BABY_MUSHROOM(EntityType.MUSHROOM_COW, true, "Baby Mushroom Cow Balloon", 0, new ItemStack(Material.MUSHROOM_SOUP)),
+ BABY_OCELOT (EntityType.OCELOT, true, "Baby Ocelot Balloon", 0, new ItemStack(Material.COOKED_FISH)),
+ BABY_WOLF (EntityType.WOLF, true, "Baby Wolf Balloon", 0, new ItemStack(Material.BONE)),
+ BABY_SHEEP (EntityType.SHEEP, true, "Baby Sheep Balloon", 0, new ItemStack(Material.WOOL)),
+ BABY_VILLAGER(EntityType.VILLAGER, true, "Baby Villager Balloon", 0, new ItemStack(Material.EMERALD)),
+ BABY_SLIME (EntityType.SLIME, true, "Baby Slime Balloon", 0, new ItemStack(Material.SLIME_BALL)),
+
+ // NOT BABY
+ SQUID (EntityType.SQUID, "Squid Balloon", 0, new ItemStack(Material.INK_SACK)),
+ BAT (EntityType.BAT, "Bat Balloon", 0, new ItemStack(Material.JACK_O_LANTERN)),
+ SILVERFISH(EntityType.SILVERFISH, "Silverfish Balloon", 0, new ItemStack(Material.getMaterial(97))),
+ GUARDIAN (EntityType.GUARDIAN, "Guardian Balloon", 0, new ItemStack(Material.PRISMARINE_SHARD)),
+
+ // BLOCK
+ /*DRAGON_EGG (new ItemStack(Material.DRAGON_EGG), false, "Dragon Egg Balloon", UtilText.splitLinesToArray(new String[]{"Placeholder"}, LineFormat.LORE), 0),
+ DIAMOND_BLOCK(new ItemStack(Material.DIAMOND_BLOCK), false, "Diamond Block Balloon", UtilText.splitLinesToArray(new String[]{"Placeholder"}, LineFormat.LORE), 0),
+ IRON_BLOCK (new ItemStack(Material.IRON_BLOCK), false, "Iron Block Balloon", UtilText.splitLinesToArray(new String[]{"Placeholder"}, LineFormat.LORE), 0),
+ GOLD_BLOCK (new ItemStack(Material.GOLD_BLOCK), false, "Gold Block Balloon", UtilText.splitLinesToArray(new String[]{"Placeholder"}, LineFormat.LORE), 0),*/
+ EMERALD_BLOCK(new ItemStack(Material.EMERALD_BLOCK), false, "Emerald Block Balloon", 0);
+
+ private EntityType _entityType;
+ private boolean _isBaby;
+ private String _name;
+ private String[] _lore;
+ private int _cost;
+ private ItemStack _displayItem;
+
+ BalloonType(EntityType entityType, String name, int cost, ItemStack displayItem)
+ {
+ this(entityType, false, name, cost, displayItem);
+ }
+
+ BalloonType(EntityType entityType, boolean isBaby, String name, int cost, ItemStack displayItem)
+ {
+ _entityType = entityType;
+ _isBaby = isBaby;
+ _name = name;
+ _cost = cost;
+ _displayItem = displayItem;
+ }
+
+ BalloonType(ItemStack block, boolean isBaby, String name, int cost)
+ {
+ this(EntityType.ARMOR_STAND, isBaby, name, cost, block);
+ }
+
+ public EntityType getEntityType()
+ {
+ return _entityType;
+ }
+
+ public boolean isBaby()
+ {
+ return _isBaby;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String[] getLore()
+ {
+ return UtilText.splitLinesToArray(new String[]{C.cGray + "A floating " + getName() + " that appears above your head!",
+ "",
+ C.cWhite + "Click to activate, click again to remove. You can have up to 10 balloons active at a time."}, LineFormat.LORE);
+ }
+
+ public int getCost()
+ {
+ return _cost;
+ }
+
+ public ItemStack getDisplayItem()
+ {
+ return _displayItem;
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/minestrike/GameModifierMineStrikeSkin.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/minestrike/GameModifierMineStrikeSkin.java
index a9f2ebcaf..e54903c2d 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/minestrike/GameModifierMineStrikeSkin.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/minestrike/GameModifierMineStrikeSkin.java
@@ -51,7 +51,7 @@ public class GameModifierMineStrikeSkin extends GameModifierGadget
*/
public GameModifierMineStrikeSkin(GadgetManager manager, MineStrikeSkin skin, int cost)
{
- this(manager, skin, new String[]{""}, cost);
+ this(manager, skin, new String[]{skin.getWeaponName()}, cost);
}
/**
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/minestrike/MineStrikeSkin.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/minestrike/MineStrikeSkin.java
index 1b118c120..14b21a559 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/minestrike/MineStrikeSkin.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/minestrike/MineStrikeSkin.java
@@ -5,25 +5,33 @@ import org.bukkit.Material;
public enum MineStrikeSkin
{
- P250_Muertos( "P250", "P250 Muertos", Material.INK_SACK, (byte) 3),
- CZ75_Auto_Tigris( "CZ75-Auto", "CZ75-Auto Tigris", Material.CLAY_BRICK, (byte) 0),
- Desert_Eagle_Blaze( "Desert Eagle", "Desert Eagle Blaze", Material.NETHER_STALK, (byte) 0),
- Nova_Koi( "Nova", "Nova Koi", Material.INK_SACK, (byte) 14),
- XM1014_Tranquility( "XM1014", "XM1014 Tranquility", Material.DIAMOND, (byte) 0),
- PP_Bizon_Streak( "PP Bizon", "PP-Bizon Streak", Material.INK_SACK, (byte) 4),
- P90_Asiimov( "P90", "P90 Asiimov", Material.INK_SACK, (byte) 0),
- SSG_08_Blood_in_the_Water( "SSG 08", "SSG 08 Blood in the Water", Material.INK_SACK, (byte) 12),
- AWP_Asiimov( "AWP", "AWP Asiimov", Material.SULPHUR, (byte) 0),
- P2000_Fire_Elemental( "P2000", "P2000 Fire Elemental", Material.INK_SACK, (byte) 6),
- FAMAS_Pulse( "FAMAS", "FAMAS Pulse", Material.CLAY_BALL, (byte) 0),
- M4A4_Howl( "M4A4", "M4A4 Howl", Material.INK_SACK, (byte) 11),
- Steyr_AUG_Torque( "Steyr AUG", "Steyr AUG Torque", Material.BLAZE_ROD, (byte) 0),
- Glock_18_Fade( "Glock 18", "Glock 18 Fade", Material.INK_SACK, (byte) 9),
- Galil_AR_Eco( "Galil AR", "Galil AR Eco", Material.INK_SACK, (byte) 10),
- AK_47_Vulcan( "AK-47", "AK-47 Vulcan", Material.INK_SACK, (byte) 7),
- SG553_Pulse( "SG553", "SG553 Pulse", Material.INK_SACK, (byte) 5),
+ P250_Muertos( "P250", "P250 Muertos", Material.INK_SACK, (byte) 3),
+ CZ75_Auto_Tigris( "CZ75-Auto", "CZ75-Auto Tigris", Material.CLAY_BRICK, (byte) 0),
+ Desert_Eagle_Blaze( "Desert Eagle", "Desert Eagle Blaze", Material.NETHER_STALK, (byte) 0),
+ Desert_Eagle_Golden_Gun( "Desert Eagle", "Golden Gun", Material.GLOWSTONE_DUST, (byte) 0),
+ Nova_Koi( "Nova", "Nova Koi", Material.INK_SACK, (byte) 14),
+ XM1014_Tranquility( "XM1014", "XM1014 Tranquility", Material.DIAMOND, (byte) 0),
+ XM1014_Pig_Gun( "XM1014", "XM1014 Pig Gun", Material.LEATHER, (byte) 0),
+ PP_Bizon_Streak( "PP Bizon", "PP-Bizon Streak", Material.INK_SACK, (byte) 4),
+ P90_Asiimov( "P90", "P90 Asiimov", Material.INK_SACK, (byte) 0),
+ SSG_08_Blood_in_the_Water( "SSG 08", "SSG 08 Blood in the Water", Material.INK_SACK, (byte) 12),
+ AWP_Asiimov( "AWP", "AWP Asiimov", Material.SULPHUR, (byte) 0),
+ P2000_Fire_Elemental( "P2000", "P2000 Fire Elemental", Material.INK_SACK, (byte) 6),
+ FAMAS_Pulse( "FAMAS", "FAMAS Pulse", Material.CLAY_BALL, (byte) 0),
+ M4A4_Howl( "M4A4", "M4A4 Howl", Material.INK_SACK, (byte) 11),
+ //M4A4_Enderman( "M4A4", "Enderman M4", )
+ Steyr_AUG_Torque( "Steyr AUG", "Steyr AUG Torque", Material.BLAZE_ROD, (byte) 0),
+ Glock_18_Fade( "Glock 18", "Glock 18 Fade", Material.INK_SACK, (byte) 9),
+ Galil_AR_Eco( "Galil AR", "Galil AR Eco", Material.INK_SACK, (byte) 10),
+ AK_47_Vulcan( "AK-47", "AK-47 Vulcan", Material.INK_SACK, (byte) 7),
+ AK_47_Guardian( "AK-47", "Guardian AK", Material.PRISMARINE_SHARD, (byte) 0),
+ SG553_Pulse( "SG553", "SG553 Pulse", Material.INK_SACK, (byte) 5),
+
- Knife_M9_Bayonette_Fade( "Knife", "M9 Bayonette Fade", Material.DIAMOND_SWORD, (byte) 0);
+ Knife_M9_Bayonette_Fade( "Knife", "M9 Bayonette Fade", Material.DIAMOND_SWORD, (byte) 0),
+ Knife_Counter_Terrorist_Sword("Knife", "Counter Terrorist Sword", Material.STICK, (byte) 0),
+ Knife_Terrorist_Sword( "Knife", "Terrorist Sword", Material.FEATHER, (byte) 0),
+ Knife_M9_Bayonette_Glass( "Knife", "Glass M9 Bayonette", Material.QUARTZ, (byte) 0);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/item/ItemFootball.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/item/ItemFootball.java
index a405ea02c..06a4178ff 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/item/ItemFootball.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/item/ItemFootball.java
@@ -51,7 +51,7 @@ public class ItemFootball extends ItemGadget
FallingBlock ball = player.getWorld().spawnFallingBlock(player.getLocation().add(0, 1, 0), Material.SKULL, (byte) 3);
Bat bat = player.getWorld().spawn(player.getLocation(), Bat.class);
- UtilEnt.Vegetate(bat);
+ UtilEnt.vegetate(bat);
UtilEnt.ghost(bat, true, true);
UtilEnt.silence(bat, true);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/WinEffectHalloween.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/WinEffectHalloween.java
index 49aaa7bbe..821a9daff 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/WinEffectHalloween.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/wineffect/WinEffectHalloween.java
@@ -134,7 +134,7 @@ public class WinEffectHalloween extends WinEffectGadget
skeleton.setCustomNameVisible(true);
skeleton.getEquipment().setHelmet(new ItemStack(Material.JACK_O_LANTERN));
UtilEnt.ghost(skeleton, true, false);
- UtilEnt.Vegetate(skeleton);
+ UtilEnt.vegetate(skeleton);
for (int i = 0; i < 15; i++)
{
playFirework(skeleton.getLocation().clone().add(0, 2, 0), i, true);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/BalloonGadget.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/BalloonGadget.java
index 721282b33..980c43fd2 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/BalloonGadget.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/BalloonGadget.java
@@ -1,64 +1,138 @@
package mineplex.core.gadget.types;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
-import mineplex.core.gadget.GadgetManager;
import org.bukkit.Material;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.gadget.GadgetManager;
+import mineplex.core.gadget.gadgets.balloons.BalloonType;
+import mineplex.core.gadget.util.BalloonData;
+import mineplex.core.updater.UpdateType;
+import mineplex.core.updater.event.UpdateEvent;
public abstract class BalloonGadget extends Gadget
{
- protected static final Map> PLAYER_BALLOONS = new HashMap<>();
+ private static final Map> PLAYER_BALLOONS = new HashMap<>();
- protected final Random _random;
+ private EntityType _balloon;
+ private BalloonType _balloonType;
- public BalloonGadget(GadgetManager manager, String name, String[] desc, int cost, Material material, byte data, String... altNames)
+ public BalloonGadget(GadgetManager manager, String name, String[] desc, int cost, Material material, byte data, BalloonType balloonType, EntityType balloon, String... altNames)
{
super(manager, GadgetType.BALLOON, name, desc, cost, material, data, 1, altNames);
- _random = new Random();
+ _balloon = balloon;
+ _balloonType = balloonType;
}
- protected boolean canSpawnBalloon(Player player)
+ @Override
+ public void enableCustom(Player player, boolean message)
+ {
+ boolean add = addPlayerBalloon(player);
+ if (add)
+ {
+ _active.add(player);
+ if (message)
+ {
+ UtilPlayer.message(player, F.main("Gadget", "You spawned a " + F.elem(getName()) + "!"));
+ }
+ }
+ else
+ {
+ Manager.removeActive(player, this);
+ UtilPlayer.message(player, F.main("Gadget", "You cannot have more than " + F.count("10") + " balloons!"));
+ }
+ }
+
+ @Override
+ public void disableCustom(Player player, boolean message)
+ {
+ if (!_active.remove(player))
+ return;
+
+ removePlayerBalloon(player);
+ if (message)
+ UtilPlayer.message(player, F.main("Gadget", "You despawned a " + F.elem(getName())) + "!");
+ }
+
+ private boolean addPlayerBalloon(Player player)
+ {
+ if (!canSpawnBalloon(player))
+ return false;
+
+ PLAYER_BALLOONS.computeIfAbsent(player.getUniqueId(), map -> new HashMap<>());
+ BalloonData balloonData;
+ Entity[] ents = spawnEntity(player);
+ if (ents[1] == null)
+ balloonData = new BalloonData(player, ents[0]);
+ else if (!_balloon.equals(EntityType.ARMOR_STAND))
+ balloonData = new BalloonData(player, ents[0], ents[1]);
+ else
+ {
+ balloonData = new BalloonData(player, ents[0]);
+ balloonData.setLeash(ents[1]);
+ }
+ PLAYER_BALLOONS.get(player.getUniqueId()).put(_balloon, balloonData);
+
+ return true;
+ }
+
+ private void removePlayerBalloon(Player player)
{
if (PLAYER_BALLOONS.containsKey(player.getUniqueId()))
{
- List balloonGadgets = PLAYER_BALLOONS.get(player.getUniqueId());
+ if (PLAYER_BALLOONS.get(player.getUniqueId()).containsKey(_balloon))
+ {
+ removeEntities(player);
+ PLAYER_BALLOONS.get(player.getUniqueId()).remove(_balloon);
+ }
+ }
+ }
+
+ protected abstract Entity[] spawnEntity(Player player);
+
+ protected abstract void removeEntities(Player player);
+
+ @EventHandler
+ public void onUpdate(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.TICK)
+ return;
+
+ for (Map.Entry> entry : PLAYER_BALLOONS.entrySet())
+ {
+ for (BalloonData balloonData : entry.getValue().values())
+ {
+ balloonData.update();
+ }
+ }
+ }
+
+ private boolean canSpawnBalloon(Player player)
+ {
+ if (PLAYER_BALLOONS.containsKey(player.getUniqueId()))
+ {
+ Map balloonGadgets = PLAYER_BALLOONS.get(player.getUniqueId());
return balloonGadgets.size() < 10;
}
return true;
}
- protected void addPlayerBalloon(Player player)
+ public BalloonType getBalloonType()
{
- if (canSpawnBalloon(player))
- {
- PLAYER_BALLOONS.computeIfAbsent(player.getUniqueId(), list -> new ArrayList<>());
- List balloonGadgets = PLAYER_BALLOONS.get(player.getUniqueId());
- balloonGadgets.add(this);
- PLAYER_BALLOONS.put(player.getUniqueId(), balloonGadgets);
- }
+ return _balloonType;
}
- protected void removePlayerBalloon(Player player)
+ public static int getBalloons(Player player)
{
- List balloonGadgets = PLAYER_BALLOONS.computeIfPresent(player.getUniqueId(), (uuid, list) -> list);
- if (balloonGadgets.contains(this))
- {
- balloonGadgets.remove(this);
- }
- if (balloonGadgets.size() >= 1)
- PLAYER_BALLOONS.put(player.getUniqueId(), balloonGadgets);
- else
- PLAYER_BALLOONS.remove(player.getUniqueId());
+ return ((PLAYER_BALLOONS.containsKey(player.getUniqueId())) ? PLAYER_BALLOONS.get(player.getUniqueId()).size() : 0);
}
-
- protected double getNewHeight(Player player)
- {
- List balloonGadgets = PLAYER_BALLOONS.computeIfPresent(player.getUniqueId(), (uuid, list) -> list);
- if (balloonGadgets != null)
- return balloonGadgets.size() * _random.nextDouble() * (_random.nextInt(1) + 2);
- return 3;
- }
-
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/util/BalloonData.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/util/BalloonData.java
new file mode 100644
index 000000000..da817f426
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/util/BalloonData.java
@@ -0,0 +1,133 @@
+package mineplex.core.gadget.util;
+
+import org.bukkit.Location;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilMath;
+
+public class BalloonData
+{
+
+ /**
+ * Makes the balloons fly around the player
+ * Copied from {@link mineplex.core.gadget.gadgets.particle.ParticleFairyData}
+ */
+
+ private Player _player;
+ private Entity _balloon, _passenger, _leash;
+ private Location _balloonLoc, _target;
+ private Vector _direction;
+ private double _speed;
+ private long _idleTime;
+
+ public BalloonData(Player player, Entity balloon)
+ {
+ _player = player;
+ _balloon = balloon;
+ _balloonLoc = player.getEyeLocation();
+ _target = getNewTarget();
+ _speed = 0.2;
+ _idleTime = 0;
+ _direction = new Vector(1, 0, 0);
+ ((LivingEntity) _balloon).setLeashHolder(_player);
+ }
+
+ // This exists for a possible widder balloon that could be added later
+ public BalloonData(Player player, Entity balloon, Entity passenger)
+ {
+ _player = player;
+ _balloon = balloon;
+ _passenger = passenger;
+ _balloonLoc = player.getEyeLocation();
+ _target = getNewTarget();
+ _speed = 0.2;
+ _idleTime = 0;
+ _direction = new Vector(1, 0, 0);
+ ((LivingEntity) _balloon).setLeashHolder(_player);
+ }
+
+ public void update()
+ {
+ if (_leash == null)
+ {
+ if (!((LivingEntity) _balloon).isLeashed())
+ ((LivingEntity) _balloon).setLeashHolder(_player);
+ }
+ else
+ {
+ if (!((LivingEntity) _leash).isLeashed())
+ ((LivingEntity) _leash).setLeashHolder(_player);
+ }
+
+ //Update Target
+ if (UtilMath.offset(_player.getEyeLocation(), _target) > 3 || UtilMath.offset(_balloonLoc, _target) < 1)
+ _target = getNewTarget();
+
+ //Pause?
+ if (Math.random() > 0.98)
+ _idleTime = System.currentTimeMillis() + (long)(Math.random() * 3000);
+
+ //Speed
+ if (UtilMath.offset(_player.getEyeLocation(), _balloonLoc) < 3)
+ {
+ if (_idleTime > System.currentTimeMillis())
+ {
+ _speed = Math.max(0, _speed - 0.005);
+ }
+ else
+ {
+ _speed = Math.min(0.15, _speed + 0.005);
+ }
+ }
+ else
+ {
+ _idleTime = 0;
+
+ _speed = Math.min(0.15 + UtilMath.offset(_player.getEyeLocation(), _balloonLoc) * 0.05, _speed + 0.02);
+ }
+
+
+ //Modify Direction
+ _direction.add(UtilAlg.getTrajectory(_balloonLoc, _target).multiply(0.15));
+ if (_direction.length() < 1)
+ _speed = _speed * _direction.length();
+ UtilAlg.Normalize(_direction);
+
+ //Move
+ if (UtilMath.offset(_balloonLoc, _target) > 0.1)
+ _balloonLoc.add(_direction.clone().multiply(_speed));
+
+ _balloon.teleport(_balloonLoc);
+ _balloon.setVelocity(new Vector(0, .25, 0));
+ if (_passenger != null)
+ {
+ _passenger.teleport(_balloonLoc);
+ _balloon.setPassenger(_passenger);
+ }
+ if (_leash != null)
+ {
+ _leash.teleport(_balloon.getLocation().add(0, 1.5, 0));
+ }
+ }
+
+ private Location getNewTarget()
+ {
+ return _player.getEyeLocation().add(Math.random() * 6 - 3, Math.random() * 7.5, Math.random() * 6 - 3);
+ }
+
+ public Entity getBalloon()
+ {
+ return _balloon;
+ }
+
+ public void setLeash(Entity leashedEntity)
+ {
+ _leash = leashedEntity;
+ ((LivingEntity) _leash).setLeashHolder(_player);
+ }
+
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java b/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java
index 585e37864..cc5ba27d4 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java
@@ -96,6 +96,8 @@ public enum GameDisplay
Basketball("Hoops", Material.SLIME_BALL, (byte)0, GameCategory.EXTRA, 63, false),
QuiverPayload("One in the Quiver Payload", Material.ARROW, (byte)0, GameCategory.ARCADE, 64, false),
+
+ StrikeGames("Strike Games", Material.DIAMOND_LEGGINGS, (byte) 0, GameCategory.SURVIVAL, 66, false),
Event("Mineplex Event", Material.CAKE, (byte)0, GameCategory.EVENT, 999, false),
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/giveaway/GiveawayRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/giveaway/GiveawayRepository.java
index 01b07bc7e..a88efc3fd 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/giveaway/GiveawayRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/giveaway/GiveawayRepository.java
@@ -12,12 +12,13 @@ import mineplex.core.database.MinecraftRepository;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
import mineplex.serverdata.Region;
-public class GiveawayRepository extends MinecraftRepository
+public class GiveawayRepository extends RepositoryBase
{
private static final String INSERT_GIVEAWAY = "INSERT INTO Account.accountGiveaway (giveawayId, accountId, cooldownId, region, serverName, time, uuid) VALUES (?, ?, ?, ?, ?, now(), ?)";
private static final String LOAD_GIVEAWAY = "SELECT id, name, prettyName, header, message, max, notifyNetwork, notifyCooldown, canWinTwice FROM Account.giveaway WHERE enabled = TRUE";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/ignore/data/IgnoreRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/ignore/data/IgnoreRepository.java
index 14ea9c2e5..d69fa55b1 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/ignore/data/IgnoreRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/ignore/data/IgnoreRepository.java
@@ -5,12 +5,13 @@ import java.sql.SQLException;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnVarChar;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
-public class IgnoreRepository extends MinecraftRepository
+public class IgnoreRepository extends RepositoryBase
{
private static String ADD_IGNORE_RECORD = "INSERT INTO accountIgnore (uuidIgnorer, uuidIgnored) SELECT fA.uuid AS uuidIgnorer, tA.uuid AS uuidIgnored FROM accounts as fA LEFT JOIN accounts AS tA ON tA.name = ? WHERE fA.name = ?;";
private static String DELETE_IGNORE_RECORD = "DELETE aF FROM accountIgnore AS aF INNER JOIN accounts as fA ON aF.uuidIgnorer = fA.uuid INNER JOIN accounts AS tA ON aF.uuidIgnored = tA.uuid WHERE fA.name = ? AND tA.name = ?;";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/incognito/repository/IncognitoRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/incognito/repository/IncognitoRepository.java
index fbb8243b7..adebcf4cf 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/incognito/repository/IncognitoRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/incognito/repository/IncognitoRepository.java
@@ -3,9 +3,10 @@ package mineplex.core.incognito.repository;
import mineplex.core.database.MinecraftRepository;
import mineplex.core.incognito.IncognitoManager;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
-public class IncognitoRepository extends MinecraftRepository
+public class IncognitoRepository extends RepositoryBase
{
private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS incognitoStaff (accountId INT NOT NULL, status TINYINT(1) DEFAULT '0', PRIMARY KEY (accountId));";
private static final String INSERT_STATUS = "INSERT INTO incognitoStaff (accountId, status) VALUES (?, ?);";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/inventory/data/InventoryRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/inventory/data/InventoryRepository.java
index b679ab62c..6bf7de0f5 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/inventory/data/InventoryRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/inventory/data/InventoryRepository.java
@@ -10,13 +10,14 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.util.NautHashMap;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
import mineplex.core.inventory.ClientInventory;
import mineplex.core.inventory.ClientItem;
-public class InventoryRepository extends MinecraftRepository
+public class InventoryRepository extends RepositoryBase
{
private static String CREATE_INVENTORY_TABLE = "CREATE TABLE IF NOT EXISTS items (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(100), rarity INT, PRIMARY KEY (id), INDEX mameIndex (name));";
private static String CREATE_INVENTORY_RELATION_TABLE = "CREATE TABLE IF NOT EXISTS accountInventory (id INT NOT NULL AUTO_INCREMENT, accountId INT NOT NULL, itemId INT NOT NULL, count INT NOT NULL, PRIMARY KEY (id), FOREIGN KEY (accountId) REFERENCES accounts(id), FOREIGN KEY (itemId) REFERENCES items(id), UNIQUE INDEX accountItemIndex (accountId, itemId));";
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatEventsRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatEventsRepository.java
index c4b129df4..3acf6a2f8 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatEventsRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/leaderboard/StatEventsRepository.java
@@ -2,6 +2,7 @@ package mineplex.core.leaderboard;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
@@ -15,7 +16,7 @@ import org.bukkit.plugin.java.JavaPlugin;
* @author MrTwiggy
*
*/
-public class StatEventsRepository extends MinecraftRepository
+public class StatEventsRepository extends RepositoryBase
{
// Insert or update stat events query
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/Component.java b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/Component.java
new file mode 100644
index 000000000..cee7da78f
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/Component.java
@@ -0,0 +1,21 @@
+package mineplex.core.lifetimes;
+
+/**
+ * A Component defines behavior that can exist within a Lifetime. Components
+ * should have no impact upon the game while not active.
+ */
+public interface Component
+{
+ /**
+ * Activates the Component, performing any sort of required initialization.
+ * Components may be activated and deactivated multiple times, however a component
+ * will not be activated more than once without subsequent calls to deactivate.
+ */
+ void activate();
+
+ /**
+ * Deactivates the Component, disabling any sort of functionality it provides
+ * and performing clean up. A Component may be subsequently reactivated.
+ */
+ void deactivate();
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/Lifetime.java b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/Lifetime.java
new file mode 100644
index 000000000..1cb578bc0
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/Lifetime.java
@@ -0,0 +1,29 @@
+package mineplex.core.lifetimes;
+
+/**
+ * A Lifetime represents a duration for which a collection of Components
+ * will be active. While Lifetime does contain a method for registering
+ * instantiated Components, individual Lifetimes may have unique
+ * strategies for creating Components and activating them. Lifetime
+ * doesn't provide any guarantee of Component activation or deactivation
+ * order. Implementations of Lifetime, however, may.
+ *
+ * Lifetime doesn't provide mechanisms for beginning or ending a Lifetime.
+ * This is provided by the various implementations of Lifetime, as it varies
+ * between the implementations and is functionality that most consumers of
+ * Lifetimes will not need.
+ */
+public interface Lifetime
+{
+ /**
+ * Registers the provided component with this Lifetime. If the Lifetime
+ * is currently active, then the Component will be immediately activated.
+ * @param component the component to register
+ */
+ void register(Component component);
+ /**
+ * Gets whether the Lifetime is currently active.
+ * @return true if the Lifetime is active
+ */
+ boolean isActive();
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/Lifetimed.java b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/Lifetimed.java
new file mode 100644
index 000000000..fa08dd533
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/Lifetimed.java
@@ -0,0 +1,19 @@
+package mineplex.core.lifetimes;
+
+/**
+ * Represents an object that is associated with a specific lifetime.
+ * Multiple Lifetimed objects may be associated with the same Lifetime.
+ * As a roughly generalized explanation, any time functionality should
+ * be enabled(whether its a command, listener, etc.) it should be registered
+ * as a Component of a Lifetime. Any object wishing to enable functionality
+ * that is associated with this Lifetimed object should do so with the Lifetime
+ * returned by {@link #getLifetime()}.
+ */
+public interface Lifetimed
+{
+ /**
+ * Gets the Lifetime associated with this Lifetimed object.
+ * @return non-null Lifetime
+ */
+ Lifetime getLifetime();
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/ListenerComponent.java b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/ListenerComponent.java
new file mode 100644
index 000000000..d6b664fb4
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/ListenerComponent.java
@@ -0,0 +1,54 @@
+package mineplex.core.lifetimes;
+
+import mineplex.core.common.util.UtilServer;
+import org.apache.commons.lang.Validate;
+import org.bukkit.Bukkit;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.Listener;
+
+/**
+ * A convenience class for Components that are a Listener. ListenerComponent
+ * can either be used as a wrapper class for a specific Listener, or can be
+ * extended by another Component to provide event registration.
+ */
+public class ListenerComponent implements Component, Listener
+{
+ private final Listener _listener;
+
+ /**
+ * Creates a ListenerComponent that registers the provided Listener when
+ * activated and unregisters it when deactivated. The newly created
+ * ListenerComponent will not be registered as a Listener. When a
+ * ListenerComponent is created with this constructor, it is effectively
+ * a wrapper to bind a Listener to a specific lifetime.
+ *
+ * @param listener non-null listener to wrap
+ * @throws IllegalArgumentException if listener is null
+ */
+ public ListenerComponent(Listener listener) throws IllegalArgumentException
+ {
+ Validate.notNull(listener);
+ _listener = listener;
+ }
+
+ /**
+ * Creates a ListenerComponent that registers itself when activated and
+ * unregisters itself when deactivated.
+ */
+ public ListenerComponent()
+ {
+ _listener = this;
+ }
+
+ @Override
+ public void activate()
+ {
+ Bukkit.getPluginManager().registerEvents(_listener, UtilServer.getPlugin());
+ }
+
+ @Override
+ public void deactivate()
+ {
+ HandlerList.unregisterAll(_listener);
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/PhasedComponent.java b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/PhasedComponent.java
new file mode 100644
index 000000000..417bf56b1
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/PhasedComponent.java
@@ -0,0 +1,7 @@
+package mineplex.core.lifetimes;
+
+public interface PhasedComponent extends Component
+{
+
+ void setPhase(T phase);
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/PhasedLifetime.java b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/PhasedLifetime.java
new file mode 100644
index 000000000..b9760e761
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/PhasedLifetime.java
@@ -0,0 +1,289 @@
+package mineplex.core.lifetimes;
+
+import com.google.common.base.Preconditions;
+import mineplex.core.common.util.UtilServer;
+import org.apache.commons.lang.Validate;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A PhasedLifetime is a lifetime that is composed of several
+ * smaller lifetimes, referred to as phases. This class is provided
+ * in order to support a system in which Components may exist within multiple
+ * Lifetimes. PhasedLifetime is not thread-safe.
+ *
+ * Registering a Component will register it for the entirety of this Lifetime,
+ * unless registered with {@link #register(Component, Iterable)}. Special behavior
+ * is provided for instances of {@link PhasedComponent}. See {@link #register(Component,
+ * Iterable)} for more information. Components registered using {@link
+ * #register(Component)} are registered for the entire duration of the Lifetime.
+ */
+public class PhasedLifetime implements Lifetime
+{
+ private final Map> _phases = new HashMap<>();
+ private final List _global = new ArrayList<>();
+ private boolean _active = false;
+ private T _current;
+
+ /**
+ * Registers the Component for all phases within the provided Iterable,
+ * and creates a Lifetime that is active during all those phases, and
+ * therefore identical to when the provided Component is active. If a change
+ * occurs from a Phase that the Component is active in to another phase that
+ * the component is active in, it will not be disabled. When this
+ * Lifetime ends, all Lifetimes created by this Lifetime also end, as all
+ * phases are considered over.
+ *
+ * If the Component is an instance of PhasedComponent, then any phase change
+ * in which one of the phases is within the provided Iterable of phases will
+ * result in an invocation of {@link PhasedComponent#setPhase(Object)}. This
+ * should not be used as a mechanism to detect when the component is being
+ * disabled, but rather as a means to provide specific behavior when that
+ * phase change occurs. If a phase change drastically changes the behavior
+ * of a Component such that not all functionality is active for some phases
+ * that a Component is registered for, you should consider refactoring that
+ * Component into two separate Components.
+ *
+ * As an example, assume that we have a PhasedLifetime with phases A-F,
+ * and a PhasedComponent is registered for phases A, B, and E. The chain
+ * of events would be as followed(italic indicates an event call to the
+ * PhasedComponent, an activation, or deactivation).
+ *
+ * - Lifetime started with a value of A
+ * - Component is activated
+ * - setPhase is called with a value of A
+ * - Phase is set to B
+ * - setPhase is called with a value of B
+ * - Phase is set to C
+ * - setPhase is called with a value of C
+ * - Component is deactivated
+ * - Phase is set to D
+ * - Phase is set to E
+ * - Component is activated
+ * - setPhase is called with a value of E
+ * - Phase is set to F
+ * - setPhase is called with a value of F
+ * - Component is deactivated
+ * - Lifetime ends
+ *
+ *
+ * If phases contains no elements, then the Component will not be
+ * registered.
+ * @param component non-null Component being registered
+ * @param phases non-null Iterable of phases to register the Component for
+ * @return a Lifetime corresponding to when the Component is active
+ * @throws IllegalArgumentException if component or phases is null
+ */
+ public Lifetime register(Component component, Iterable phases) throws IllegalArgumentException {
+ Validate.notNull(component, "Component cannot be null");
+ Validate.notNull(phases, "Phases cannot be null");
+ RegisteredComponent rComponent = new RegisteredComponent(component);
+ for (T phase : phases)
+ {
+ _phases.computeIfAbsent(phase, (p) -> new ArrayList<>()).add(rComponent);
+ if (Objects.equals(phase, _current))
+ {
+ rComponent.start();
+ if (component instanceof PhasedComponent)
+ {
+ ((PhasedComponent) component).setPhase(phase);
+ }
+ }
+ }
+ return rComponent;
+ }
+
+ /**
+ * Starts the Lifetime, activating all components that are active for
+ * the entire lifetime, and then activating all components that are part
+ * of the provided phase.
+ * @param phase non-null phase to start
+ * @throws IllegalArgumentException if phase is null
+ * @throws IllegalStateException if the Lifetime is currently active
+ */
+ public void start(T phase) throws IllegalArgumentException, IllegalStateException
+ {
+ Validate.notNull(phase, "phase cannot be null");
+ Preconditions.checkState(!_active, "Lifetime already started");
+ _active = true;
+ _global.forEach(PhasedLifetime::active);
+ setPhase(phase);
+ }
+
+ /**
+ * Ends the Lifetime, deactivating all components in the current phase
+ * and then deactivating all components that are active for the entire Lifetime.
+ * A Lifetime may be subsequently reactivated after it has ended.
+ * @throws IllegalStateException if the lifetime isn't active
+ */
+ public void end() throws IllegalStateException
+ {
+ Preconditions.checkState(_active, "Lifetime not active");
+ List toDisable = _phases.get(getPhase());
+ if (toDisable != null)
+ {
+ toDisable.forEach(RegisteredComponent::end);
+ }
+ _global.forEach(PhasedLifetime::deactive);
+ _active = false;
+ _current = null;
+ }
+
+ /**
+ * Sets the current phase to the provided value, activating components
+ * that are active in the phase and not currently active, and deactiving
+ * components that were previously active and are not registered for the
+ * provided phase.
+ * @param phase non-null
+ * @throws IllegalStateException if the Lifetime isn't active
+ * @throws IllegalArgumentException if the phase equals the current phase
+ * or is null
+ */
+ public void setPhase(T phase) throws IllegalStateException, IllegalArgumentException
+ {
+ Preconditions.checkState(_active, "Lifetime not active");
+ Validate.isTrue(!Objects.equals(phase, _current), "Can't set the phase to the current phase");
+ Validate.notNull(phase, "the phase cannot be null");
+ T oldPhase = getPhase();
+ _current = phase;
+ List old = _phases.get(oldPhase);
+ List nextPhase = _phases.get(phase);
+
+ for (Component c : _global)
+ {
+ if (c instanceof PhasedComponent)
+ {
+ ((PhasedComponent) c).setPhase(phase);
+ }
+ }
+ // Disable components that were active in the last phase but not in the next phase.
+ if (old != null)
+ {
+ List toDisable = new ArrayList<>();
+ toDisable.addAll(old);
+ // Components that are in the next phase shouldn't be disabled.
+ if (nextPhase != null)
+ {
+ toDisable.removeAll(nextPhase);
+ }
+
+ // Ensure that all old ones get a setPhase call before disabling them.
+ for (RegisteredComponent r : toDisable)
+ {
+ if (r.getComponent() instanceof PhasedComponent)
+ {
+ ((PhasedComponent) r.getComponent()).setPhase(phase);
+ }
+ }
+ toDisable.forEach(RegisteredComponent::end);
+ }
+ if (nextPhase != null)
+ {
+ // New but not old
+ List toActivate = new ArrayList<>();
+ toActivate.addAll(nextPhase);
+ // Ensure that all components from last phase don't end up getting activated again.
+ if (old != null)
+ {
+ toActivate.removeAll(old);
+ }
+ // Start all the new ones
+ toActivate.forEach(RegisteredComponent::start);
+ // Give every remaining component a call to setPhase
+ for (RegisteredComponent r : nextPhase)
+ {
+ if (r.getComponent() instanceof PhasedComponent)
+ {
+ ((PhasedComponent) r.getComponent()).setPhase(phase);
+ }
+ }
+ }
+ }
+
+ private static void active(Component component)
+ {
+ try
+ {
+ component.activate();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ UtilServer.getPlugin().getLogger().severe("Failed to activate component: " + component);
+ }
+ }
+ private static void deactive(Component component)
+ {
+ try
+ {
+ component.deactivate();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ UtilServer.getPlugin().getLogger().severe("Failed to deactivate component: " + component);
+ }
+ }
+ /**
+ * Gets the current Phase. If this PhasedLifetime isn't active then
+ * the current phase is null.
+ * @return the current phase, null if not active
+ */
+ public T getPhase()
+ {
+ return _current;
+ }
+
+ /**
+ * {@inheritDoc}
+ * If the Component is an instance of PhasedComponent, it will receive
+ * notifications of phase changes prior to any components registered
+ * with specific phases. Global components will also be deactivated last.
+ * @param component the component to register
+ */
+ @Override
+ public void register(Component component)
+ {
+ _global.add(component);
+ if (this.isActive())
+ {
+ component.activate();
+ }
+ }
+
+ @Override
+ public boolean isActive()
+ {
+ return _active;
+ }
+
+ private static class RegisteredComponent extends SimpleLifetime implements Lifetime {
+ private Component _component;
+
+ public RegisteredComponent(Component component)
+ {
+ this._component = component;
+ }
+
+ public Component getComponent()
+ {
+ return _component;
+ }
+
+ @Override
+ public void start() throws IllegalStateException
+ {
+ PhasedLifetime.active(_component);
+ super.start();
+ }
+
+ @Override
+ public void end() throws IllegalStateException
+ {
+ super.end();
+ PhasedLifetime.deactive(_component);
+ }
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/SimpleLifetime.java b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/SimpleLifetime.java
new file mode 100644
index 000000000..28dcfe45e
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/lifetimes/SimpleLifetime.java
@@ -0,0 +1,96 @@
+package mineplex.core.lifetimes;
+
+import mineplex.core.common.util.UtilServer;
+import org.apache.commons.lang3.Validate;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * A Lifetime that is not thread-safe and is essentially a list of Components.
+ * All components are activated in the order that they are registered. All
+ * components are deactivated in the reverse order that they are registered.
+ * Components may not be registered during invocations of start or end. If a
+ * Component throws an exception during activation it will be logged, however the
+ * Component will still only be disabled once all other Components are disabled.
+ */
+public class SimpleLifetime implements Lifetime
+{
+ protected final List _components = new ArrayList<>();
+ protected boolean _active = false;
+ @Override
+ public void register(Component component)
+ {
+ this._components.add(component);
+ if (this.isActive())
+ {
+ try
+ {
+ component.activate();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ UtilServer.getPlugin().getLogger().severe("Failed to active component: " + component);
+ }
+ }
+ }
+
+ @Override
+ public boolean isActive()
+ {
+ return _active;
+ }
+
+ /**
+ * Starts the SimpleLifetime, activating all components in the order that
+ * they were registered. A SimpleLifetime may be started multiple times,
+ * so long that every invocation of start after the first is preceded by
+ * an invocation of {@link #end()}. If a Component throws an exception
+ * during activation the exception will be logged, however no specific
+ * error-handling mechanism is provided. The Component will still be
+ * considered active and will be deactivated with all other Components.
+ * @throws IllegalStateException if currently active
+ */
+ public void start() throws IllegalStateException
+ {
+ Validate.isTrue(!_active);
+ _active = true;
+ for (Component component : _components)
+ {
+ try
+ {
+ component.activate();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ UtilServer.getPlugin().getLogger().severe("Failed to active component: " + component);
+ }
+ }
+ }
+
+ /**
+ * Deactivates all components in the reverse order that they were registered.
+ * Any exception thrown by a Component while being deactivated will be logged,
+ * however no exception handling mechanism is provided.
+ * @throws IllegalStateException if not currently active
+ */
+ public void end() throws IllegalStateException
+ {
+ Validate.isTrue(_active);
+ _active = false;
+ ListIterator reverseIterator = _components.listIterator(_components.size());
+ while (reverseIterator.hasPrevious())
+ {
+ Component component = reverseIterator.previous();
+ try
+ {
+ component.deactivate();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ UtilServer.getPlugin().getLogger().severe("Failed to deactivate component: " + component);
+ }
+ }
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/mavericks/DisplaySlot.java b/Plugins/Mineplex.Core/src/mineplex/core/mavericks/DisplaySlot.java
index 8e38983f6..35f605f3f 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/mavericks/DisplaySlot.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/mavericks/DisplaySlot.java
@@ -86,7 +86,7 @@ public class DisplaySlot
}
else
{
- UtilEnt.Vegetate(e, true);
+ UtilEnt.vegetate(e, true);
UtilEnt.ghost(e, true, false);
}
_pastedEntities.add(e);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/menu/builtin/ButtonOpenAnvilInput.java b/Plugins/Mineplex.Core/src/mineplex/core/menu/builtin/ButtonOpenAnvilInput.java
new file mode 100644
index 000000000..393f5d60e
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/menu/builtin/ButtonOpenAnvilInput.java
@@ -0,0 +1,28 @@
+package mineplex.core.menu.builtin;
+
+import java.util.function.Supplier;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.ClickType;
+import org.bukkit.inventory.ItemStack;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.menu.Button;
+import mineplex.core.menu.Menu;
+
+public abstract class ButtonOpenAnvilInput extends Button
+{
+ private final Supplier