diff --git a/Plugins/Mineplex.Bungee.Mineplexer/pom.xml b/Plugins/Mineplex.Bungee.Mineplexer/pom.xml
index b32fcf94a..4b46f2b44 100644
--- a/Plugins/Mineplex.Bungee.Mineplexer/pom.xml
+++ b/Plugins/Mineplex.Bungee.Mineplexer/pom.xml
@@ -28,10 +28,6 @@
commons-codec
commons-codec
-
- net.kencochrane.raven
- raven
-
net.md-5
bungeecord-proxy
diff --git a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/Mineplexer.java b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/Mineplexer.java
index 56e179590..91039533d 100644
--- a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/Mineplexer.java
+++ b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/Mineplexer.java
@@ -1,39 +1,21 @@
package mineplex.bungee;
-import java.util.logging.Handler;
-import java.util.logging.Level;
import mineplex.bungee.lobbyBalancer.LobbyBalancer;
import mineplex.bungee.motd.MotdManager;
import mineplex.bungee.playerCount.PlayerCount;
import mineplex.bungee.playerStats.PlayerStats;
import mineplex.bungee.playerTracker.PlayerTracker;
-import net.kencochrane.raven.DefaultRavenFactory;
-import net.kencochrane.raven.dsn.Dsn;
-import net.kencochrane.raven.jul.SentryHandler;
import net.md_5.bungee.api.plugin.Plugin;
public class Mineplexer extends Plugin
{
@Override
public void onEnable() {
- getProxy().getScheduler().runAsync(this, new Runnable() {
- @Override
- public void run() {
- // Sentry setup
- Handler sentry = new SentryHandler(new DefaultRavenFactory().createRavenInstance(
- new Dsn("https://470f12378af3453ba089e0c0a0c9aae6:292516b722594784807aebb06db8ec38@app.getsentry.com/66323"
- )));
- sentry.setLevel(Level.SEVERE);
- getProxy().getLogger().addHandler(sentry);
- }
- });
-
new MotdManager(this);
new LobbyBalancer(this);
- PlayerCount playerCount = new PlayerCount(this);
+ new PlayerCount(this);
new FileUpdater(this);
new PlayerStats(this);
- //new InternetStatus(this);
new PlayerTracker(this);
}
}
diff --git a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyBalancer.java b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyBalancer.java
index 5f7153ae9..0c57abfea 100644
--- a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyBalancer.java
+++ b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyBalancer.java
@@ -2,7 +2,6 @@ package mineplex.bungee.lobbyBalancer;
import java.io.File;
import java.net.InetSocketAddress;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -12,21 +11,24 @@ import mineplex.serverdata.Region;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
-import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
+import com.google.common.collect.Lists;
+
public class LobbyBalancer implements Listener, Runnable
{
private Plugin _plugin;
private ServerRepository _repository;
- private List _sortedLobbies = new ArrayList();
+ private List _sortedLobbies = Lists.newArrayList();
+ private List _sortedClans = Lists.newArrayList();
private static Object _serverLock = new Object();
private int _lobbyIndex = 0;
+ private int _clansIndex = 0;
public LobbyBalancer(Plugin plugin)
{
@@ -35,7 +37,7 @@ public class LobbyBalancer implements Listener, Runnable
Region region = !new File("eu.dat").exists() ? Region.US : Region.EU;
_repository = ServerManager.getServerRepository(region);
- loadLobbyServers();
+ run();
_plugin.getProxy().getPluginManager().registerListener(_plugin, this);
_plugin.getProxy().getScheduler().schedule(_plugin, this, 500L, 500L, TimeUnit.MILLISECONDS);
@@ -44,27 +46,49 @@ public class LobbyBalancer implements Listener, Runnable
@EventHandler
public void playerConnect(ServerConnectEvent event)
{
- if (!event.getTarget().getName().equalsIgnoreCase("Lobby"))
- return;
-
- synchronized (_serverLock)
+ if (event.getTarget().getName().equalsIgnoreCase("Lobby"))
{
- if (_lobbyIndex >= _sortedLobbies.size() || _sortedLobbies.get(_lobbyIndex).getPlayerCount() >= _sortedLobbies.get(_lobbyIndex).getMaxPlayerCount())
- _lobbyIndex = 0;
-
- event.setTarget(_plugin.getProxy().getServerInfo(_sortedLobbies.get(_lobbyIndex).getName()));
- _sortedLobbies.get(_lobbyIndex).incrementPlayerCount(1);
- System.out.println("Sending " + event.getPlayer().getName() + " to " + _sortedLobbies.get(_lobbyIndex).getName() + "(" + _sortedLobbies.get(_lobbyIndex).getPublicAddress() + ")");
- _lobbyIndex++;
+ synchronized (_serverLock)
+ {
+ if (_lobbyIndex >= _sortedLobbies.size() || _sortedLobbies.get(_lobbyIndex).getPlayerCount() >= _sortedLobbies.get(_lobbyIndex).getMaxPlayerCount())
+ _lobbyIndex = 0;
+
+ event.setTarget(_plugin.getProxy().getServerInfo(_sortedLobbies.get(_lobbyIndex).getName()));
+ _sortedLobbies.get(_lobbyIndex).incrementPlayerCount(1);
+ System.out.println("Sending " + event.getPlayer().getName() + " to " + _sortedLobbies.get(_lobbyIndex).getName() + "(" + _sortedLobbies.get(_lobbyIndex).getPublicAddress() + ")");
+ _lobbyIndex++;
+ }
+ }
+ if (event.getTarget().getName().equalsIgnoreCase("ClansHub"))
+ {
+ synchronized (_serverLock)
+ {
+ if (_clansIndex >= _sortedClans.size() || _sortedClans.get(_clansIndex).getPlayerCount() >= _sortedClans.get(_clansIndex).getMaxPlayerCount())
+ _clansIndex = 0;
+
+ event.setTarget(_plugin.getProxy().getServerInfo(_sortedClans.get(_clansIndex).getName()));
+ _sortedClans.get(_clansIndex).incrementPlayerCount(1);
+ System.out.println("Sending " + event.getPlayer().getName() + " to " + _sortedClans.get(_clansIndex).getName() + "(" + _sortedClans.get(_clansIndex).getPublicAddress() + ")");
+ _clansIndex++;
+ }
}
}
public void run()
{
- loadLobbyServers();
+ loadServers();
+
+ if (!_plugin.getProxy().getServers().containsKey("ClansHub"))
+ {
+ _plugin.getProxy().getServers().put("ClansHub", _plugin.getProxy().constructServerInfo("ClansHub", new InetSocketAddress("lobby.mineplex.com", 25565), "LobbyBalancer", false));
+ }
+ if (!_plugin.getProxy().getServers().containsKey("Lobby"))
+ {
+ _plugin.getProxy().getServers().put("Lobby", _plugin.getProxy().constructServerInfo("Lobby", new InetSocketAddress("lobby.mineplex.com", 25565), "LobbyBalancer", false));
+ }
}
- public void loadLobbyServers()
+ public void loadServers()
{
Collection servers = _repository.getServerStatuses();
@@ -72,6 +96,7 @@ public class LobbyBalancer implements Listener, Runnable
{
long startTime = System.currentTimeMillis();
_sortedLobbies.clear();
+ _sortedClans.clear();
for (MinecraftServer server : servers)
{
@@ -88,9 +113,17 @@ public class LobbyBalancer implements Listener, Runnable
_sortedLobbies.add(server);
}
}
+ if (server.getName().toUpperCase().startsWith("CLANSHUB"))
+ {
+ if (server.getMotd() == null || !server.getMotd().contains("Restarting"))
+ {
+ _sortedClans.add(server);
+ }
+ }
}
Collections.sort(_sortedLobbies, new LobbySorter());
+ Collections.sort(_sortedClans, new LobbySorter());
long timeSpentInLock = System.currentTimeMillis() - startTime;
diff --git a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java
index 1f5bc2b09..aa2565f27 100644
--- a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java
+++ b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java
@@ -1,20 +1,18 @@
package mineplex.bungee.motd;
-import java.awt.Color;
import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import mineplex.serverdata.Region;
-import mineplex.serverdata.data.BungeeServer;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ConnectionData;
-import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ConnectionData.ConnectionType;
-import net.md_5.bungee.api.ChatColor;
+import mineplex.serverdata.servers.ServerManager;
import net.md_5.bungee.api.event.ProxyPingEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
@@ -31,6 +29,8 @@ public class MotdManager implements Listener, Runnable
private Random _random = new Random();
private String _firstLine = " §b§l§m §8§l§m[ §r §9§lMineplex§r §f§lGames§r §8§l§m ]§b§l§m §r";
private List _motdLines;
+ private String _firstCLine = " §b§l§m §8§l§m[ §r §9§lMineplex§r §f§lGames§r §8§l§m ]§b§l§m §r";
+ private List _motdCLines;
public MotdManager(Plugin plugin)
{
@@ -70,25 +70,50 @@ public class MotdManager implements Listener, Runnable
public void serverPing(ProxyPingEvent event)
{
net.md_5.bungee.api.ServerPing serverPing = event.getResponse();
-
- String motd = _firstLine;
- if (_motdLines != null && _motdLines.size() > 0)
+ if (event.getConnection().getListener() != null && event.getConnection().getListener().getDefaultServer().equalsIgnoreCase("ClansHub"))
{
- motd += "\n" + _motdLines.get(_random.nextInt(_motdLines.size()));
+ String motd = _firstCLine;
+ if (_motdCLines != null && _motdCLines.size() > 0)
+ {
+ motd += "\n" + _motdCLines.get(_random.nextInt(_motdCLines.size()));
+ }
+ event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getVersion(), serverPing.getPlayers(), motd, serverPing.getFaviconObject()));
+ }
+ else
+ {
+ String motd = _firstLine;
+ if (_motdLines != null && _motdLines.size() > 0)
+ {
+ motd += "\n" + _motdLines.get(_random.nextInt(_motdLines.size()));
+ }
+ event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getVersion(), serverPing.getPlayers(), motd, serverPing.getFaviconObject()));
}
-
- event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getVersion(), serverPing.getPlayers(), motd, serverPing.getFaviconObject()));
}
@Override
public void run()
{
- GlobalMotd motd = _repository.getElement("MainMotd");
-
- if (motd != null)
- {
- _motdLines = motd.getMotd();
- _firstLine = motd.getHeadline();
+ {
+ GlobalMotd motd = _repository.getElement("MainMotd");
+
+ if (motd != null)
+ {
+ _motdLines = motd.getMotd();
+ _firstLine = motd.getHeadline();
+ }
+ }
+ {
+ GlobalMotd motd = _repository.getElement("ClansMotd");
+
+ if (motd != null)
+ {
+ _motdCLines = motd.getMotd();
+ _firstCLine = motd.getHeadline();
+ }
+ else
+ {
+ _repository.addElement(new GlobalMotd("ClansMotd", "§4§lMineplex Clans§r", Arrays.asList("Default MOTD")));
+ }
}
}
diff --git a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerCount/PlayerCount.java b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerCount/PlayerCount.java
index 61767b81d..9c6cdfbc5 100644
--- a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerCount/PlayerCount.java
+++ b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerCount/PlayerCount.java
@@ -1,7 +1,6 @@
package mineplex.bungee.playerCount;
import java.io.File;
-import java.util.UUID;
import java.util.concurrent.TimeUnit;
import mineplex.bungee.status.InternetStatus;
@@ -12,7 +11,6 @@ import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ConnectionData;
import mineplex.serverdata.servers.ConnectionData.ConnectionType;
import mineplex.serverdata.servers.ServerManager;
-import mineplex.serverdata.servers.ServerRepository;
import net.md_5.bungee.api.ServerPing.Players;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.event.ProxyPingEvent;
@@ -39,7 +37,13 @@ public class PlayerCount implements Listener, Runnable
_plugin.getProxy().getScheduler().schedule(_plugin, this, 4L, 4L, TimeUnit.SECONDS);
_plugin.getProxy().getPluginManager().registerListener(_plugin, this);
- _listenerInfo = _plugin.getProxy().getConfigurationAdapter().getListeners().iterator().next();
+ for (ListenerInfo info : _plugin.getProxy().getConfigurationAdapter().getListeners())
+ {
+ if (info.getDefaultServer().equalsIgnoreCase("Lobby"))
+ {
+ _listenerInfo = info;
+ }
+ }
_repository = new RedisDataRepository(ServerManager.getConnection(true, ServerManager.SERVER_STATUS_LABEL), ServerManager.getConnection(false, ServerManager.SERVER_STATUS_LABEL),
Region.ALL, BungeeServer.class, "bungeeServers");
@@ -55,7 +59,10 @@ public class PlayerCount implements Listener, Runnable
public void run()
{
BungeeServer snapshot = generateSnapshot();
- _repository.addElement(snapshot, 15); // Update with a 15 second expiry on session
+ if (snapshot != null)
+ {
+ _repository.addElement(snapshot, 15); // Update with a 15 second expiry on session
+ }
_totalPlayers = fetchPlayerCount();
}
@@ -84,6 +91,10 @@ public class PlayerCount implements Listener, Runnable
*/
private BungeeServer generateSnapshot()
{
+ if (_listenerInfo == null)
+ {
+ return null;
+ }
String name = _listenerInfo.getHost().getAddress().getHostAddress();
String host = _listenerInfo.getHost().getAddress().getHostAddress();
int port = _listenerInfo.getHost().getPort();
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/CurrencyType.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/CurrencyType.java
deleted file mode 100644
index 550a761a7..000000000
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/CurrencyType.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package mineplex.core.common;
-
-import mineplex.core.common.util.C;
-import org.bukkit.Material;
-
-public enum CurrencyType
-{
- TOKEN("Tokens", "Token", C.cWhite, Material.EMERALD),
- TREASURE_SHARD("Treasure Shards", "Treasure Shard", C.cAqua, Material.PRISMARINE_SHARD),
- GEM("Gems", "Gem", C.cGreen, Material.EMERALD),
- GOLD("Gold", "Gold", C.cGold, Material.GOLD_NUGGET);
-
- private String _plural;
- private String _single;
- private String _color;
- private Material _displayMaterial;
-
- CurrencyType(String plural, String single, String color, Material displayMaterial)
- {
- _plural = plural;
- _single = single;
- _color = color;
- _displayMaterial = displayMaterial;
- }
-
- @Deprecated
- public String getPrefix()
- {
- return _plural;
- }
-
- public String getString(int amount)
- {
- return _color + amount + " " + (amount == 1 ? _single : _plural);
- }
-
- public Material getDisplayMaterial()
- {
- return _displayMaterial;
- }
-}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/SortedSchematicLoader.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/SortedSchematicLoader.java
index 7b985dd82..279747684 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/SortedSchematicLoader.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/SortedSchematicLoader.java
@@ -42,6 +42,7 @@ public class SortedSchematicLoader
if (entry != null && !entry.getKey().equals(_currentValue))
{
_currentValue = entry.getKey();
+ Schematic schematic = entry.getValue();
entry.getValue().paste(_pasteLocation, false);
}
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiEndpoint.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiEndpoint.java
index 06fdc0896..3b12c1d0b 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiEndpoint.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiEndpoint.java
@@ -1,23 +1,30 @@
package mineplex.core.common.api;
import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
/**
* @author Shaun Bennett
*/
public class ApiEndpoint
{
- private static final String API_HOST = "10.33.53.12";
-// private static final String API_HOST = "localhost";
-// private static final int API_PORT = 3000;
- private static final int API_PORT = 7979;
-
private Gson _gson;
private ApiWebCall _webCall;
- public ApiEndpoint(String path, Gson gson)
+ public ApiEndpoint(ApiHost host, String path)
{
- String url = "http://" + API_HOST + ":" + API_PORT + path;
+ this(host, path, new GsonBuilder().setFieldNamingStrategy(new ApiFieldNamingStrategy())
+ .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").create());
+ }
+
+ public ApiEndpoint(ApiHost host, String path, Gson gson)
+ {
+ this(host.getHost(), host.getPort(), path, gson);
+ }
+
+ public ApiEndpoint(String host, int port, String path, Gson gson)
+ {
+ String url = "http://" + host + ":" + port + path;
_webCall = new ApiWebCall(url, gson);
_gson = gson;
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java
new file mode 100644
index 000000000..93dbf761b
--- /dev/null
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java
@@ -0,0 +1,31 @@
+package mineplex.core.common.api;
+
+/**
+ * TODO: Store this in a file instead of being hardcoded
+ *
+ * @author Shaun Bennett
+ */
+public enum ApiHost
+{
+ AMPLIFIERS("10.33.53.12", 7979),
+ ANTISPAM("10.33.53.12", 8181);
+
+ private String _host;
+ private int _port;
+
+ ApiHost(String host, int port)
+ {
+ _host = host;
+ _port = port;
+ }
+
+ public String getHost()
+ {
+ return _host;
+ }
+
+ public int getPort()
+ {
+ return _port;
+ }
+}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/Schematic.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/Schematic.java
index 492c58bfc..e08a70c0d 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/Schematic.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/Schematic.java
@@ -283,13 +283,29 @@ public class Schematic
return index < _blocks.length && index >= 0;
}
- public short getBlock(int x, int y, int z)
+ public Short getBlock(int x, int y, int z)
{
+ if (getIndex(x, y, z) >= _blocks.length)
+ {
+ return null;
+ }
+ if (getIndex(x, y, z) < 0)
+ {
+ return null;
+ }
return _blocks[getIndex(x, y, z)];
}
- public byte getData(int x, int y, int z)
+ public Byte getData(int x, int y, int z)
{
+ if (getIndex(x, y, z) >= _blocks.length)
+ {
+ return null;
+ }
+ if (getIndex(x, y, z) < 0)
+ {
+ return null;
+ }
return _blockData[getIndex(x, y, z)];
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/SchematicRunnable.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/SchematicRunnable.java
index e3b8c1d0a..b45c9b682 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/SchematicRunnable.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/SchematicRunnable.java
@@ -99,10 +99,13 @@ public class SchematicRunnable implements Runnable
private void setBlock(Block block, int x, int y, int z)
{
-
- int materialId = _schematic.getBlock(x, y, z);
- byte data = _schematic.getData(x, y, z);
-
+ Short materialId = _schematic.getBlock(x, y, z);
+ Byte data = _schematic.getData(x, y, z);
+
+ if (materialId == null || data == null)
+ {
+ return;
+ }
Material material = Material.getMaterial(materialId);
if (material == null)
{
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/currency/Currency.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/currency/Currency.java
new file mode 100644
index 000000000..f82182bb6
--- /dev/null
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/currency/Currency.java
@@ -0,0 +1,41 @@
+package mineplex.core.common.currency;
+
+import org.bukkit.Material;
+
+/**
+ * Currency is the base class for all currency types in mineplex:
+ * - Global currencies, found in {@link GlobalCurrency}, e.g., treasure shards
+ * - Clans gold, found in the Mineplex.Game.Clans project
+ */
+public class Currency
+{
+ private final String _plural;
+ private final String _singular;
+ private final String _color;
+ private final Material _displayMaterial;
+
+ public Currency(String plural, String singular, String color, Material displayMaterial)
+ {
+ this._plural = plural;
+ this._singular = singular;
+ this._color = color;
+ this._displayMaterial = displayMaterial;
+ }
+
+ @Deprecated
+ public String getPrefix()
+ {
+ return _plural;
+ }
+
+ public String getString(int amount)
+ {
+ return _color + amount + " " + (amount == 1 ? _singular : _plural);
+ }
+
+ public Material getDisplayMaterial()
+ {
+ return _displayMaterial;
+ }
+}
+
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/currency/GlobalCurrency.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/currency/GlobalCurrency.java
new file mode 100644
index 000000000..1e6b6bc03
--- /dev/null
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/currency/GlobalCurrency.java
@@ -0,0 +1,17 @@
+package mineplex.core.common.currency;
+
+import mineplex.core.common.util.C;
+import org.bukkit.Material;
+
+/**
+ * A GlobalCurrency is one whose state is shared between all Mineplex servers.
+ * GlobalCurrencies can be retrieved and modified through DonationManager/Donor in Mineplex.Core
+ */
+public class GlobalCurrency extends Currency {
+ public static final GlobalCurrency TREASURE_SHARD = new GlobalCurrency("Treasure Shards", "Treasure Shard", C.cAqua, Material.PRISMARINE_SHARD);
+ public static final GlobalCurrency GEM = new GlobalCurrency("Gems", "Gem", C.cGreen, Material.EMERALD);
+
+ public GlobalCurrency(String plural, String singular, String color, Material displayMaterial) {
+ super(plural, singular, color, displayMaterial);
+ }
+}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/events/EntityVelocityChangeEvent.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/events/EntityVelocityChangeEvent.java
new file mode 100644
index 000000000..12b860d19
--- /dev/null
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/events/EntityVelocityChangeEvent.java
@@ -0,0 +1,60 @@
+package mineplex.core.common.events;
+
+import org.bukkit.entity.Entity;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.util.Vector;
+
+/**
+ * Called just before UtilAction#velocity changes an entity's velocity.
+ */
+public class EntityVelocityChangeEvent extends Event
+{
+ private static final HandlerList handlers = new HandlerList();
+
+ private Entity _ent;
+ private Vector _vel;
+
+ private boolean _cancelled;
+
+ public EntityVelocityChangeEvent(Entity entity, Vector velocity)
+ {
+ _ent = entity;
+ _vel = velocity;
+ }
+
+ public Entity getEntity()
+ {
+ return _ent;
+ }
+
+ public boolean isCancelled()
+ {
+ return _cancelled;
+ }
+
+ public Vector getVelocity()
+ {
+ return _vel;
+ }
+
+ public void setVelocity(Vector velocity)
+ {
+ _vel = velocity;
+ }
+
+ public void setCancelled(boolean cancelled)
+ {
+ _cancelled = cancelled;
+ }
+
+ public HandlerList getHandlers()
+ {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList()
+ {
+ return handlers;
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/jsonchat/JsonMessage.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/jsonchat/JsonMessage.java
index f4ce9532e..c32abd4a8 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/jsonchat/JsonMessage.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/jsonchat/JsonMessage.java
@@ -108,7 +108,7 @@ public class JsonMessage
public void sendToPlayer(Player player)
{
- UtilServer.getServer().dispatchCommand(UtilServer.getServer().getConsoleSender(), "tellraw " + player.getName() + " " + toString());
+ ((CraftPlayer) player).getHandle().sendMessage(IChatBaseComponent.ChatSerializer.a(toString()));
}
/**
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/skin/SkinData.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/skin/SkinData.java
index b89b34866..5494a5672 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/skin/SkinData.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/skin/SkinData.java
@@ -1,7 +1,22 @@
package mineplex.core.common.skin;
+import java.lang.reflect.Field;
+import java.util.Base64;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import com.google.common.collect.Maps;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.mojang.authlib.minecraft.InsecureTextureException;
+import com.mojang.authlib.minecraft.MinecraftProfileTexture;
+import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
+import mineplex.core.common.util.UtilPlayer;
+import net.minecraft.server.v1_8_R3.MinecraftServer;
+import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.entity.Player;
@@ -16,20 +31,42 @@ import net.minecraft.server.v1_8_R3.MinecraftKey;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.NBTTagList;
import net.minecraft.server.v1_8_R3.NBTTagString;
+import org.bukkit.inventory.meta.SkullMeta;
public class SkinData
{
+ private static final Field PROFILE_FIELD;
+
+ static
+ {
+ try
+ {
+ PROFILE_FIELD = Class.forName("org.bukkit.craftbukkit.v1_8_R3.inventory.CraftMetaSkull").getDeclaredField("profile");
+ PROFILE_FIELD.setAccessible(true);
+ }
+ catch (ReflectiveOperationException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+ }
+
private static long _nameCount = -99999999999999L;
public final static SkinData FREEDOM_CHEST = new SkinData("eyJ0aW1lc3RhbXAiOjE0NjY1NzA5NDAzODcsInByb2ZpbGVJZCI6IjQwZWQ5NzU1OWIzNTQ1M2Q4NjU1ZmMwMDM5OGRiNmI5IiwicHJvZmlsZU5hbWUiOiJTcG9vYm5jb29iciIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjc4N2Q4OGNlYzNmOWI0M2RiNDg1YTU0Mjc2YTQ1MjQzNGFiZDI2ZDMzY2QzZmZhMTM2N2ZiMzVmOWUzODQifX19", "UgsQyW/HJ/jmDzfI1d7RWFbhKi8PeJAKBuAOk7ajS5dzH5od301KfcmiT2X3TU7cBbUswcKtDb2F/m7gNrg/t+pU7Bi9UKzyALEu9HRjd4s1uKbqGkBip1z5Qycp4fhkSyKvtvTnA2fhpP9oHtE5FxGXdMhZXyFkLrli4Hyxp1BI0N4h7pgbcMaISPS0ZYzDRNxkrSnl3y3KyKn5Rl5qH7utmQtAjoyx9aueMZxG3tg/igfYF7uAvvmuYKsSiTZWZOOuSh+U1dkP+ZE/cQANfryXkLJSJHa9YZPCMJHXe4mMoAyu0/quwZCW9NlW3P30XeCfZ87IxfKxISIP0dLgY8hUJyCuI2u5U7TEDrDggPKr6XTcIbX2kFKOsYSeovsAgjC+1UKFH4Ba0jTbRmqzPK49fk/jU8XqRP2Gl9UZDIVbc0dMEXNOeJ0e0wejDtSyX8flBk9sIKYwqeB9ns4cFqSyTI5tKnNin12BNTFRK/bDp8dN7nloyQvhDGlW88UlnJmOFhR6R0naP89VM04VCLaYCr6jyv/ZwV88uPvL2kjhx14qSFfgqJI5ORhFgYkuc+nhyQaD8+y2t3ZMs0HAfoujmq98lp2ECLWyI0ATUcXjUyNYadLj4valS/m0jl7U2fwzcmVMQqOC3ddu6mHbt871hIkG2X4v6kEcVAtKmkg=");
+
+ public final static SkinData ALEX = new SkinData("eyJ0aW1lc3RhbXAiOjE0NjY3Mzc4OTE4MTgsInByb2ZpbGVJZCI6IjZhYjQzMTc4ODlmZDQ5MDU5N2Y2MGY2N2Q5ZDc2ZmQ5IiwicHJvZmlsZU5hbWUiOiJNSEZfQWxleCIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7Im1ldGFkYXRhIjp7Im1vZGVsIjoic2xpbSJ9LCJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzYzYjA5ODk2NzM0MGRhYWM1MjkyOTNjMjRlMDQ5MTA1MDliMjA4ZTdiOTQ1NjNjM2VmMzFkZWM3YjM3NTAifX19", "BCyo2Ycx5cxjS9eR8ejakJ0inXSaiOO/2Wb3GoOSBFeKmnLpigR2kbvnIv0j+R5wtGLAbcAmxCZzvI9VpkHC0Al7zyAzY+WypfXi5MAju+dpVdCmp8p3m3oznYscPaI1ADR8ecQBMLFeG8RWuWha5whUyyRNQU8pBPbKMcsIMOn2voCQkH3cjtrZRgDGebxF32CE7I10GEhiFv8UyBVhZ11t6Jbbsj345j0ZHoydTlGADFFpnx+bAQ6BQlkMgNOWAJoI7/3p6IjFQUVYQV70o3VvP9G+B0VwHSQPxhCYxgF/1PcmKsET/HN6cPR34qKJ5HiSt2oS5q/EqLPc9cK/pFAVb+/rq/Z/TSVL94SE/OcImT7NHvVOqurLPLNyj7SMbQvL3bZS3wNkeU7TIkQkGiza2jmeTfPOkBXwMUBl95b+BX3aM36EtyZ4jL1eTOJdqG4x5JG9uGVvcGHw5289ykXUW3L3+A/9J2uYT3mzH9dJ1YLGA3dmTmMqjWrJRxdA5OU46fREsMWMaELbpiHOkhAgqMW1Bofs4hdvkBZE3JIbjIivncvXVU0MGgnd//U4P5iteUMY8Dpc+uKJ3N8KMojCbhWiig0ElLMuNFbNG9PVsUNwwT/wYLJZ3PJ0VBcNERgAWnJ16DM4oA8SfAKosmSQBCW11+1Sxfkj55QoxH0=");
+ public final static SkinData STEVE = new SkinData("eyJ0aW1lc3RhbXAiOjE0NjY3MzgxOTAzNDYsInByb2ZpbGVJZCI6ImJiYjg3ZGJlNjkwZjQyMDViZGM1NzJmZmI4ZWJjMjlkIiwicHJvZmlsZU5hbWUiOiJkaXJld29sZjIwIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS82NmZlNTE3NjY1MTdmM2QwMWNmZGI3MjQyZWI1ZjM0YWVhOTYyOGExNjZlM2U0MGZhZjRjMTMyMTY5NiJ9fX0=", "xIDCRBS39ZhhROcYkYORDcWosWqR5xvrTTScNzpt8WtBq1cAoL1mXEi/PtBrEEvajcpR/nGhRlZV/IeavtmUx49ulY3bdX827Rex3504DnmolxVqnq8/p1W8ywxV9FBcMI4Cto3c5kmIXHTTAcLsUuCmsmprzuMS+/RvfJ//vjem+lUc+eQKBe3Hc3ocapfxf1dHqSrtzurW2fRTMZcJWEOr9eicRDzOOP2nbtfZGeCcwJPnYJMxJReBWLO/LiV6Bzm/8+ynRFzmJVw7zvXY9WCz/Yt95nK1lqpFZXR7djFYTsnLpLc71rUPhPwSZSVm0Ca+wZWI2RFnm3kbKRsIB89EqsVIxgw9SMKHJwGPc/GBMOZuO2J6HxGn5xXE5JnLTn8YzpBDft+3Hnb2EJTJ2OCPHaQtzMiYDG4+OkwP7ksxcwmMxRUWuE37dwXi/d4A94IKsLqrCxj+vGFPo13wc5L0DRRx7Plk2/nrC32UhKomkjGz2XbS1aJpKgLILbaM1nYnNGKx/VBLNNJdpwhwaoWgRPEB2MEFmxV+GQ/QgOJuaI7fj5KfLqCePX5V3tfdEUb5OmnC2rH1+ptE1RNOBvPPV/D04NzpvvT9QtCq3I6f1fqbcdWVaYkrRcyD/EjQv0Vod46GJPT4jEQ8f2K10dpDtaB/cWGpT16XCRNT0F8=");
+
+ public final static SkinData MOOSHROOM = new SkinData("eyJ0aW1lc3RhbXAiOjE0NDk4NzI0OTU0MTcsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzIxOWJlYTU0Y2FkN2Q1OGFiNWRhNDA2YjBhOTJhYjNhODI0MjI1MjY2Nzc3ZTUzNGI3ZGI2YzM3MmRkZmY3ZiJ9fX0=", "UoSif81+UyvkcaanU8KAMYBpw9mefAmWehE2liDUFvk+y0X/9NovsxTYVpIDCltTSpLW3sNgamvbj4Ybs+s6DbudPiEkvh0ER7Bv2v29UJw7RzIdr6/1g548X12zcnh5iPGz/P75uNRnSfTFQx0ed8P/GNkPIjWpDuJFxEj6KcPzrCAGMx+BVw1VwryBIYf9cCDHky8z0bxR89rjiIvPTBFI6MRhqI3vgpEBTySHDS+Ki0Hwl5oa3PwS6+jgYx/4RSfFsb+BawcvDk2Xpkt5UimvqZ5BceYLIfCt4KbShYipgLXLfYUZrntjPemd3SxthjxUuA07i44UxRdiC8uqy1twLT/HUS28gpk68lA/id9tKFwu1CUzshgcmvQPt3ghtNViNziR/2t7D/+5D31Vzmhf6n7Pnpdirt/5frMi2BKMMs7pLa0EF8CrrDU7QCwPav+EZVGFvVZbxSkCDq+n3IQ3PUWSCzy6KPxpdOlUjD0pAfLoiNj0P8u4+puQtID76r/St8ExchYl2dodUImu1ZETWeFUClF3ZGat62evx8uRQEI2W4dsVwj40VUfjaAuvyDzuouaKTrCzJXLQZZjR1B8URvuK61fGX0nhW607mEi6DE+nxP2ZoBrROEX4e37Ap6+TQn9Q8tKDPdcxtwSOpPO4Qkncjn/mGtP9lZU/DQ=");
+
public final static SkinData COMPANION_CUBE = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTUxMDk5NjI0NjEsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2MyMTVkYmRhNTY1ZjVjYjhlYjEyZjU1NWY1ZTNkYTBlYTVmNTUxOTg5MWNjNWM1ZDY3NmZkODJjNjIifX19", "vaAQbhnhnTOs64ToFWLg7o4JmqkIl07HWJ6l7xibfISaOcU4BvYBxsfGvmoxlVdsUeCunAJ8/05qVLl5zZYd8Dt+To6JSY0RlqV8piRaaj3FztYWV2ZvG3YZxPxiD3HRJTAQnDobSuxHyPa1e3khjAFp9xJo4q1oqQ28oI2WDuoT+IHqxwkKVbGzO7UD5lzz5chjQC46E8SxddNKp9aqwbbccrkHYT4gteoonOXu4MFxZniJN12LqUCb6+G15rU8MijlBkWx0xE5NMUloeTGuJZItbHun9fysLk/+HE5xJOKYtpZNMuWX+DB/O5ds9dXrOoSAg+Vn0QU4CZbwcxzLii5ILOfEEBtePuEAgzROri+iCKp59CqlEMBrCsd3Um0MCdbuOfvkXGBHBz+bqX7VJY1ujlSdMefmbJtHAkDANnsaaVb+eli9Dk6139041sptsLytD+EfJzaitX6crBwKZ2WDx2P6LHo8B+iSOzOJxjf/08zlXqFw1vsk62IN6lisuZ89QyZw23RvOx3obLAGYs1GxAlMl9qQdpXcmuE1+lPR3g8gZ0BfnTeYwflC2wbR1tuwGG98lyUGCvGLyqNKAQTN87XV4IFQWR81mi1c5CcasoWhKf9D9nAik9aK7A915fEE5IvpeuUdZseDxDVVN5dBIs5q2PIHFAS0rDsDBc=");
- public final static SkinData THE_GRINCH = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTYxNDMwMDQsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzg4ZWRlOTI3ZDQzOWVmMzliMzFhYzFkYzJhODM5NGZlNzlhY2U4NDMyNzBjYmUxMjg2ZGM3NTE3ZjMxYTk2In19fQ==","ELo594vTzPq9ZmPYOtVr4kim/k19gzmoxEIK1ehS87gwgag5HcgM+P1FMnHIyrmSvTVaMh0NxwXmNS+JETFL7OrmgRYNpkxkkO4VBA0pfSn3dA9ujnXpDnDiWEPxKdMgQspIOOI0Z3esNt3pj8qIj6dWPtGwtso48tjHl2o/kazfa82yvGORlFhGkeEJKQMno/Buc12C0foQw39XI8GjvlSkFN2eH4Fp16RLu8/hf7SqJQC3L1KacvzMW1d8BWEIgACCJDni29+YqxflSqSyYrV4Z+D66S0jYvUUL/vM4/q/p/YWX/vs/FtMtHQTj4PCpAmMNTgfkahuhb6rCvKHukbjA+WhUdwyxSqXU5YnpXCu1M2dzZgiXjIi+fnyn4CmXKindWCQtSwu+mCA2ILv/6vEHoYJgdlz+DXyRkFx+DH4Sl74HBCOXTOq5AGjq5h3LYfsre+UjCCUv8VgxbVprOyj35So7K0m+6faCFVSt35T3RgicDQfdiWUrW7kmHQVvJpvaq9Vu+63F/0X93cwqwaR0buMirxRx7qkFrRunSI4T+9fsN02t1fAieeu80lBSv83wr7BFneSsLsdVAND9xttTb6fClg7anr8/XVEVIkylB4B+ZcWQbH61XP1nn7oFP2VBg1h6XuuLp8FGSgYf/LW+54/KZci/MnanqQE6QQ=");
+ public final static SkinData THE_GRINCH = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTYxNDMwMDQsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzg4ZWRlOTI3ZDQzOWVmMzliMzFhYzFkYzJhODM5NGZlNzlhY2U4NDMyNzBjYmUxMjg2ZGM3NTE3ZjMxYTk2In19fQ==", "ELo594vTzPq9ZmPYOtVr4kim/k19gzmoxEIK1ehS87gwgag5HcgM+P1FMnHIyrmSvTVaMh0NxwXmNS+JETFL7OrmgRYNpkxkkO4VBA0pfSn3dA9ujnXpDnDiWEPxKdMgQspIOOI0Z3esNt3pj8qIj6dWPtGwtso48tjHl2o/kazfa82yvGORlFhGkeEJKQMno/Buc12C0foQw39XI8GjvlSkFN2eH4Fp16RLu8/hf7SqJQC3L1KacvzMW1d8BWEIgACCJDni29+YqxflSqSyYrV4Z+D66S0jYvUUL/vM4/q/p/YWX/vs/FtMtHQTj4PCpAmMNTgfkahuhb6rCvKHukbjA+WhUdwyxSqXU5YnpXCu1M2dzZgiXjIi+fnyn4CmXKindWCQtSwu+mCA2ILv/6vEHoYJgdlz+DXyRkFx+DH4Sl74HBCOXTOq5AGjq5h3LYfsre+UjCCUv8VgxbVprOyj35So7K0m+6faCFVSt35T3RgicDQfdiWUrW7kmHQVvJpvaq9Vu+63F/0X93cwqwaR0buMirxRx7qkFrRunSI4T+9fsN02t1fAieeu80lBSv83wr7BFneSsLsdVAND9xttTb6fClg7anr8/XVEVIkylB4B+ZcWQbH61XP1nn7oFP2VBg1h6XuuLp8FGSgYf/LW+54/KZci/MnanqQE6QQ=");
public final static SkinData LOVESTRUCK = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTUxMTAyNDMyNjUsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzczMTY5YWQwZTUyYjM1N2NiZGYxZDU0NGVkNGNmOWJmOTI4YmI0ZWNlMDhlY2YyY2M0YmYyYTlmMjJhODI4MmQifX19", "LL4RiSKQoTZamRQ4QG6izpvhgFu5gAqW4eZxcWAihk7GkhyxifpJpBTOzKrj5hH9fCUfYkkijVWUYTEcVSVRWhocp2HXW59TbKfxOeMvHU5vTMwgpwm6PnUfwuTsRPSLC7WMnEreI3cjOxPVmXbTniOSd+o8j4oOIgwFS+VLPiYLh5Jl16i5I/9ekafl3/x41NISKWl62geqO2jPWehlk+r3soiRJsxaKw20T61GSNLu19iA96Rz2T2tUHB4opm8hbLgoiNL2g1affTjq3cZPLHH4JWF3vPhqLB5uw6xb55vFLM/PP0YiEMIi7YZOfRGeaPp7uXbXgHeew+7PG9UDVMfqbwANQY4ndECijZoei54+xX3MDXkMhQsc5S+FLnGH6e4d008v81eEOyzJUPkKbGxLCBgTUb1s4IHwomCr30twPlo1IuFBOY1qeVvZUfAfPJsREuj5q/oCAoYFgupmb3ClWECnwwaH/T4wdHjfSBHoZQdLzcgDOAl0b5EXxWmYBECqk/WA4TrYIDVGdwkqjI0RkPLUoxTj6135KO+F7P7PwhU9WBGeW8hHq918DBL0fjQVHjrzvolTqwmw6nySSePnPOxFX/iwtHWzpBa9V6kUNNN+V7OGTgRr0H/yUxB+oq1F8UBqyqT4YpqxXCSD36derF/Xt5IdpTbEbGBpm0=");
- public final static SkinData PRESENT = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTk3MDIxNjIsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2U2YzRkZWQwNTdjMjhiMTU0NjVkYzQzNmFmODIyYTNkZTY4NzgyZTZjMzgyOGMzMmFhYWE4ZjRiOTIzOWVjIn19fQ==","rJNlxTqHHmOoWwbXdMQLcj0P9w/PIr/hWKXH0nbhm/S2CFo/zfefffZlnQmpKCgn1Y8tXvcRwLGQ4CLpm9m2ZrKprSWRhrnOtZWYabrhExQESEammS3TY81VoNt+4On0pAGBippz/bRfWLuDne2rDbhuljnqvxjROmxpky7gRCU06VMlm2WLFC5XYJkiAaOXBqzpiHMMRPNnCvtcbtpILKi/Luj302eyN8nRKjHHbbiDmttwvlshxZ8UxJHvALtM506IUHba10Q6QX2zCeDAU5/WYRKa6e19r8plROcgGbKYFSq8JW5cWuWT3/rveZM6FnU6ABn9DWsCyfQ5wr2jdBd+xaevGTAScRHA5J493GqL1bBZYKj9yhQFtxJHCAf0++raAVPCZgyPtwTth4TAQisn8gnhM5R+txnW6xK+oflLy0dwEN1YdPLN/h7yuDnyjSMDe9RZT2NKMjok2C6Kux4WBI0KFXKC5Gqwa3Htku4v3WEOWMaVoWOtchQ9BzpQ/etD0ylmzjALQLB+HtndEEm1Jd3tmob42X4hBE8hCce7C3EtGINB33dlx4CK1xBqyGTJEqi69DJRzVL99u98+7kJ1Db9+MaPOfI4B2RY3XbvnSYwecandY//A3bb19FGSdl299ZXbp4zpm8fivzeB1rUAhhmtaA3Iwu/nEQNMkU=");
- public final static SkinData RUDOLPH = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTk1NjgxODIsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2IzZjdlMjhiNTJkZjJjZjhlZWM2NDk2ZmM0NWFlMGQ2NTM0Njc5OGIxYWRjNzM3ZDcxYzBmOTRlNDIyMSJ9fX0=","uUBOTe63CL+qRvtsb2g4AjB2YzxE3N6AUqIsTv8n0jYyPsuXpuOmZPSMEdgDVONywEJ1L4XRx05sjnGu56A8vuXmGI/uHQWuMZzbOSjiFfT3DkEm8zEl5AWpH9dz/t8nZ1WYUIwy0pN5VrZqIr1DAkF6AMh/Qy+FGDw1GG9ReRr80eJ0JiRskpkCpCZIGGjrgwNKAM8JOuNZ4gCQOTRC3etrcfls3qmUMFcVlhuB4bydxSR01i2w0A4b5KpufsJjLKw4InWn2+m/druo8hl9sYuusTeItW0MQmZqCAqXCc9YBnRPQ0hDXFgnPxOh3RwGWiZvL4MnWUVmLwZWh/Fk9QmyVbd7zVao0lxS8YNsKtP8j5B+hs4l9qNohhf0A07bt4oPeTtd5fQeOU5N87fUGuUAcpC4gP9U5WpVY5FFPBvLvGbXdV5jpuAQz4lLSoo1grsP9baR2IBvdN/0awjQWoPJfGOttegubkBHwz3LNcVqvZLtX/M13IDHZa6zQZEX0wsnMX60LeWgBWfTON1l2cSgaPTerHFS2EifJ2LvTBife3s9/4XR6Zth3FLFqxI3MSlqT2hVFRPLke6rBqfqPoWOj2MCykQ70IAwb3oTHcJDJ86V2DdNaU2bZ8V4TjaP+nRobsLJOImoPYEPq23MP36X8gbXEIjmuu8S5xRlrrc=");
- public final static SkinData SANTA = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTk3OTM3NTgsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2MyNTM5ZGFkZDUxYmE5ZTg0YzFhOTE1OTY3NWUxZTJiYWM1NmFlNmFlNTMxNTQyZDI1YTlkM2Q1YzQ2ODZmNiJ9fX0=","gvLc0Vo6+1vl17vrFCbK1eNqa4/ix4xiwcWae7WOCvqiVIX4sdIPagOGUrKsDdEhuWCKkTWILGP1K3wYfC9v/0mXZvbu0sRln+APTOsswMkQmbKcA1zTFTMpwEI+nIMzYJSbIx5wjz28K5hDf/umtHH2GADTENdJGGUtU4CyEdeHTzcqIAEV3bcMLkfTKvwKUWqI5gZbbercqmDeGkmXVS9297a9paRX1NfEL9pFT0pjdH3tCjgvvKfAwGC6tYtvTFbfcJocqgI+PI2f5OFf62A4XjWwWFi4wxCHVYNpqs/XTbfF64K7KVE0d9gsLjJoB8DMZPxlNpMFA0R5OIW6Q7Qjyz9IKxUqEYRCQbuUKpHyNDcmVKcTJRwBpCHeqAbTbweZHd5tzrT/terWhLEMsK1+lH2KBfIRIRB9kd3epyShNjSEKoly6uRXVxU+IJtfcq0aFVZlwgG3c1Ds9jbsNJV158e1n6WCmvT00RLdvpcIekwUKODhi3zFeFkrVvV50tGYqXLRZenitLJvDzx4c0IGK4krALrUS0oybinBS7/GmW3Ktz3xbGKZSzzaDw0EKB7Y6XHdb4yqR1xS7lAWgv4cNDEIUSzUDJ7HpmDCIF2A5kPS4XVYFCclyR6qPGD5e+9apVhBMz4lfYlT1IfRAUQlucO4UpAlkXs7ho3pQXU=");
+ public final static SkinData PRESENT = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTk3MDIxNjIsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2U2YzRkZWQwNTdjMjhiMTU0NjVkYzQzNmFmODIyYTNkZTY4NzgyZTZjMzgyOGMzMmFhYWE4ZjRiOTIzOWVjIn19fQ==", "rJNlxTqHHmOoWwbXdMQLcj0P9w/PIr/hWKXH0nbhm/S2CFo/zfefffZlnQmpKCgn1Y8tXvcRwLGQ4CLpm9m2ZrKprSWRhrnOtZWYabrhExQESEammS3TY81VoNt+4On0pAGBippz/bRfWLuDne2rDbhuljnqvxjROmxpky7gRCU06VMlm2WLFC5XYJkiAaOXBqzpiHMMRPNnCvtcbtpILKi/Luj302eyN8nRKjHHbbiDmttwvlshxZ8UxJHvALtM506IUHba10Q6QX2zCeDAU5/WYRKa6e19r8plROcgGbKYFSq8JW5cWuWT3/rveZM6FnU6ABn9DWsCyfQ5wr2jdBd+xaevGTAScRHA5J493GqL1bBZYKj9yhQFtxJHCAf0++raAVPCZgyPtwTth4TAQisn8gnhM5R+txnW6xK+oflLy0dwEN1YdPLN/h7yuDnyjSMDe9RZT2NKMjok2C6Kux4WBI0KFXKC5Gqwa3Htku4v3WEOWMaVoWOtchQ9BzpQ/etD0ylmzjALQLB+HtndEEm1Jd3tmob42X4hBE8hCce7C3EtGINB33dlx4CK1xBqyGTJEqi69DJRzVL99u98+7kJ1Db9+MaPOfI4B2RY3XbvnSYwecandY//A3bb19FGSdl299ZXbp4zpm8fivzeB1rUAhhmtaA3Iwu/nEQNMkU=");
+ public final static SkinData RUDOLPH = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTk1NjgxODIsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2IzZjdlMjhiNTJkZjJjZjhlZWM2NDk2ZmM0NWFlMGQ2NTM0Njc5OGIxYWRjNzM3ZDcxYzBmOTRlNDIyMSJ9fX0=", "uUBOTe63CL+qRvtsb2g4AjB2YzxE3N6AUqIsTv8n0jYyPsuXpuOmZPSMEdgDVONywEJ1L4XRx05sjnGu56A8vuXmGI/uHQWuMZzbOSjiFfT3DkEm8zEl5AWpH9dz/t8nZ1WYUIwy0pN5VrZqIr1DAkF6AMh/Qy+FGDw1GG9ReRr80eJ0JiRskpkCpCZIGGjrgwNKAM8JOuNZ4gCQOTRC3etrcfls3qmUMFcVlhuB4bydxSR01i2w0A4b5KpufsJjLKw4InWn2+m/druo8hl9sYuusTeItW0MQmZqCAqXCc9YBnRPQ0hDXFgnPxOh3RwGWiZvL4MnWUVmLwZWh/Fk9QmyVbd7zVao0lxS8YNsKtP8j5B+hs4l9qNohhf0A07bt4oPeTtd5fQeOU5N87fUGuUAcpC4gP9U5WpVY5FFPBvLvGbXdV5jpuAQz4lLSoo1grsP9baR2IBvdN/0awjQWoPJfGOttegubkBHwz3LNcVqvZLtX/M13IDHZa6zQZEX0wsnMX60LeWgBWfTON1l2cSgaPTerHFS2EifJ2LvTBife3s9/4XR6Zth3FLFqxI3MSlqT2hVFRPLke6rBqfqPoWOj2MCykQ70IAwb3oTHcJDJ86V2DdNaU2bZ8V4TjaP+nRobsLJOImoPYEPq23MP36X8gbXEIjmuu8S5xRlrrc=");
+ public final static SkinData SANTA = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTk3OTM3NTgsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2MyNTM5ZGFkZDUxYmE5ZTg0YzFhOTE1OTY3NWUxZTJiYWM1NmFlNmFlNTMxNTQyZDI1YTlkM2Q1YzQ2ODZmNiJ9fX0=", "gvLc0Vo6+1vl17vrFCbK1eNqa4/ix4xiwcWae7WOCvqiVIX4sdIPagOGUrKsDdEhuWCKkTWILGP1K3wYfC9v/0mXZvbu0sRln+APTOsswMkQmbKcA1zTFTMpwEI+nIMzYJSbIx5wjz28K5hDf/umtHH2GADTENdJGGUtU4CyEdeHTzcqIAEV3bcMLkfTKvwKUWqI5gZbbercqmDeGkmXVS9297a9paRX1NfEL9pFT0pjdH3tCjgvvKfAwGC6tYtvTFbfcJocqgI+PI2f5OFf62A4XjWwWFi4wxCHVYNpqs/XTbfF64K7KVE0d9gsLjJoB8DMZPxlNpMFA0R5OIW6Q7Qjyz9IKxUqEYRCQbuUKpHyNDcmVKcTJRwBpCHeqAbTbweZHd5tzrT/terWhLEMsK1+lH2KBfIRIRB9kd3epyShNjSEKoly6uRXVxU+IJtfcq0aFVZlwgG3c1Ds9jbsNJV158e1n6WCmvT00RLdvpcIekwUKODhi3zFeFkrVvV50tGYqXLRZenitLJvDzx4c0IGK4krALrUS0oybinBS7/GmW3Ktz3xbGKZSzzaDw0EKB7Y6XHdb4yqR1xS7lAWgv4cNDEIUSzUDJ7HpmDCIF2A5kPS4XVYFCclyR6qPGD5e+9apVhBMz4lfYlT1IfRAUQlucO4UpAlkXs7ho3pQXU=");
public final static SkinData SECRET_PACKAGE = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTUxMTAzNzE3OTIsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2QyNWI5YTRjOWRhOThkZTliZmIwZDNjOWI1M2MzMjJhMjgxN2IyMTMxOTQzY2E1YWM2NTBjZThmMzEzZjdhIn19fQ==", "Wb5T0Zhp1RVt78V/i8dYrwZCNT0xZIRe3LvL0bngH498f8Jrl43KHgTi4f299zE9giVynkTogGhJ8inq/xqFCRctl7Nn9L3LVu78uQwt+fs+o+kw/Qc+lggFSjEIc+fc13AZndpec0Df46Kh/OGD7NXbtbLb6TE/0dU2RwQlvZrZ/QHYJb8OJ6aUcnHvAZim8NUtG/nlZtSClepHVSuKdNnfzoF9rFVFA/x4jTr6mZYPZ33YgQd2oTAPk+qE3iN+0InjZQNs2YLoKFmFrgzn+tGvNApC0siF0HEZGQCFIwJOtnBsasGoxujIrln/ZdOil+5ac4VWInXr8lKgY0Q3Ocy8/0cJl+E/XqB+ztG29zhB8B1zdHBfJr+MgeSIqBCPx4SCtY6r7gnMlQYG+uVx5NP3S5aJW/cEfDyXmpCykIcBPzeErnKC0SiAqXkCVNjWJpX6qRWvWMXqS69w6ht6qHvEY2GxlZUb5AP+JgFlsl3hJDms6EPvM4zNL0Ko4oWIBzwYRQXiemrP9TGgyo0aL1RcQ0JgBFO2hSo37PK0YL3tUPgteJXzm21wu0TiZLkLCWSgMUfYfvVnhTa+xzod0xvfujpN6Y1DUTdcf8WS8TRYw2JigSkWrRW0fXPBCtTtQN5jiwM5/HrTpNLzg03J6SpfZ+rr8Rhq0S/8beQOMas=");
- public final static SkinData SNOWMAN = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTk4Nzk5NDIsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzEzMTgxYWViODQzODk3NzM1ZDQwMmIyNDk2OTQxNmZkYjBjZTM0YTZiOTM3ODE2MjQzNzU2ZTlkYWU1OGUzIn19fQ==","NZvsNu+HQ5uvGWq6O8VNDGq9A145bmk2IkHiz916uRVPMRqqCI/zwhKWNLlFACE/feuLkhYAois29ec6sVVOtHIoNA+S5q1Mb/Vjc3TJQxzqmx2FZOhJiIttFwYuo9WomQKBqrPMSJ9tpQig4wzoqldeeTjWC3dLz7JeX+gkzinryVjG7NNN9L5hXK5/BBxRcrtwmXJfUlSANyrd8RZW7mEUgU8yxlzdqTu0w7bZLjQNd4vciwoF3NelXDorMIIqiHTkuQesG91Njtu25VCUDK3nXbqEnZw2ZtxB5fT5G2Omm/vkNSRXc0P7iqchVowdYQcMlQUsp65xpkBbFS4LwjzDkYIfLmF++hePb8z72Gz77FxhO5sRLGreSH227McyL/0CtWNKm9ZZIfQtZZjEZTj9+eiJMCloCMg3yWa1VBOiLHzz0wY6gGklccIImPyXEg7E0dIK8qYseJMhmmBNZ8pDOkbUDp3mRlrQ2iyClgQkbuR63j79IBUaCxmsa3NnrAtaJklzd9mzkHXfMBh2XT7Gl8AhJS6JK5kCvip1rBBI8yjrsjE/E+lyJFIbC4rXxyMDGZWkcdrd7U4ZFYKiLHbzdFRqX+11qs9xO2BvomGXkATCzYmOf2kQ86R6rNN0+JfE4QpKzj2WWt3C8ky2qpuXZz29p0816E3/qseYtgg=");
+ public final static SkinData SNOWMAN = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTAwMTk4Nzk5NDIsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzEzMTgxYWViODQzODk3NzM1ZDQwMmIyNDk2OTQxNmZkYjBjZTM0YTZiOTM3ODE2MjQzNzU2ZTlkYWU1OGUzIn19fQ==", "NZvsNu+HQ5uvGWq6O8VNDGq9A145bmk2IkHiz916uRVPMRqqCI/zwhKWNLlFACE/feuLkhYAois29ec6sVVOtHIoNA+S5q1Mb/Vjc3TJQxzqmx2FZOhJiIttFwYuo9WomQKBqrPMSJ9tpQig4wzoqldeeTjWC3dLz7JeX+gkzinryVjG7NNN9L5hXK5/BBxRcrtwmXJfUlSANyrd8RZW7mEUgU8yxlzdqTu0w7bZLjQNd4vciwoF3NelXDorMIIqiHTkuQesG91Njtu25VCUDK3nXbqEnZw2ZtxB5fT5G2Omm/vkNSRXc0P7iqchVowdYQcMlQUsp65xpkBbFS4LwjzDkYIfLmF++hePb8z72Gz77FxhO5sRLGreSH227McyL/0CtWNKm9ZZIfQtZZjEZTj9+eiJMCloCMg3yWa1VBOiLHzz0wY6gGklccIImPyXEg7E0dIK8qYseJMhmmBNZ8pDOkbUDp3mRlrQ2iyClgQkbuR63j79IBUaCxmsa3NnrAtaJklzd9mzkHXfMBh2XT7Gl8AhJS6JK5kCvip1rBBI8yjrsjE/E+lyJFIbC4rXxyMDGZWkcdrd7U4ZFYKiLHbzdFRqX+11qs9xO2BvomGXkATCzYmOf2kQ86R6rNN0+JfE4QpKzj2WWt3C8ky2qpuXZz29p0816E3/qseYtgg=");
public final static SkinData TEDDY_BEAR = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTUxMDkzOTE4MjYsInByb2ZpbGVJZCI6ImE5ZDBjMDcyYmYxOTQwYTFhMTkzNjhkMDlkNTAwMjZlIiwicHJvZmlsZU5hbWUiOiJTcGlyaXR1c1NhbmN0dXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzQ0OTU4ZDdjNjlhZTQ4NGM2NWYzMTM0N2NkY2M5MmM2OWY1NDA2ODA1YjUzNjUyYTc1YThlZDc5OWRmNyJ9fX0=", "sNTRV9jTjLszUmyaqyEG7N8d5RM1jbwMSXi34S2EkVmIjWsowfSMnHRQqqgZfxcyqBM5I7MljtB84IeQWu4rqhyFrM9blWvtowjijFIOgKCs97q2sswv9iauU6ohvgTpgN5B0Q16MJmMIgZU8d8TATtEaIzq2eg6Ve1AJlNnW4huGNsoNfm8WdVU1tZmsYAwtVP/ryvhyj7mHyVF27m0Sm4fZRf/lHH5gEJYB4JHSAoEhjPIQOdkgRMJRrWGOfhhiGs3kEWmsRGfIPFo2ZJfcu+TFV2rd4Q+A1LmY8kimnzdKX3InXeKbk8qzcgqGNro4XFnSiHo1d6/B+N0JeYOTITYRQ6u24rNSUh5ezbG01iikVFCfrgb7UR6utoLK15F4/fmhpex+BJpmyZoXAqk08tZws/5wsIWQ1okrGcbBKWEHhw2ekUc82US21/W53vd657UBg7FuqM4FhkAqmsYPvYLMpNYxxmDJaI8uJyU7cnGFYyBaFlqUxfJUfcFTwWo10JO3yp5FjqeCQa7rFvfpsqw3w2mBpJmlZ5HRjfS5pmhk0QiY0TRfwZfFemkuZYnNbO82qLUm+6zTm0fbC90Swt8nNr/42ajzEoUjnL6VsERIXS5/fPwjftbQAC60ujy8yo66Sp3sSAALNg5zjM+Uizkq2f9Axc+kind22hp10M=");
public final static SkinData UNCLE_SAM = new SkinData("eyJ0aW1lc3RhbXAiOjE0NjYxODA0NjY4NTcsInByb2ZpbGVJZCI6IjlmY2FlZDhiMTRiNTRmN2ZhNjRjYjYwNDBlNzA1MjcyIiwicHJvZmlsZU5hbWUiOiJMQ2FzdHIxIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jYzM1YWRmZTQ3ODBjNmU2NTk4YTJlYzk2ZjdhZGQ5ZDc4NjljMjBlZjRmYjEyNjk2NmJhOGFlMDRlOWRhIn19fQ==", "NmJ+hXmvwQlYFYY7YVQWRr11yBbAfJP+jk11SQ91gUUtJJjb4v8RFbNu5UXNCKxYj3BPtldqshG1maNB0NWJRud7ZyAdHc0JMmR1vtHEge9Hhet4fLyyaZ9rZn4BvD9Guqgv9H/mZzUzrft9TIho0Qbu/U++lVsbZXC2GrJDDMyLnYr9C7f+FUnr0z4WvkNcg23SHBOYkOYT95NSdykIka3c3v+/HvSvuwOnMsfVxqLyCZLpo20vamBJ1uK1dmx2+TVGnUPlofFHRdOXOpJc+YmicJvrsQR6a9zlvnTbU4MYClMOKvjLe6aX5Af+n8Gw3oKcm0PuR8CPLyf9kjcmUF6XMiEXAWWJtCgvhCiFV5/mQQH3cQ1kqk4BDLUxMVhG5tzjKLoQQy39cFM32ee+QFjXlzy59meC8jgvPmOVU3GpJ32XWOtaXMCyeJrhz2QVKRLEr2KZgz8Pd8VrHARXVZsNYEasj8z0cHjgSJqTU9kD90CC+4YpvdyRBRqbNQig5KuGCqUHKgflsEsM7YrFRKP5As1LgqYQfqRAMmLSo47eW0onOwchC9wCqqisPlYSuDRt4Mun/KFGqYh1Sghn8/gzu49La8BpwlekjVEoPEcDaIIgnFzOvgmmgMANkoJ3PzhHoHMoXtObe3eSTi+eYp4qAQVzkTxfF3WXY2fui1M=");
@@ -40,49 +77,39 @@ public class SkinData
//public final static SkinData CHISS = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTk1NDI5NjgyNDEsInByb2ZpbGVJZCI6IjFkMmJmZTYxN2ViZDQ0NWRiYTdkODM1NGEwZmZkMWVhIiwicHJvZmlsZU5hbWUiOiJDaGlzcyIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTg3MmNkMzRjY2IzMTIxYjRjNmEzOGFjM2JmOGVkM2UwMzk3YmQ2YTg4NDI4YjdhZmM2ZTUyNTI4NTVhMzQzIiwibWV0YWRhdGEiOnsibW9kZWwiOiJzbGltIn19fX0=", "hNTLRA2acZYx2dM90lnJN8FMK/ceD3+AxKNdD5FrXzxGtYL4C1Jr/vbTE0UosmwFP3wScNEW/fuDOjeZRjZHMJdvgDZMlMK/5KDhOY6sj/RS9RckztsgummSyjH/hdDn7TWWfhZLMbiia/K0VReI9eq2yD6zGQpvMlz5hB/5SX5YHWXvCah3TL4UzYSlSVDlwY/Q3sVuIZUr8m/LIXJwniJKLGo6tUgtiJd9eseOsbBpVjzCUtLD8A9WBe2/eODgmLfqEvXESIoDRG8vL2nPSXWma/YolYHIl32/i+ZxVD7dRRaXQFYSiLI24EtzX1pPhMjyaTLazP9abH43J6J31w02pKM7N/xTa62020L/YfRRKGT5lygEDb1NMoSpAjszPxah+Ra2/L+yUWEI8cMES6I4mIJ00tclPjWK01xhIn3tqg+y2gqsGHwPhu/7vmF5NirNfKFw0qciKNBfbCAF7ae+mkUKjmAPuvBUBqQb7BOcpNVWsCo/XvzmiZZYsf5P4Uwz8LqUK4uH6V/5dg7lY2Xg3+IUylsrDqLGFDI8iy/NdjIQMbuRadh4IDO6DcmxBri2Ax4JNBPBTnRezge8uq37MZcft/IXQgFWKB9RtidVEACaTOkRj27k+Ojnkki+j44k0wZB47hiXFUHMCHl3a0SVdQe15ZbVsQj/HAvAS0=");
//public final static SkinData DEFEK7 = new SkinData("eyJ0aW1lc3RhbXAiOjE0NTk1NDI3ODkwNTksInByb2ZpbGVJZCI6Ijg5ZDQ2M2Y3MjNlYzQ3MGE4MjQ0NDU3ZjBjOGQ4NjFjIiwicHJvZmlsZU5hbWUiOiJkZWZlazciLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2JmYWNjOWM4ZjhlY2E1OWU0NTE4MTUxZmE4OGFiMDZjOTFmNjM3OTE2NzJmMTRlNGYzODY3YTI2OTVlN2NmYmYifSwiQ0FQRSI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzIyYjljNWVhNzYzYzg2ZmM1Y2FlYTMzZDgyYjBmYTY1YTdjMjI4ZmQzMjFiYTU0NzY2ZWE5NWEzZDBiOTc5MyJ9fX0=", "jBoRvkhQXz+nap8yJJIZ+4HClMItWODumeSOYjXytP3WWKHK0UMq0xC/keXsnmvo89lMRdRbknPt2ZX5Flgyjgr4Rt0KtDvpL/hG4BUsTWryUZZMKxdd6DkZXYRtTogLUfHeDYIz+cZQ0aXGMtvX/ZYTXJfMi6FYbIHY/qEEDnWhDX5y+SPpaJaZByPsvzi+qbfcFGnJ6nqi9ccyZYnYpnI2IVBM/yO/VRXWHxfqvJ0VVvv5KsGmVbko2Jxo0SDCxUL2UTH2+eol53FxhkkC+m2geC14k1zsZQLHDF3BgAG9+kFJ4UEoYRKF2Gy1FxeDCJtjYNdrYR8fdaUKRMcpBgEs+ZGe2U9EVVS/ZcBCjB7S+1Ne2bPzPFzTQPuBoMgggo1xbxBmQ5NyhYo4gwgj/xjSLIhb+5h7ioN1URfSRcfYdVv6RRO9l/u9l09jEom8y/jGRviefpEr+/e9iAl5Dd/6nzQgosBQja3NSfqYZmyuet2eI9zu61CObDTpR6yaCbNgBe/lWofRfULdpJpgjb4UNTBom3q82FcCiOe02OekGPw4+YlilhICBhajF5JzN8FKAdqI1osDcX3KuJgikYIW3voNaOP5YN3GXgilJNdou20KFC8ICq68HglgX7/0rLrWKIEoswnINIM6HcJbQuXncVPwQhV6K34Hlt/Na60=");
-
+
private Property _skinProperty;
-
+
public SkinData(String value, String signature)
{
_skinProperty = new Property("textures", value, signature);
}
-
- public SkinData(GameProfile profile)
+
+ private SkinData(GameProfile profile)
{
_skinProperty = profile.getProperties().get("textures").iterator().next();
}
-
- public SkinData(Player player)
- {
- this(((CraftPlayer)player).getProfile());
- }
-
+
public ItemStack getSkull()
{
- NBTTagCompound arrayElement = new NBTTagCompound();
- arrayElement.setString("Value", _skinProperty.getValue());
- arrayElement.setString("Signature", _skinProperty.getSignature());
-
- NBTTagList textures = new NBTTagList();
- textures.add(arrayElement);
-
- NBTTagCompound properties = new NBTTagCompound();
- properties.set("textures", textures);
-
- NBTTagCompound skullOwner = new NBTTagCompound();
- skullOwner.set("Properties", properties);
- skullOwner.set("Name", new NBTTagString(getUnusedSkullName()));
-
- NBTTagCompound tag = new NBTTagCompound();
- tag.set("SkullOwner", skullOwner);
-
-
- net.minecraft.server.v1_8_R3.ItemStack nmsItem = new net.minecraft.server.v1_8_R3.ItemStack(Item.REGISTRY.get(new MinecraftKey("skull")), 1, 3);
- nmsItem.setTag(tag);
-
-
- return CraftItemStack.asBukkitCopy(nmsItem);
+ ItemStack item = new ItemStack(Material.SKULL_ITEM, 1, (byte) 3);
+ SkullMeta meta = (SkullMeta) item.getItemMeta();
+
+ GameProfile data = new GameProfile(UUID.randomUUID(), getUnusedSkullName());
+ data.getProperties().put("textures", getProperty());
+
+ try
+ {
+ PROFILE_FIELD.set(meta, data);
+ }
+ catch (ReflectiveOperationException t)
+ {
+ t.printStackTrace();
+ }
+
+ item.setItemMeta(meta);
+
+ return item;
}
public ItemStack getSkull(String name, List lore)
@@ -94,16 +121,51 @@ public class SkinData
stack.setItemMeta(meta);
return stack;
}
-
+
public Property getProperty()
{
return new Property(_skinProperty.getName(), _skinProperty.getValue(), _skinProperty.getSignature());
}
-
+
public static String getUnusedSkullName()
{
_nameCount++;
return "_" + _nameCount;
}
+
+ /*
+ * Creates a {@link SkinData} from a given {@link GameProfile}.
+ * Will return null if the GameProfile does not have any texture data
+ *
+ * @param input The GameProfile to get textures from
+ * @param requireSecure Whether the SkinData should be signed
+ * @param useDefaultSkins Whether to subsitute an Alex or Steve skin if no textures are present
+ *
+ * @return The SkinData, or null if no textures are present
+ */
+ public static SkinData constructFromGameProfile(GameProfile input, boolean requireSecure, boolean useDefaultSkins)
+ {
+ final Map map = Maps.newHashMap();
+
+ try
+ {
+ map.putAll(MinecraftServer.getServer().aD().getTextures(input, requireSecure));
+ }
+ catch (InsecureTextureException ignored)
+ {
+ }
+
+ if (map.containsKey(MinecraftProfileTexture.Type.SKIN))
+ {
+ return new SkinData(input);
+ }
+
+ if (useDefaultSkins)
+ {
+ return UtilPlayer.isSlimSkin(input.getId()) ? SkinData.ALEX : SkinData.STEVE;
+ }
+
+ return null;
+ }
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/F.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/F.java
index aef32b218..ed3548020 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/F.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/F.java
@@ -2,8 +2,8 @@ package mineplex.core.common.util;
import org.bukkit.ChatColor;
-import mineplex.core.common.CurrencyType;
import mineplex.core.common.Rank;
+import mineplex.core.common.currency.Currency;
public class F
{
@@ -204,7 +204,7 @@ public class F
return out;
}
- public static String currency(CurrencyType type, int amount)
+ public static String currency(Currency type, int amount)
{
return type.getString(amount) + ChatColor.RESET + C.mBody;
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAction.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAction.java
index 50d8fe661..887369e33 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAction.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAction.java
@@ -1,5 +1,8 @@
package mineplex.core.common.util;
+import mineplex.core.common.events.EntityVelocityChangeEvent;
+
+import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
@@ -49,6 +52,15 @@ public class UtilAction
if (groundBoost)
if (UtilEnt.isGrounded(ent))
vec.setY(vec.getY() + 0.2);
+
+ EntityVelocityChangeEvent event = new EntityVelocityChangeEvent(ent, vec);
+ Bukkit.getPluginManager().callEvent(event);
+
+ if (event.isCancelled())
+ {
+ return;
+ }
+ vec = event.getVelocity();
//Velocity
ent.setFallDistance(0);
@@ -65,6 +77,16 @@ public class UtilAction
public static void zeroVelocity(Entity ent)
{
Vector vec = new Vector(0,0,0);
+
+ EntityVelocityChangeEvent event = new EntityVelocityChangeEvent(ent, vec);
+ Bukkit.getPluginManager().callEvent(event);
+
+ if (event.isCancelled())
+ {
+ return;
+ }
+ vec = event.getVelocity();
+
ent.setFallDistance(0);
//Store It!
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java
index 1945a0e1b..adcc05264 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java
@@ -1,25 +1,23 @@
package mineplex.core.common.util;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.stream.Stream;
-
+import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import org.bukkit.Location;
import org.bukkit.block.Block;
+import org.bukkit.craftbukkit.v1_8_R3.TrigMath;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
-import net.minecraft.server.v1_8_R3.AxisAlignedBB;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
public class UtilAlg
{
@@ -56,6 +54,17 @@ public class UtilAlg
{
return to.clone().subtract(from).normalize();
}
+
+ public static double[] getTrajectory(double srcx, double srcy, double srcz, double dstx, double dsty, double dstz)
+ {
+ double dx = dstx - srcx;
+ double dy = dsty - srcy;
+ double dz = dstz - srcz;
+
+ double len = Math.sqrt(dx * dx + dy * dy + dz * dz);
+
+ return new double[] { dx / len, dy / len, dz / len};
+ }
public static Vector getTrajectory2d(Entity from, Entity to)
{
@@ -98,28 +107,42 @@ public class UtilAlg
public static float GetPitch(Vector vec)
{
- double x = vec.getX();
- double y = vec.getY();
- double z = vec.getZ();
+ return GetPitch(vec.getX(), vec.getY(), vec.getZ());
+ }
+
+ public static float GetPitch(double[] vec)
+ {
+ return GetPitch(vec[0], vec[1], vec[2]);
+ }
+
+ public static float GetPitch(double x, double y, double z)
+ {
double xz = Math.sqrt((x*x) + (z*z));
- double pitch = Math.toDegrees(Math.atan(xz/y));
+ double pitch = Math.toDegrees(TrigMath.atan(xz/y));
if (y <= 0) pitch += 90;
else pitch -= 90;
-
- //Fix for two vectors at same Y giving 180
+
+ //Fix for two vectors at same Y giving 180
if (pitch == 180)
pitch = 0;
-
+
return (float) pitch;
}
public static float GetYaw(Vector vec)
{
- double x = vec.getX();
- double z = vec.getZ();
-
- double yaw = Math.toDegrees(Math.atan((-x)/z));
+ return GetYaw(vec.getX(), vec.getY(), vec.getZ());
+ }
+
+ public static float GetYaw(double[] vec)
+ {
+ return GetYaw(vec[0], vec[1], vec[2]);
+ }
+
+ public static float GetYaw(double x, double y, double z)
+ {
+ double yaw = Math.toDegrees(TrigMath.atan((-x)/z));
if (z < 0) yaw += 180;
return (float) yaw;
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java
index e1113d49b..00a28781d 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java
@@ -1616,4 +1616,35 @@ public class UtilBlock
}
}
+
+ public static boolean water(Material type)
+ {
+ return type == Material.WATER || type == Material.STATIONARY_WATER;
+ }
+
+ public static boolean lava(Material type)
+ {
+ return type == Material.LAVA || type == Material.STATIONARY_LAVA;
+ }
+
+ public static boolean liquid(Material type)
+ {
+ return water(type) || lava(type);
+ }
+
+ public static boolean water(Block block)
+ {
+ return water(block.getType());
+ }
+
+ public static boolean lava(Block block)
+ {
+ return lava(block.getType());
+ }
+
+ public static boolean liquid(Block block)
+ {
+ return liquid(block.getType());
+ }
+
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java
index 786f816a2..0e78782db 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java
@@ -12,6 +12,7 @@ import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
+import org.bukkit.craftbukkit.v1_8_R3.TrigMath;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreature;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity;
@@ -295,7 +296,7 @@ public class UtilEnt
Vector dir = entity.getEyeLocation().toVector().subtract(location.toVector()).normalize();
Location loc = entity.getEyeLocation().clone();
- loc.setYaw(180 - (float) Math.toDegrees(Math.atan2(dir.getX(), dir.getZ())));
+ loc.setYaw(180 - (float) Math.toDegrees(TrigMath.atan2(dir.getX(), dir.getZ())));
loc.setPitch(90 - (float) Math.toDegrees(Math.acos(dir.getY())));
Rotate(entity, loc.getYaw(), loc.getPitch());
@@ -700,6 +701,13 @@ public class UtilEnt
return CreatureLook(ent, UtilAlg.GetPitch(vec), UtilAlg.GetYaw(vec));
}
+ public static boolean CreatureLook(Entity ent, double srcx, double srcy, double srcz, double dstx, double dsty, double dstz)
+ {
+ double[] vec = UtilAlg.getTrajectory(srcx, srcy, srcz, dstx, dsty, dstz);
+
+ return CreatureLook(ent, UtilAlg.GetPitch(vec), UtilAlg.GetYaw(vec));
+ }
+
public static boolean CreatureLook(Entity ent, Vector target)
{
return CreatureLook(ent, UtilAlg.GetPitch(target), UtilAlg.GetYaw(target));
@@ -737,16 +745,19 @@ public class UtilEnt
EntityTrackerEntry entry = (EntityTrackerEntry) ((WorldServer) ec.getWorld()).tracker.trackedEntities.get(ec.getId());
- byte ya = (byte) (yaw * 256.0F / 360.0F);
- byte pi = (byte) (pitch * 256.0F / 360.0F);
+ if (entry != null)
+ {
+ byte ya = (byte) (yaw * 256.0F / 360.0F);
+ byte pi = (byte) (pitch * 256.0F / 360.0F);
- entry.yRot = ya;
- entry.xRot = pi;
- entry.i = ya;
+ entry.yRot = ya;
+ entry.xRot = pi;
+ entry.i = ya;
- // Looks like both packets need to be sent. EntityLook packet for body yaw and head pitch. Head rotation for head yaw.
- entry.broadcast(new PacketPlayOutEntity.PacketPlayOutEntityLook(ent.getEntityId(), ya, pi, ec.onGround));
- entry.broadcast(new PacketPlayOutEntityHeadRotation(ec, ya));
+ // Looks like both packets need to be sent. EntityLook packet for body yaw and head pitch. Head rotation for head yaw.
+ entry.broadcast(new PacketPlayOutEntity.PacketPlayOutEntityLook(ent.getEntityId(), ya, pi, ec.onGround));
+ entry.broadcast(new PacketPlayOutEntityHeadRotation(ec, ya));
+ }
return true;
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java
index 9f5f14739..bac5ec7fb 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java
@@ -1,8 +1,16 @@
package mineplex.core.common.util;
-import java.util.*;
-
-import net.minecraft.server.v1_8_R3.*;
+import mineplex.core.common.MinecraftVersion;
+import mineplex.core.common.events.PlayerMessageEvent;
+import net.md_5.bungee.api.chat.ClickEvent;
+import net.md_5.bungee.api.chat.ClickEvent.Action;
+import net.md_5.bungee.api.chat.HoverEvent;
+import net.md_5.bungee.api.chat.TextComponent;
+import net.minecraft.server.v1_8_R3.EntityPlayer;
+import net.minecraft.server.v1_8_R3.Packet;
+import net.minecraft.server.v1_8_R3.PacketPlayOutWorldBorder;
+import net.minecraft.server.v1_8_R3.PlayerConnection;
+import net.minecraft.server.v1_8_R3.WorldBorder;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
@@ -20,8 +28,17 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.util.BlockIterator;
import org.bukkit.util.Vector;
-import mineplex.core.common.MinecraftVersion;
-import mineplex.core.common.events.PlayerMessageEvent;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
public class UtilPlayer
{
@@ -179,7 +196,7 @@ public class UtilPlayer
for (Entity entity : p.getNearbyEntities(range, range, range))
{
- if (entity == p || UtilPlayer.isSpectator(entity))
+ if (entity == p || UtilPlayer.isSpectator(entity) || !(entity instanceof Player))
continue;
double theirDist = p.getEyeLocation().distance(entity.getLocation());
@@ -938,9 +955,79 @@ public class UtilPlayer
return true;
}
+
public static void removeAllowedCommands(Player player)
{
if (ALLOWED_COMMANDS.containsKey(player.getUniqueId()))
ALLOWED_COMMANDS.remove(player.getUniqueId());
}
+
+ /**
+ * Sends a formatted clickable accept or deny (or view) message to a player
+ * Both ACCEPT and DENY will always be sent, but VIEW will only be sent when viewCommand
is not null
+ *
+ * @param player The player to send the message to
+ * @param header The message header, such as Party or Game
+ * @param acceptCommand The command to be run if ACCEPT is clicked
+ * @param acceptDisplayText The text displayed when hovering over ACCEPT
+ * @param declineCommand The command to be run when DENY is clicked
+ * @param declineDisplayText The text displayed when hovering over DENY
+ * @param viewCommand Optional
The command to be run when VIEW is clicked
+ * @param viewDisplayText Optional
The text displayed when hovering over VIEW
+ */
+ public static void sendAcceptOrDeny(Player player, String header,
+ String acceptCommand, String acceptDisplayText,
+ String declineCommand, String declineDisplayText,
+ String viewCommand, String viewDisplayText)
+ {
+ TextComponent textComponent = new TextComponent(F.main(header, "Reply: "));
+
+ TextComponent accept = new TextComponent("ACCEPT");
+ accept.setColor(net.md_5.bungee.api.ChatColor.GREEN);
+ accept.setBold(true);
+ accept.setClickEvent(new ClickEvent(Action.RUN_COMMAND, acceptCommand));
+ accept.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{
+ new TextComponent(acceptDisplayText)
+ }));
+
+ textComponent.addExtra(accept);
+ textComponent.addExtra(" ");
+
+ TextComponent deny = new TextComponent("DENY");
+ deny.setColor(net.md_5.bungee.api.ChatColor.RED);
+ deny.setBold(true);
+ deny.setClickEvent(new ClickEvent(Action.RUN_COMMAND, declineCommand));
+ deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{
+ new TextComponent(declineDisplayText)
+ }));
+
+ textComponent.addExtra(deny);
+
+ if(viewCommand != null)
+ {
+ textComponent.addExtra(" ");
+
+ TextComponent view = new TextComponent("VIEW");
+ view.setColor(net.md_5.bungee.api.ChatColor.YELLOW);
+ view.setBold(true);
+ view.setClickEvent(new ClickEvent(Action.RUN_COMMAND, viewCommand));
+ if(viewDisplayText != null)
+ {
+ view.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{
+ new TextComponent(viewDisplayText)
+ }));
+ }
+ textComponent.addExtra(view);
+ }
+
+ player.spigot().sendMessage(textComponent);
+ }
+
+ /*
+ * Returns whether the UUID belongs to a slim skin
+ */
+ public static boolean isSlimSkin(UUID playerUUID)
+ {
+ return (playerUUID.hashCode() & 1) == 1;
+ }
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilServer.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilServer.java
index 886d8e26d..b0ccc63ef 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilServer.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilServer.java
@@ -111,7 +111,7 @@ public class UtilServer
HandlerList.unregisterAll(listener);
}
- public static Plugin getPlugin()
+ public static JavaPlugin getPlugin()
{
return JavaPlugin.getProvidingPlugin(UtilServer.class);
}
@@ -193,6 +193,11 @@ public class UtilServer
return _serverName;
}
+ public static String getServerNameFromConfig()
+ {
+ return getPlugin().getConfig().getString("serverstatus.name");
+ }
+
public static Collection GetPlayers()
{
return Lists.newArrayList(getPlayers());
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilTasks.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilTasks.java
new file mode 100644
index 000000000..6e71d4002
--- /dev/null
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilTasks.java
@@ -0,0 +1,40 @@
+package mineplex.core.common.util;
+
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitScheduler;
+
+import java.util.function.Consumer;
+
+public class UtilTasks
+{
+ private static final JavaPlugin LOADING_PLUGIN = JavaPlugin.getProvidingPlugin(UtilTasks.class);
+
+ private static final BukkitScheduler SCHEDULER = Bukkit.getScheduler();
+
+ public static Runnable onMainThread(Runnable original)
+ {
+ return () ->
+ {
+ if (Bukkit.isPrimaryThread())
+ {
+ original.run();
+ }
+ else
+ {
+ SCHEDULER.runTask(LOADING_PLUGIN, original);
+ }
+ };
+ }
+
+ public static Consumer onMainThread(Consumer original)
+ {
+ return t ->
+ {
+ onMainThread(() ->
+ {
+ original.accept(t);
+ });
+ };
+ }
+}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java
index d0825126d..0867db6d4 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java
@@ -1,5 +1,9 @@
package mineplex.core.common.util;
+import org.apache.commons.lang.WordUtils;
+import org.bukkit.ChatColor;
+
+import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
@@ -7,13 +11,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import javax.imageio.ImageIO;
-
-import org.apache.commons.lang.WordUtils;
-import org.bukkit.ChatColor;
-
-import mineplex.core.common.CurrencyType;
-
public class UtilText
{
private static HashMap _characters = new HashMap<>();
@@ -25,7 +22,7 @@ public class UtilText
{
try
{
- InputStream inputStream = CurrencyType.class.getResourceAsStream("/ascii.png");
+ InputStream inputStream = UtilText.class.getResourceAsStream("/ascii.png");
BufferedImage image = ImageIO.read(inputStream);
char[] text = new char[]
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilWorld.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilWorld.java
index 99979144b..86c6083f2 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilWorld.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilWorld.java
@@ -24,7 +24,12 @@ public class UtilWorld
{
return UtilServer.getServer().getWorld(world);
}
-
+
+ public static boolean areChunksEqual(Location first, Location second)
+ {
+ return first.getBlockX() >> 4 == second.getBlockX() >> 4 && first.getBlockZ() >> 4 == second.getBlockZ() >> 4;
+ }
+
public static String chunkToStr(Chunk chunk)
{
if (chunk == null)
diff --git a/Plugins/Mineplex.Core/pom.xml b/Plugins/Mineplex.Core/pom.xml
index 2a88ca1ca..81a567966 100644
--- a/Plugins/Mineplex.Core/pom.xml
+++ b/Plugins/Mineplex.Core/pom.xml
@@ -44,6 +44,11 @@
org.apache.httpcomponents
httpclient
+
+ com.mineplex
+ anticheat
+ 1.1
+
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/CustomTagFix.java b/Plugins/Mineplex.Core/src/mineplex/core/CustomTagFix.java
index 7a32a4aa3..fbbe9c561 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/CustomTagFix.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/CustomTagFix.java
@@ -1,9 +1,12 @@
package mineplex.core;
+import java.util.HashMap;
import java.util.HashSet;
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 mineplex.core.common.DummyEntity;
@@ -53,15 +56,15 @@ import fr.neatmonster.nocheatplus.hooks.NCPHookManager;
public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
{
- private NautHashMap> _entityMap = new NautHashMap>();
- private NautHashMap> _entityNameMap = new NautHashMap>();
- private NautHashMap> _entityRiding = new NautHashMap>();
+ private Map> _entityMap = new HashMap<>();
+ private Map> _entityNameMap = new HashMap<>();
+ private Map> _entityRiding = new HashMap<>();
- private HashSet _loggedIn = new HashSet();
- private HashSet _ignoreIds = new HashSet();
+ private Set _loggedIn = new HashSet<>();
+ private Set _ignoreIds = new HashSet<>();
- private NautHashMap _exemptTimeMap = new NautHashMap();
- private NautHashMap> _doubleStrike = new NautHashMap>();
+ private Map _exemptTimeMap = new HashMap<>();
+ private Map> _doubleStrike = new HashMap<>();
public CustomTagFix(JavaPlugin plugin, PacketHandler packetHandler)
{
@@ -79,10 +82,10 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
- _entityMap.remove(event.getPlayer().getName());
- _entityNameMap.remove(event.getPlayer().getName());
- _entityRiding.remove(event.getPlayer().getName());
- _loggedIn.remove(event.getPlayer().getName());
+ _entityMap.remove(event.getPlayer().getUniqueId());
+ _entityNameMap.remove(event.getPlayer().getUniqueId());
+ _entityRiding.remove(event.getPlayer().getUniqueId());
+ _loggedIn.remove(event.getPlayer().getUniqueId());
}
@EventHandler(priority = EventPriority.LOW)
@@ -122,7 +125,7 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
public void ncpExemptVelocity(final PlayerVelocityEvent event)
{
long ignoreTime = System.currentTimeMillis() + (long) (event.getVelocity().length() * 1500);
-
+
if (_exemptTimeMap.containsKey(event.getPlayer().getUniqueId()))
{
_exemptTimeMap.put(event.getPlayer().getUniqueId(),
@@ -139,7 +142,7 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
if (event.getType() != UpdateType.TICK)
return;
- for (Iterator> iterator = _exemptTimeMap.entrySet().iterator(); iterator.hasNext();)
+ for (Iterator> iterator = _exemptTimeMap.entrySet().iterator(); iterator.hasNext(); )
{
final Entry entry = iterator.next();
@@ -150,12 +153,12 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
}
for (Iterator>> iterator = _doubleStrike.entrySet().iterator(); iterator
- .hasNext();)
+ .hasNext(); )
{
Entry> entry = iterator.next();
for (Iterator> innerIterator = entry.getValue().entrySet().iterator(); innerIterator
- .hasNext();)
+ .hasNext(); )
{
final Entry entry2 = innerIterator.next();
@@ -176,11 +179,11 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
if (event.getType() != UpdateType.SEC)
return;
- for (Iterator iterator = _loggedIn.iterator(); iterator.hasNext();)
+ for (Iterator iterator = _loggedIn.iterator(); iterator.hasNext(); )
{
- String player = iterator.next();
+ UUID player = iterator.next();
- if (Bukkit.getPlayerExact(player) == null)
+ if (Bukkit.getPlayer(player) == null)
{
iterator.remove();
_entityMap.remove(player);
@@ -195,7 +198,7 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
}
}
- @SuppressWarnings("unchecked")
+
public void handle(PacketInfo packetInfo)
{
if (packetInfo.isCancelled())
@@ -205,311 +208,84 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
Player owner = packetInfo.getPlayer();
PacketVerifier verifier = packetInfo.getVerifier();
- if (owner.isOnline())
+ if (!owner.isOnline())
+ // wat
+ return;
+
+ if (!_entityMap.containsKey(owner.getUniqueId()))
{
- if (owner.isOnline() && !_entityMap.containsKey(owner.getName()))
+ _entityMap.put(owner.getUniqueId(), new HashMap<>());
+ _entityNameMap.put(owner.getUniqueId(), new HashMap<>());
+ _loggedIn.add(owner.getUniqueId());
+ }
+
+ if (packet instanceof PacketPlayOutSpawnEntityLiving)
+ {
+ PacketPlayOutSpawnEntityLiving spawnPacket = (PacketPlayOutSpawnEntityLiving) packet;
+
+ // Ignore Armor stand packets
+ if (spawnPacket.b == EntityType.ARMOR_STAND.getTypeId() || spawnPacket.l == null || spawnPacket.l.c() == null)
{
- _entityMap.put(owner.getName(), new NautHashMap());
- _entityNameMap.put(owner.getName(), new NautHashMap());
- _loggedIn.add(owner.getName());
- }
-
- if (packet instanceof PacketPlayOutSpawnEntityLiving)
- {
- PacketPlayOutSpawnEntityLiving spawnPacket = (PacketPlayOutSpawnEntityLiving) packet;
-
- // Ignore Armor stand packets
- if (spawnPacket.b == EntityType.ARMOR_STAND.getTypeId() || spawnPacket.l == null || spawnPacket.l.c() == null)
- {
- if (spawnPacket.b == EntityType.ARMOR_STAND.getTypeId())
- {
- _ignoreIds.add(spawnPacket.a);
- }
-
- return;
- }
-
- for (WatchableObject watchable : (List) spawnPacket.l.c())
- {
- if (watchable.a() == 3 && watchable.b() instanceof Byte && ((Byte) watchable.b()) == 1)
- {
- if (_entityMap.get(owner.getName()).containsKey(spawnPacket.a))
- {
- Integer[] ids = _entityMap.get(owner.getName()).get(spawnPacket.a);
- int[] newIds = new int[ids.length];
-
- for (int a = 0; a < ids.length; a++)
- {
- newIds[a] = ids[a];
- }
-
- UtilPlayer.sendPacket(owner, new PacketPlayOutEntityDestroy(newIds));
-
- _entityNameMap.get(owner.getName()).remove(spawnPacket.a);
- _entityMap.get(owner.getName()).remove(spawnPacket.a);
- }
-
- final String entityName = spawnPacket.l.getString(2);
-
- if (entityName.isEmpty())
- {
- return;
- }
-
- Integer[] ids = new Integer[]
- {
- UtilEnt.getNewEntityId(),
- UtilEnt.getNewEntityId()
- };
-
- _entityNameMap.get(owner.getName()).put(spawnPacket.a, entityName);
- _entityMap.get(owner.getName()).put(spawnPacket.a, ids);
-
- sendProtocolPackets(owner, spawnPacket.a, entityName, verifier, true, ids);
- break;
- }
- }
- }
- else if (packet instanceof PacketPlayOutNamedEntitySpawn)
- {
- PacketPlayOutNamedEntitySpawn spawnPacket = (PacketPlayOutNamedEntitySpawn) packet;
-
- for (WatchableObject watchable : (List) spawnPacket.i.c())
- {
- if (watchable.a() == 3 && watchable.b() instanceof Byte && ((Byte) watchable.b()) == 1)
- {
- if (_entityMap.get(owner.getName()).containsKey(spawnPacket.a))
- {
- Integer[] ids = _entityMap.get(owner.getName()).get(spawnPacket.a);
-
- int[] newIds = new int[ids.length];
-
- for (int a = 0; a < ids.length; a++)
- {
- newIds[a] = ids[a];
- }
-
- UtilPlayer.sendPacket(owner, new PacketPlayOutEntityDestroy(newIds));
-
- _entityNameMap.get(owner.getName()).remove(spawnPacket.a);
- _entityMap.get(owner.getName()).remove(spawnPacket.a);
- }
-
- final String entityName = spawnPacket.i.getString(2);
-
- if (entityName.isEmpty())
- {
- return;
- }
-
- Integer[] ids = new Integer[]
- {
- UtilEnt.getNewEntityId(),
- UtilEnt.getNewEntityId()
- };
-
- _entityNameMap.get(owner.getName()).put(spawnPacket.a, entityName);
- _entityMap.get(owner.getName()).put(spawnPacket.a, ids);
-
- sendProtocolPackets(owner, spawnPacket.a, entityName, verifier, true, ids);
- break;
- }
- }
- }
- else if (packet instanceof PacketPlayOutEntityMetadata)
- {
- PacketPlayOutEntityMetadata metaPacket = (PacketPlayOutEntityMetadata) packet;
-
- if (metaPacket.a != 777777 && !_ignoreIds.contains(metaPacket.a) && metaPacket.a != owner.getEntityId())
- {
- boolean isDisplaying = _entityMap.get(owner.getName()).containsKey(metaPacket.a);
- String currentName = _entityNameMap.get(owner.getName()).get(metaPacket.a);
-
- if (currentName == null)
- {
- currentName = "";
- }
-
- String newName = currentName;
- boolean displayName = isDisplaying;
-
- for (WatchableObject watchable : (List) metaPacket.b)
- {
- if (watchable.a() == 3 && watchable.b() instanceof Byte)
- {
- displayName = ((Byte) watchable.b()) == 1;
- }
-
- if (watchable.a() == 2 && watchable.b() instanceof String)
- {
- newName = (String) watchable.b();
- }
- }
-
- // If the name has changed and the name should be showing, or the name display status has changed.
- if ((!newName.equals(currentName) && displayName) || displayName != isDisplaying)
- {
- // If name is still being displayed
- if (displayName)
- {
- Integer[] newId;
-
- if (isDisplaying) // Sending metadata
- {
- newId = _entityMap.get(owner.getName()).get(metaPacket.a);
- }
- else
- // Spawning new entity
- {
- newId = new Integer[]
- {
- UtilEnt.getNewEntityId(),
- UtilEnt.getNewEntityId()
- };
-
- _entityMap.get(owner.getName()).put(metaPacket.a, newId);
- }
-
- _entityNameMap.get(owner.getName()).put(metaPacket.a, newName);
- sendProtocolPackets(owner, metaPacket.a, newName, verifier, !isDisplaying, newId);
- }
- else
- { // Lets delete it
- Integer[] ids = _entityMap.get(owner.getName()).get(metaPacket.a);
- int[] newIds = new int[ids.length];
-
- for (int a = 0; a < ids.length; a++)
- {
- newIds[a] = ids[a];
- }
-
- verifier.bypassProcess(new PacketPlayOutEntityDestroy(newIds));
-
- _entityMap.get(owner.getName()).remove(metaPacket.a);
- _entityNameMap.get(owner.getName()).remove(metaPacket.a);
- }
- }
- }
- }
- else if (packet instanceof PacketPlayOutEntityDestroy)
- {
- try
- {
- for (int id : ((PacketPlayOutEntityDestroy) packet).a)
- {
- if (_entityMap.get(owner.getName()).containsKey(id))
- {
- Integer[] ids = _entityMap.get(owner.getName()).get(id);
- int[] newIds = new int[ids.length];
-
- for (int a = 0; a < ids.length; a++)
- {
- newIds[a] = ids[a];
- }
-
- UtilPlayer.sendPacket(owner, new PacketPlayOutEntityDestroy(newIds));
- _entityMap.get(owner.getName()).remove(id);
- _entityNameMap.get(owner.getName()).remove(id);
- }
- }
- }
- catch (Exception exception)
- {
- exception.printStackTrace();
- }
- }
- else if (packet instanceof PacketPlayOutSpawnEntity)
- {
- PacketPlayOutSpawnEntity spawnPacket = (PacketPlayOutSpawnEntity) packet;
- if (spawnPacket.j == 78) // Armor Stand Object ID
+ if (spawnPacket.b == EntityType.ARMOR_STAND.getTypeId())
{
_ignoreIds.add(spawnPacket.a);
}
+
+ return;
}
- else if (packet instanceof PacketPlayInUseEntity)
+
+ for (WatchableObject watchable : (List) spawnPacket.l.c())
{
- PacketPlayInUseEntity usePacket = (PacketPlayInUseEntity) packet;
-
- loop:
-
- for (Entry entry : _entityMap.get(owner.getName()).entrySet())
+ if (watchable.a() == 3 && watchable.b() instanceof Byte && ((Byte) watchable.b()) == 1)
{
- for (int id : entry.getValue())
+ if (_entityMap.get(owner.getUniqueId()).containsKey(spawnPacket.a))
{
- if (id == usePacket.a)
+ Integer[] ids = _entityMap.get(owner.getUniqueId()).get(spawnPacket.a);
+ int[] newIds = new int[ids.length];
+
+ for (int a = 0; a < ids.length; a++)
{
- PacketPlayInUseEntity newPacket = new PacketPlayInUseEntity();
- newPacket.a = entry.getKey();
- newPacket.action = usePacket.action;
- newPacket.c = usePacket.c;
-
- {
- ((CraftPlayer) owner).getHandle().playerConnection.a(newPacket);
- }
-
- break loop;
+ newIds[a] = ids[a];
}
+
+ UtilPlayer.sendPacket(owner, new PacketPlayOutEntityDestroy(newIds));
+
+ _entityNameMap.get(owner.getUniqueId()).remove(spawnPacket.a);
+ _entityMap.get(owner.getUniqueId()).remove(spawnPacket.a);
}
+
+ final String entityName = spawnPacket.l.getString(2);
+
+ if (entityName.isEmpty())
+ {
+ return;
+ }
+
+ Integer[] ids = new Integer[]
+ {
+ UtilEnt.getNewEntityId(),
+ UtilEnt.getNewEntityId()
+ };
+
+ _entityNameMap.get(owner.getUniqueId()).put(spawnPacket.a, entityName);
+ _entityMap.get(owner.getUniqueId()).put(spawnPacket.a, ids);
+
+ sendProtocolPackets(owner, spawnPacket.a, entityName, verifier, true, ids);
+ break;
}
}
- else if (packet instanceof PacketPlayOutAttachEntity || packet instanceof PacketPlayOutNewAttachEntity)
+ }
+ else if (packet instanceof PacketPlayOutNamedEntitySpawn)
+ {
+ PacketPlayOutNamedEntitySpawn spawnPacket = (PacketPlayOutNamedEntitySpawn) packet;
+
+ for (WatchableObject watchable : (List) spawnPacket.i.c())
{
- int vech = -1;
- int rider = -1;
-
- if (packet instanceof PacketPlayOutAttachEntity)
+ if (watchable.a() == 3 && watchable.b() instanceof Byte && ((Byte) watchable.b()) == 1)
{
- PacketPlayOutAttachEntity attachPacket = (PacketPlayOutAttachEntity) packet;
- vech = attachPacket.b;
- rider = attachPacket.c;
- }
- else if (packet instanceof PacketPlayOutNewAttachEntity)
- {
- PacketPlayOutNewAttachEntity attachPacket = (PacketPlayOutNewAttachEntity) packet;
- vech = attachPacket.a;
-
- if (attachPacket.b.length > 0)
- rider = attachPacket.b[0];
- }
-
- // c = rider, b = ridden
- // When detaching, c is sent, b is -1
-
- // If this attach packet is for a player that has the fix
- // If the attach packet isn't ordained by me
- if (!_entityMap.containsKey(owner.getName()))
- {
- return;
- }
-
- if (!_entityRiding.containsKey(owner.getName()))
- {
- _entityRiding.put(owner.getName(), new NautHashMap());
- }
-
- int vehicleId = -1;
-
- if (_entityRiding.get(owner.getName()).containsKey(vech))
- {
- vehicleId = _entityRiding.get(owner.getName()).get(vech);
- }
-
- if (rider == -1 && _entityMap.get(owner.getName()).containsKey(vehicleId))
- {
- Integer[] ids = _entityMap.get(owner.getName()).get(vehicleId);
-
- _entityRiding.get(owner.getName()).remove(vech);
-
- sendProtocolPackets(owner, vehicleId, _entityNameMap.get(owner.getName()).get(vehicleId), verifier, true,
- ids);
- }
- else
- {
- Integer[] ids = _entityMap.get(owner.getName()).get(rider);
-
- if (ids != null && ids[1] != vech)
+ if (_entityMap.get(owner.getUniqueId()).containsKey(spawnPacket.a))
{
- _entityRiding.get(owner.getName()).put(vech, rider);
+ Integer[] ids = _entityMap.get(owner.getUniqueId()).get(spawnPacket.a);
int[] newIds = new int[ids.length];
@@ -519,14 +295,242 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
}
UtilPlayer.sendPacket(owner, new PacketPlayOutEntityDestroy(newIds));
+
+ _entityNameMap.get(owner.getUniqueId()).remove(spawnPacket.a);
+ _entityMap.get(owner.getUniqueId()).remove(spawnPacket.a);
}
+
+ final String entityName = spawnPacket.i.getString(2);
+
+ if (entityName.isEmpty())
+ {
+ return;
+ }
+
+ Integer[] ids = new Integer[]
+ {
+ UtilEnt.getNewEntityId(),
+ UtilEnt.getNewEntityId()
+ };
+
+ _entityNameMap.get(owner.getUniqueId()).put(spawnPacket.a, entityName);
+ _entityMap.get(owner.getUniqueId()).put(spawnPacket.a, ids);
+
+ sendProtocolPackets(owner, spawnPacket.a, entityName, verifier, true, ids);
+ break;
+ }
+ }
+ }
+ else if (packet instanceof PacketPlayOutEntityMetadata)
+ {
+ PacketPlayOutEntityMetadata metaPacket = (PacketPlayOutEntityMetadata) packet;
+
+ if (metaPacket.a != 777777 && !_ignoreIds.contains(metaPacket.a) && metaPacket.a != owner.getEntityId())
+ {
+ boolean isDisplaying = _entityMap.get(owner.getUniqueId()).containsKey(metaPacket.a);
+ String currentName = _entityNameMap.get(owner.getUniqueId()).get(metaPacket.a);
+
+ if (currentName == null)
+ {
+ currentName = "";
+ }
+
+ String newName = currentName;
+ boolean displayName = isDisplaying;
+
+ for (WatchableObject watchable : (List) metaPacket.b)
+ {
+ if (watchable.a() == 3 && watchable.b() instanceof Byte)
+ {
+ displayName = ((Byte) watchable.b()) == 1;
+ }
+
+ if (watchable.a() == 2 && watchable.b() instanceof String)
+ {
+ newName = (String) watchable.b();
+ }
+ }
+
+ // If the name has changed and the name should be showing, or the name display status has changed.
+ if ((!newName.equals(currentName) && displayName) || displayName != isDisplaying)
+ {
+ // If name is still being displayed
+ if (displayName)
+ {
+ Integer[] newId;
+
+ if (isDisplaying) // Sending metadata
+ {
+ newId = _entityMap.get(owner.getUniqueId()).get(metaPacket.a);
+ }
+ else
+ // Spawning new entity
+ {
+ newId = new Integer[]
+ {
+ UtilEnt.getNewEntityId(),
+ UtilEnt.getNewEntityId()
+ };
+
+ _entityMap.get(owner.getUniqueId()).put(metaPacket.a, newId);
+ }
+
+ _entityNameMap.get(owner.getUniqueId()).put(metaPacket.a, newName);
+ sendProtocolPackets(owner, metaPacket.a, newName, verifier, !isDisplaying, newId);
+ }
+ else
+ { // Lets delete it
+ Integer[] ids = _entityMap.get(owner.getUniqueId()).get(metaPacket.a);
+ int[] newIds = new int[ids.length];
+
+ for (int a = 0; a < ids.length; a++)
+ {
+ newIds[a] = ids[a];
+ }
+
+ verifier.bypassProcess(new PacketPlayOutEntityDestroy(newIds));
+
+ _entityMap.get(owner.getUniqueId()).remove(metaPacket.a);
+ _entityNameMap.get(owner.getUniqueId()).remove(metaPacket.a);
+ }
+ }
+ }
+ }
+ else if (packet instanceof PacketPlayOutEntityDestroy)
+ {
+ try
+ {
+ for (int id : ((PacketPlayOutEntityDestroy) packet).a)
+ {
+ if (_entityMap.get(owner.getUniqueId()).containsKey(id))
+ {
+ Integer[] ids = _entityMap.get(owner.getUniqueId()).get(id);
+ int[] newIds = new int[ids.length];
+
+ for (int a = 0; a < ids.length; a++)
+ {
+ newIds[a] = ids[a];
+ }
+
+ UtilPlayer.sendPacket(owner, new PacketPlayOutEntityDestroy(newIds));
+ _entityMap.get(owner.getUniqueId()).remove(id);
+ _entityNameMap.get(owner.getUniqueId()).remove(id);
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ exception.printStackTrace();
+ }
+ }
+ else if (packet instanceof PacketPlayOutSpawnEntity)
+ {
+ PacketPlayOutSpawnEntity spawnPacket = (PacketPlayOutSpawnEntity) packet;
+ if (spawnPacket.j == 78) // Armor Stand Object ID
+ {
+ _ignoreIds.add(spawnPacket.a);
+ }
+ }
+ else if (packet instanceof PacketPlayInUseEntity)
+ {
+ PacketPlayInUseEntity usePacket = (PacketPlayInUseEntity) packet;
+
+ loop:
+
+ for (Entry entry : _entityMap.get(owner.getUniqueId()).entrySet())
+ {
+ for (int id : entry.getValue())
+ {
+ if (id == usePacket.a)
+ {
+ PacketPlayInUseEntity newPacket = new PacketPlayInUseEntity();
+ newPacket.a = entry.getKey();
+ newPacket.action = usePacket.action;
+ newPacket.c = usePacket.c;
+
+ {
+ ((CraftPlayer) owner).getHandle().playerConnection.a(newPacket);
+ }
+
+ break loop;
+ }
+ }
+ }
+ }
+ else if (packet instanceof PacketPlayOutAttachEntity || packet instanceof PacketPlayOutNewAttachEntity)
+ {
+ int vech = -1;
+ int rider = -1;
+
+ if (packet instanceof PacketPlayOutAttachEntity)
+ {
+ PacketPlayOutAttachEntity attachPacket = (PacketPlayOutAttachEntity) packet;
+ vech = attachPacket.b;
+ rider = attachPacket.c;
+ }
+ else if (packet instanceof PacketPlayOutNewAttachEntity)
+ {
+ PacketPlayOutNewAttachEntity attachPacket = (PacketPlayOutNewAttachEntity) packet;
+ vech = attachPacket.a;
+
+ if (attachPacket.b.length > 0)
+ rider = attachPacket.b[0];
+ }
+
+ // c = rider, b = ridden
+ // When detaching, c is sent, b is -1
+
+ // If this attach packet is for a player that has the fix
+ // If the attach packet isn't ordained by me
+ if (!_entityMap.containsKey(owner.getUniqueId()))
+ {
+ return;
+ }
+
+ if (!_entityRiding.containsKey(owner.getUniqueId()))
+ {
+ _entityRiding.put(owner.getUniqueId(), new HashMap());
+ }
+
+ int vehicleId = -1;
+
+ if (_entityRiding.get(owner.getUniqueId()).containsKey(vech))
+ {
+ vehicleId = _entityRiding.get(owner.getUniqueId()).get(vech);
+ }
+
+ if (rider == -1 && _entityMap.get(owner.getUniqueId()).containsKey(vehicleId))
+ {
+ Integer[] ids = _entityMap.get(owner.getUniqueId()).get(vehicleId);
+
+ _entityRiding.get(owner.getUniqueId()).remove(vech);
+
+ sendProtocolPackets(owner, vehicleId, _entityNameMap.get(owner.getUniqueId()).get(vehicleId), verifier, true,
+ ids);
+ }
+ else
+ {
+ Integer[] ids = _entityMap.get(owner.getUniqueId()).get(rider);
+
+ if (ids != null && ids[1] != vech)
+ {
+ _entityRiding.get(owner.getUniqueId()).put(vech, rider);
+
+ int[] newIds = new int[ids.length];
+
+ for (int a = 0; a < ids.length; a++)
+ {
+ newIds[a] = ids[a];
+ }
+
+ UtilPlayer.sendPacket(owner, new PacketPlayOutEntityDestroy(newIds));
}
}
}
}
private void sendProtocolPackets(final Player owner, final int entityId, String entityName, final PacketVerifier packetList,
- final boolean newPacket, final Integer[] entityIds)
+ final boolean newPacket, final Integer[] entityIds)
{
CustomTagEvent event = new CustomTagEvent(owner, entityId, entityName);
_plugin.getServer().getPluginManager().callEvent(event);
@@ -565,9 +569,9 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
if (UtilPlayer.is1_9(owner))
{
UtilPlayer.sendPacket(owner, new PacketPlayOutNewAttachEntity(entityId, new int[]
- {
- entityIds[1]
- }));
+ {
+ entityIds[1]
+ }));
}
else
{
@@ -595,9 +599,9 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
if (UtilPlayer.is1_9(owner))
{
UtilPlayer.sendPacket(owner, new PacketPlayOutNewAttachEntity(entityIds[1], new int[]
- {
- entityIds[0]
- }));
+ {
+ entityIds[0]
+ }));
}
else
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/Managers.java b/Plugins/Mineplex.Core/src/mineplex/core/Managers.java
new file mode 100644
index 000000000..f37bfc810
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/Managers.java
@@ -0,0 +1,92 @@
+package mineplex.core;
+
+import mineplex.core.common.util.UtilServer;
+
+import java.lang.reflect.Constructor;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class will manage all the MiniPlugin instances. It's not the best way to do it, but it works given how
+ * we use MiniPlugins right now, so let's not fret about that
+ */
+public class Managers
+{
+ private static final Map, Object> MANAGER_MAP = Collections.synchronizedMap(new HashMap<>());
+
+ /**
+ * Gets a Manager ({@link MiniPlugin}) based on its class
+ *
+ * @param clazz The class of the MiniPlugin to return
+ * @return The mapped MiniPlugin, or null if not found
+ */
+ public static T get(Class clazz)
+ {
+ Object result = MANAGER_MAP.get(clazz);
+ return clazz.cast(result);
+ }
+
+ /**
+ * Gets the given module, and initializes if necessary
+ * @param clazz
+ * @param
+ * @return
+ */
+ public static T require(Class clazz)
+ {
+ if (MANAGER_MAP.containsKey(clazz))
+ {
+ return get(clazz);
+ }
+ try
+ {
+ ReflectivelyCreateMiniPlugin annotation = clazz.getAnnotation(ReflectivelyCreateMiniPlugin.class);
+ if (annotation != null)
+ {
+ Constructor defaultConstructor = clazz.getDeclaredConstructor();
+ defaultConstructor.setAccessible(true);
+ return defaultConstructor.newInstance();
+ }
+ }
+ catch (ReflectiveOperationException ex)
+ {
+ ex.printStackTrace(System.out);
+ }
+ return null;
+ }
+
+ public static void put(MiniPlugin manager)
+ {
+ if (manager == null) throw new NullPointerException("Manager cannot be null");
+ if (MANAGER_MAP.containsKey(manager.getClass()))
+ {
+ if (!UtilServer.isTestServer())
+ {
+ System.out.println("============== WARNING ==============");
+ System.out.println(" ");
+ System.out.println(" ");
+ System.out.println(" ");
+ System.out.println("Attempted to register " + manager.getClass().getName() + ", but it was already registered");
+ new Exception("Stack trace").printStackTrace(System.out);
+ System.out.println(" ");
+ System.out.println(" ");
+ System.out.println(" ");
+ System.out.println("============== WARNING ==============");
+ }
+ else
+ {
+ throw new IllegalArgumentException("Manager " + manager.getClass().getName() + " is already registered");
+ }
+ }
+ MANAGER_MAP.put(manager.getClass(), manager);
+ }
+
+ public static void put(MiniPlugin manager, Class extends MiniPlugin> type)
+ {
+ if (manager == null) throw new NullPointerException("Manager cannot be null");
+ if (!type.isAssignableFrom(manager.getClass())) throw new IllegalArgumentException(manager.getClass().getName() + " is not a subclass of " + type.getName());
+ if (MANAGER_MAP.containsKey(type)) throw new IllegalArgumentException("Manager " + type.getName() + " is already registered");
+ MANAGER_MAP.put(type, manager);
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/MiniClientPlugin.java b/Plugins/Mineplex.Core/src/mineplex/core/MiniClientPlugin.java
index d90d08fe5..c5f2119e1 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/MiniClientPlugin.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/MiniClientPlugin.java
@@ -1,19 +1,21 @@
package mineplex.core;
-import java.util.Collection;
-
+import mineplex.core.account.event.ClientUnloadEvent;
+import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.plugin.java.JavaPlugin;
-import mineplex.core.account.event.ClientUnloadEvent;
-import mineplex.core.common.util.NautHashMap;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
public abstract class MiniClientPlugin extends MiniPlugin
{
- private static Object _clientDataLock = new Object();
+ private static final Object _clientDataLock = new Object();
- private NautHashMap _clientData = new NautHashMap();
+ private Map _clientData = new HashMap<>();
public MiniClientPlugin(String moduleName, JavaPlugin plugin)
{
@@ -26,18 +28,27 @@ public abstract class MiniClientPlugin extends MiniPlug
synchronized (_clientDataLock)
{
saveData(event.GetName(), event.getAccountId());
- _clientData.remove(event.GetName());
+ _clientData.remove(event.getUniqueId());
}
}
-
+
+ @Deprecated
public DataType Get(String name)
+ {
+ Player player = Bukkit.getPlayerExact(name);
+ if (player == null)
+ return null;
+ return Get(player);
+ }
+
+ public DataType Get(UUID uuid)
{
synchronized (_clientDataLock)
{
- if (!_clientData.containsKey(name))
- _clientData.put(name, addPlayer(name));
-
- return _clientData.get(name);
+ if (!_clientData.containsKey(uuid))
+ _clientData.put(uuid, addPlayer(uuid));
+
+ return _clientData.get(uuid);
}
}
@@ -45,7 +56,7 @@ public abstract class MiniClientPlugin extends MiniPlug
public DataType Get(Player player)
{
- return Get(player.getName());
+ return Get(player.getUniqueId());
}
protected Collection GetValues()
@@ -55,16 +66,16 @@ public abstract class MiniClientPlugin extends MiniPlug
protected void Set(Player player, DataType data)
{
- Set(player.getName(), data);
+ Set(player.getUniqueId(), data);
}
-
- protected void Set(String name, DataType data)
+
+ protected void Set(UUID uuid, DataType data)
{
synchronized (_clientDataLock)
{
- _clientData.put(name, data);
+ _clientData.put(uuid, data);
}
}
- protected abstract DataType addPlayer(String player);
+ protected abstract DataType addPlayer(UUID uuid);
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/MiniDbClientPlugin.java b/Plugins/Mineplex.Core/src/mineplex/core/MiniDbClientPlugin.java
index 2f479adeb..52805cdc5 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/MiniDbClientPlugin.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/MiniDbClientPlugin.java
@@ -2,6 +2,7 @@ package mineplex.core;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.UUID;
import org.bukkit.plugin.java.JavaPlugin;
@@ -21,7 +22,7 @@ public abstract class MiniDbClientPlugin extends MiniCl
clientManager.addStoredProcedureLoginProcessor(this);
}
- public abstract void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException;
+ public abstract void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException;
public CoreClientManager getClientManager()
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java b/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java
index 435f4dcff..80c128715 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/MiniPlugin.java
@@ -1,20 +1,30 @@
package mineplex.core;
+import mineplex.core.command.CommandCenter;
+import mineplex.core.command.ICommand;
+import mineplex.core.common.util.F;
+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.thread.ThreadPool;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
+import org.bukkit.scheduler.BukkitTask;
-import mineplex.core.command.CommandCenter;
-import mineplex.core.command.ICommand;
-import mineplex.core.common.util.F;
-import mineplex.core.common.util.NautHashMap;
-import mineplex.core.common.util.UtilTime;
-import mineplex.core.common.util.UtilTime.TimeUnit;
-import mineplex.core.thread.ThreadPool;
-
+/**
+ * In the future, all implementations of MiniPlugin should only have one constructor:
+ *
+ * private MiniPlugin()
+ *
+ * MiniPlugins should also not depend on load order.
+ *
+ * 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
{
protected String _moduleName = "Default";
@@ -23,6 +33,11 @@ public abstract class MiniPlugin implements Listener
protected long _initializedTime;
+ public MiniPlugin(String moduleName)
+ {
+ this(moduleName, UtilServer.getPlugin());
+ }
+
public MiniPlugin(String moduleName, JavaPlugin plugin)
{
_moduleName = moduleName;
@@ -30,11 +45,13 @@ public abstract class MiniPlugin implements Listener
_initializedTime = System.currentTimeMillis();
- _commands = new NautHashMap();
+ _commands = new NautHashMap<>();
onEnable();
registerEvents(this);
+
+ Managers.put(this);
}
public PluginManager getPluginManager()
@@ -111,22 +128,36 @@ public abstract class MiniPlugin implements Listener
public void runAsync(Runnable runnable)
{
- // Instead of using
ThreadPool.ASYNC.execute(runnable);
}
- public void runAsync(Runnable runnable, long time)
+ public BukkitTask runAsync(Runnable runnable, long time)
{
- _plugin.getServer().getScheduler().runTaskLaterAsynchronously(_plugin, runnable, time);
+ return _plugin.getServer().getScheduler().runTaskLaterAsynchronously(_plugin, runnable, time);
}
- public void runSync(Runnable runnable)
+ public BukkitTask runAsyncTimer(Runnable runnable, long time, long period)
{
- _plugin.getServer().getScheduler().runTask(_plugin, runnable);
+ return _plugin.getServer().getScheduler().runTaskTimerAsynchronously(_plugin, runnable, time, period);
}
- public void runSyncLater(Runnable runnable, long delay)
+ public BukkitTask runSync(Runnable runnable)
{
- _plugin.getServer().getScheduler().runTaskLater(_plugin, runnable, delay);
+ return _plugin.getServer().getScheduler().runTask(_plugin, runnable);
+ }
+
+ public BukkitTask runSyncLater(Runnable runnable, long delay)
+ {
+ return _plugin.getServer().getScheduler().runTaskLater(_plugin, runnable, delay);
+ }
+
+ public BukkitTask runSyncTimer(Runnable runnable, long delay, long period)
+ {
+ return _plugin.getServer().getScheduler().runTaskTimer(_plugin, runnable, delay, period);
+ }
+
+ protected T require(Class clazz)
+ {
+ return Managers.require(clazz);
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/PacketsInteractionFix.java b/Plugins/Mineplex.Core/src/mineplex/core/PacketsInteractionFix.java
index 227cba9bb..19d74a4b2 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/PacketsInteractionFix.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/PacketsInteractionFix.java
@@ -4,6 +4,8 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
import net.minecraft.server.v1_8_R3.EntityPlayer;
import net.minecraft.server.v1_8_R3.MathHelper;
@@ -33,7 +35,7 @@ import mineplex.core.updater.event.UpdateEvent;
public class PacketsInteractionFix extends MiniPlugin implements IPacketHandler
{
- private HashMap> _armorStands = new HashMap>();
+ private Map> _armorStands = new HashMap<>();
public PacketsInteractionFix(JavaPlugin plugin, PacketHandler packetHandler)
{
@@ -46,7 +48,7 @@ public class PacketsInteractionFix extends MiniPlugin implements IPacketHandler
@EventHandler
public void onQuit(PlayerQuitEvent event)
{
- _armorStands.remove(event.getPlayer().getName());
+ _armorStands.remove(event.getPlayer().getUniqueId());
}
@EventHandler
@@ -57,13 +59,13 @@ public class PacketsInteractionFix extends MiniPlugin implements IPacketHandler
return;
}
- Iterator itel = _armorStands.keySet().iterator();
+ Iterator itel = _armorStands.keySet().iterator();
while (itel.hasNext())
{
- String name = itel.next();
+ UUID id = itel.next();
- Player player = Bukkit.getPlayerExact(name);
+ Player player = Bukkit.getPlayer(id);
if (player != null)
{
@@ -89,12 +91,12 @@ public class PacketsInteractionFix extends MiniPlugin implements IPacketHandler
return;
}
- if (!_armorStands.containsKey(player.getName()))
+ if (!_armorStands.containsKey(player.getUniqueId()))
{
- _armorStands.put(player.getName(), new HashSet());
+ _armorStands.put(player.getUniqueId(), new HashSet());
}
- HashSet list = _armorStands.get(player.getName());
+ HashSet list = _armorStands.get(player.getUniqueId());
if (packetInfo.getPacket() instanceof PacketPlayOutSpawnEntityLiving)
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/PlayerSelector.java b/Plugins/Mineplex.Core/src/mineplex/core/PlayerSelector.java
new file mode 100644
index 000000000..7969cf22e
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/PlayerSelector.java
@@ -0,0 +1,159 @@
+package mineplex.core;
+
+import mineplex.core.account.CoreClient;
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.common.Rank;
+import mineplex.core.incognito.IncognitoManager;
+import org.bukkit.Bukkit;
+import org.bukkit.GameMode;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * A helper for selecting arbitrary players given a set of conditions
+ */
+public class PlayerSelector
+{
+ /**
+ * Select a random player from all the online players
+ *
+ * @return A random player, or null if none matched
+ */
+ public static Player selectPlayer()
+ {
+ return selectPlayer(player -> true);
+ }
+
+ /**
+ * Select a random player who match the given criterion
+ *
+ * @param selector The condition that the players must match against
+ * @return A random player, or null if none matched
+ */
+ public static Player selectPlayer(Predicate selector)
+ {
+ List selected = selectPlayers(selector);
+ return selected.get(ThreadLocalRandom.current().nextInt(selected.size()));
+ }
+
+ /**
+ * Select all the players who match the given criterion
+ * @param selector The condition that the players must match against
+ * @return All the players who match
+ */
+ public static List selectPlayers(Predicate selector)
+ {
+ return Bukkit.getOnlinePlayers().stream().filter(selector).collect(Collectors.toList());
+ }
+
+ /**
+ * This condition will return true if the player is not vanished, and false if they are.
+ *
+ * If the {@link IncognitoManager} is not loaded, then this will return true
+ */
+ public static final Predicate NOT_VANISHED = player ->
+ {
+ IncognitoManager manager = Managers.get(IncognitoManager.class);
+ if (manager == null)
+ {
+ return true;
+ }
+ return !manager.Get(player).Status;
+ };
+
+ /**
+ * This condition will return true if the player is not spectating, and false if they are
+ */
+ public static final Predicate NOT_SPECTATING = player -> player.getGameMode() != GameMode.SPECTATOR;
+
+ /**
+ * This condition will return true if the player has one of the given ranks
+ *
+ * @param useDisguisedRank Whether to use the disguised rank of the player should they be disguised
+ * @param ranks The ranks to check
+ * @return The resulting criterion
+ */
+ public static Predicate hasAnyRank(boolean useDisguisedRank, Rank... ranks)
+ {
+ return player ->
+ {
+ CoreClientManager coreClientManager = Managers.get(CoreClientManager.class);
+ if (coreClientManager == null)
+ {
+ return true;
+ }
+ CoreClient client = coreClientManager.Get(player);
+ Rank rank = useDisguisedRank ? client.getRealOrDisguisedRank() : client.GetRank();
+
+ for (Rank requiredRank : ranks)
+ {
+ if (rank == requiredRank)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ };
+ }
+
+
+ /**
+ * This condition will return true if the entity is in the world specified
+ * @param world The world that the entity must be in
+ * @return The resulting criterion
+ */
+ public static Predicate inWorld(World world)
+ {
+ return entity -> world == null || entity.getWorld().equals(world);
+ }
+
+ /**
+ * This will return a {@link Predicate} which will return true if and only if all of the supplied Predicates
+ * return true
+ * @param predicates The Predicates to test against
+ * @return The resulting criterion
+ */
+ @SafeVarargs
+ public static Predicate and(Predicate... predicates)
+ {
+ return t ->
+ {
+ for (Predicate predicate : predicates)
+ {
+ if (!predicate.test(t))
+ {
+ return false;
+ }
+ }
+ return true;
+ };
+ }
+
+ /**
+ * This will return a {@link Predicate} which will return true if and only if one of the the supplied Predicates
+ * return true
+ * @param predicates The Predicates to test against
+ * @return The resulting criterion
+ */
+ @SafeVarargs
+ public static Predicate or(Predicate... predicates)
+ {
+ return t ->
+ {
+ for (Predicate predicate : predicates)
+ {
+ if (predicate.test(t))
+ {
+ return true;
+ }
+ }
+ return false;
+ };
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/ReflectivelyCreateMiniPlugin.java b/Plugins/Mineplex.Core/src/mineplex/core/ReflectivelyCreateMiniPlugin.java
new file mode 100644
index 000000000..18c11d4cf
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/ReflectivelyCreateMiniPlugin.java
@@ -0,0 +1,15 @@
+package mineplex.core;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Simply represents that this {@link MiniPlugin} can be reflectively instantiated with no harm
+ */
+@Target(value = ElementType.TYPE)
+@Retention(value = RetentionPolicy.RUNTIME)
+public @interface ReflectivelyCreateMiniPlugin
+{
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java
index 61ccdc618..603281907 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java
@@ -9,51 +9,66 @@ import mineplex.serverdata.Utility;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
-public class CoreClient
+import java.util.UUID;
+
+public class CoreClient
{
- private int _accountId = -1;
- private long _networkSessionLoginTime;
+ private int _accountId = -1;
+ private long _networkSessionLoginTime;
private String _name;
- private String _disguisedAs;
+ private UUID _uuid;
private Player _player;
private Rank _rank, _lastRank;
- private Rank _disguisedRank;
private Rank _tempRank, _lastTemp;
- private boolean _disguised;
-
+
+ /*
+ * Disguise info
+ */
+ private String _disguisedName;
+ private String _disguisedSkin;
+ private UUID _disguisedUUID;
+ private Rank _disguisedRank;
+
public CoreClient(Player player)
{
_player = player;
+ _uuid = player.getUniqueId();
_name = player.getName();
_networkSessionLoginTime = Utility.currentTimeMillis();
}
-
- public CoreClient(String name)
+
+ public CoreClient(String name, UUID uuid)
{
_name = name;
+ _uuid = uuid;
}
- public String GetPlayerName()
+ public UUID getUniqueId()
+ {
+ return this._uuid;
+ }
+
+ public String getName()
{
return _name;
}
-
+
public Player GetPlayer()
{
return _player;
}
-
- public void SetPlayer(Player player)
- {
- _player = player;
- }
-
- public int getAccountId()
- {
- return _accountId;
- }
- public void Delete()
+ public void SetPlayer(Player player)
+ {
+ _player = player;
+ }
+
+ public int getAccountId()
+ {
+ return _accountId;
+ }
+
+ public void Delete()
{
_name = null;
_player = null;
@@ -63,7 +78,7 @@ public class CoreClient
{
_accountId = accountId;
}
-
+
public Rank GetRank()
{
return GetRank(false);
@@ -73,13 +88,13 @@ public class CoreClient
{
if (_rank == null)
_rank = Rank.ALL;
-
+
if (bypass || _tempRank == null)
return _rank;
else
return _tempRank;
}
-
+
public Rank GetLastRank(boolean temp)
{
if (temp)
@@ -100,7 +115,7 @@ public class CoreClient
return _lastRank;
}
}
-
+
public void SetRank(Rank rank, boolean temp)
{
if (temp)
@@ -117,47 +132,70 @@ public class CoreClient
_rank = rank;
}
}
-
+
public long getNetworkSessionLoginTime()
{
return _networkSessionLoginTime;
}
- public String getDisguisedAs()
+ public void undisguise()
{
- return _disguisedAs;
+ this._disguisedName = null;
+ this._disguisedSkin = null;
+ this._disguisedRank = null;
+ this._disguisedUUID = null;
}
- public void setDisguisedAs(String originalName)
+ public String getDisguisedAs()
{
- this._disguisedAs = originalName;
+ return this._disguisedName;
}
- /**
- * Only use this method if the client is actually disguised!
- * @return
- */
- public Rank getDisguisedRank() {
+ public String getDisguisedSkin()
+ {
+ return this._disguisedSkin;
+ }
+
+ public Rank getDisguisedRank()
+ {
return _disguisedRank;
}
- public void setDisguisedRank(Rank disguisedRank) {
- this._disguisedRank = disguisedRank;
+ public UUID getDisguisedAsUUID()
+ {
+ return this._disguisedUUID;
}
- public boolean isDisguised() {
- return _disguised;
+ public boolean isDisguised()
+ {
+ if (this._disguisedName == null)
+ {
+ return false;
+ }
+ return !this._name.equalsIgnoreCase(this._disguisedName);
}
- public void setDisguised(boolean disguised) {
- this._disguised = disguised;
+ public void disguise(String name, UUID uuid, Rank rank)
+ {
+ this._disguisedName = name;
+ this._disguisedUUID = uuid;
+ this._disguisedRank = rank;
}
- public void setNetworkSessionLoginTime(long loginTime)
+ public Rank getRealOrDisguisedRank()
+ {
+ if (this._disguisedRank != null)
+ {
+ return this._disguisedRank;
+ }
+ return this.GetRank();
+ }
+
+ public void setNetworkSessionLoginTime(long loginTime)
{
_networkSessionLoginTime = loginTime;
}
-
+
public void resetTemp()
{
if (_tempRank != null)
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java
index e025133f9..dc68fca79 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java
@@ -2,12 +2,17 @@ package mineplex.core.account;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
import com.google.gson.Gson;
@@ -22,13 +27,14 @@ import mineplex.core.account.repository.AccountRepository;
import mineplex.core.account.repository.token.ClientToken;
import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback;
-import mineplex.core.common.util.NautHashMap;
import mineplex.core.common.util.UUIDFetcher;
import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.common.util.UtilTasks;
import mineplex.core.timing.TimingManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
+import mineplex.core.utils.UtilGameProfile;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
@@ -43,43 +49,41 @@ import org.bukkit.plugin.java.JavaPlugin;
public class CoreClientManager extends MiniPlugin
{
- private static NautHashMap _clientLoginLock = new NautHashMap();
-
+ private static final Map CLIENT_LOGIN_LOCKS = new ConcurrentHashMap<>();
+
private JavaPlugin _plugin;
private AccountRepository _repository;
- private NautHashMap _clientList;
- private HashSet _duplicateLoginGlitchPreventionList;
+ private Map _clientList = new HashMap<>();
+ private HashSet _duplicateLoginGlitchPreventionList = new HashSet<>();
private List _loginProcessors = new ArrayList<>();
- private Object _clientLock = new Object();
-
+ private final Object _clientLock = new Object();
+
private static AtomicInteger _clientsConnecting = new AtomicInteger(0);
private static AtomicInteger _clientsProcessing = new AtomicInteger(0);
-
+
private final Rank WHITELIST_BYPASS;
-
+
public CoreClientManager(JavaPlugin plugin, String webServer)
{
this(plugin, webServer, Rank.MODERATOR);
}
-
+
public CoreClientManager(JavaPlugin plugin, String webServer, Rank whitelistBypass)
{
super("Client Manager", plugin);
-
+
_plugin = plugin;
_repository = new AccountRepository(plugin, webServer);
- _clientList = new NautHashMap();
- _duplicateLoginGlitchPreventionList = new HashSet();
- WHITELIST_BYPASS = whitelistBypass;
+ WHITELIST_BYPASS = whitelistBypass;
}
-
+
public AccountRepository getRepository()
{
return _repository;
}
-
+
@Override
public void addCommands()
{
@@ -87,72 +91,71 @@ public class CoreClientManager extends MiniPlugin
addCommand(new TestRank(this));
}
- public CoreClient Add(String name)
+ public CoreClient Add(String name, UUID uuid)
{
- CoreClient newClient = null;
-
- if (newClient == null)
+ CoreClient newClient = new CoreClient(name, uuid);
+
+ CoreClient oldClient;
+
+ synchronized (_clientLock)
{
- newClient = new CoreClient(name);
+ oldClient = _clientList.put(uuid, newClient);
}
-
- CoreClient oldClient = null;
-
- synchronized(_clientLock)
+
+ if (oldClient != null)
{
- oldClient = _clientList.put(name, newClient);
+ oldClient.Delete();
}
-
- if (oldClient != null)
- {
- oldClient.Delete();
- }
return newClient;
}
- public void Del(String name, int accountId)
+ public void Del(String name, UUID uuid, int accountId)
{
- synchronized(_clientLock)
+ synchronized (_clientLock)
{
- _clientList.remove(name);
+ _clientList.remove(uuid);
}
// rawr added account id for custom data - william
- _plugin.getServer().getPluginManager().callEvent(new ClientUnloadEvent(name, accountId));
+ _plugin.getServer().getPluginManager().callEvent(new ClientUnloadEvent(name, uuid, accountId));
}
+ @Deprecated
public CoreClient Get(String name)
{
- synchronized(_clientLock)
+ Player p = Bukkit.getPlayerExact(name);
+ return Get(p.getUniqueId());
+ }
+
+ public CoreClient Get(UUID uuid)
+ {
+ synchronized (_clientLock)
{
- for(CoreClient client : _clientList.values())
- {
- if(client.getDisguisedAs() != null)
- if(client.getDisguisedAs().equalsIgnoreCase(name))
- return client;
- }
- CoreClient client = _clientList.get(name);
-
+ CoreClient client = _clientList.get(uuid);
+
if (client == null)
{
- client = new CoreClient(name);
+ Player player = Bukkit.getPlayer(uuid);
+ if (player != null)
+ {
+ client = new CoreClient(player.getName(), uuid);
+ }
+ else
+ {
+ client = new CoreClient(null, uuid);
+ }
}
-
+
return client;
}
}
-
- public boolean Contains(String name)
- {
- return _clientList.containsKey(name);
- }
-
+
public CoreClient Get(Player player)
{
- return Get(player.getName());
+ return Get(player.getUniqueId());
}
-
+
public int getPlayerCountIncludingConnecting()
{
return Bukkit.getOnlinePlayers().size() + Math.max(0, _clientsConnecting.get());
@@ -160,6 +163,7 @@ public class CoreClientManager extends MiniPlugin
/**
* Get the databse account id for a player. Requires the player is online
+ *
* @param player
* @return
*/
@@ -185,12 +189,12 @@ public class CoreClientManager extends MiniPlugin
e.printStackTrace();
}
}
-
+
try
{
_clientsProcessing.incrementAndGet();
-
- if (!LoadClient(Add(event.getName()), event.getUniqueId(), event.getAddress().getHostAddress()))
+
+ if (!LoadClient(Add(event.getName(), event.getUniqueId()), event.getUniqueId(), event.getAddress().getHostAddress()))
event.disallow(Result.KICK_OTHER, "There was a problem logging you in.");
}
catch (Exception exception)
@@ -202,8 +206,8 @@ public class CoreClientManager extends MiniPlugin
{
_clientsProcessing.decrementAndGet();
}
-
- if (Bukkit.hasWhitelist() && !Get(event.getName()).GetRank().has(WHITELIST_BYPASS))
+
+ if (Bukkit.hasWhitelist() && !Get(event.getUniqueId()).GetRank().has(WHITELIST_BYPASS))
{
for (OfflinePlayer player : Bukkit.getWhitelistedPlayers())
{
@@ -212,7 +216,7 @@ public class CoreClientManager extends MiniPlugin
return;
}
}
-
+
event.disallow(Result.KICK_WHITELIST, "You are not whitelisted my friend.");
}
}
@@ -226,93 +230,84 @@ public class CoreClientManager extends MiniPlugin
{
_repository.getAccountId(uuid, callback);
}
-
+
public void loadClientByName(final String playerName, final Runnable runnable)
{
- Bukkit.getServer().getScheduler().runTaskAsynchronously(getPlugin(), new Runnable()
+ loadClientByName(playerName, client -> runnable.run());
+ }
+
+ public void loadClientByName(String playerName, Consumer loadedClient)
+ {
+ runAsync(() ->
{
- public void run()
+ AtomicReference loaded = new AtomicReference<>();
+ try
{
- try
+ ClientToken token = null;
+ Gson gson = new Gson();
+
+ // Fails if not in DB and if duplicate.
+ UUID uuid = loadUUIDFromDB(playerName);
+
+ if (uuid == null)
{
- ClientToken token = null;
- Gson gson = new Gson();
-
- // Fails if not in DB and if duplicate.
- UUID uuid = loadUUIDFromDB(playerName);
-
- if (uuid == null)
+ uuid = UtilGameProfile.getProfileByName(playerName, false, profile -> {}).get().getId();
+ }
+
+ String response = "";
+
+ if (uuid == null)
+ {
+ response = _repository.getClientByName(playerName);
+ }
+ else
+ {
+ response = _repository.getClientByUUID(uuid);
+ }
+
+ token = gson.fromJson(response, ClientToken.class);
+
+ CoreClient client = Add(playerName, uuid);
+ client.SetRank(Rank.valueOf(token.Rank), false);
+ client.setAccountId(_repository.login(_loginProcessors, uuid, client.getName()));
+
+ // JSON sql response
+ Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
+
+ if (client.getAccountId() > 0)
+ {
+ PlayerInfo playerInfo = PlayerCache.getInstance().getPlayer(uuid);
+
+ if (playerInfo != null)
{
- try
- {
- uuid = UUIDFetcher.getUUIDOf(playerName);
- }
- catch (Exception exception)
- {
- System.out.println("Error fetching uuid from mojang : " + exception.getMessage());
- }
- }
-
- String response = "";
-
- if (uuid == null)
- {
- response = _repository.getClientByName(playerName);
- }
- else
- {
- response = _repository.getClientByUUID(uuid);
- }
-
- token = gson.fromJson(response, ClientToken.class);
-
- CoreClient client = Add(playerName);
- client.SetRank(Rank.valueOf(token.Rank), false);
- client.setAccountId(_repository.login(_loginProcessors, uuid, client.GetPlayerName()));
-
- // JSON sql response
- Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
-
- if (client.getAccountId() > 0)
- {
- PlayerInfo playerInfo = PlayerCache.getInstance().getPlayer(uuid);
-
- if (playerInfo != null)
- {
- playerInfo.setAccountId(client.getAccountId());
- PlayerCache.getInstance().addPlayer(playerInfo);
- }
+ playerInfo.setAccountId(client.getAccountId());
+ PlayerCache.getInstance().addPlayer(playerInfo);
}
}
- catch (Exception exception)
- {
- exception.printStackTrace();
- }
- finally
- {
- Bukkit.getServer().getScheduler().runTask(getPlugin(), new Runnable()
- {
- public void run()
- {
- if (runnable != null)
- runnable.run();
- }
- });
- }
+
+ loaded.set(client);
+ }
+ catch (Exception exception)
+ {
+ exception.printStackTrace();
+ }
+ finally
+ {
+ UtilTasks.onMainThread(() -> loadedClient.accept(loaded.get())).run();
}
});
}
-
+
public void loadClientByNameSync(final String playerName, final Runnable runnable)
{
try
{
ClientToken token = null;
Gson gson = new Gson();
-
+
// Fails if not in DB and if duplicate.
UUID uuid = loadUUIDFromDB(playerName);
-
+
if (uuid == null)
{
try
@@ -324,9 +319,9 @@ public class CoreClientManager extends MiniPlugin
System.out.println("Error fetching uuid from mojang : " + exception.getMessage());
}
}
-
+
String response = "";
-
+
if (uuid == null)
{
response = _repository.getClientByName(playerName);
@@ -335,20 +330,20 @@ public class CoreClientManager extends MiniPlugin
{
response = _repository.getClientByUUID(uuid);
}
-
- token = gson.fromJson(response, ClientToken.class);
- CoreClient client = Add(playerName);
- client.SetRank(Rank.valueOf(token.Rank), false);
- client.setAccountId(_repository.login(_loginProcessors, uuid, client.GetPlayerName()));
-
+ token = gson.fromJson(response, ClientToken.class);
+
+ CoreClient client = Add(playerName, uuid);
+ client.SetRank(Rank.valueOf(token.Rank), false);
+ client.setAccountId(_repository.login(_loginProcessors, uuid, client.getName()));
+
// JSON sql response
Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
-
+
if (client.getAccountId() > 0)
{
PlayerInfo playerInfo = PlayerCache.getInstance().getPlayer(uuid);
-
+
if (playerInfo != null)
{
playerInfo.setAccountId(client.getAccountId());
@@ -358,7 +353,7 @@ public class CoreClientManager extends MiniPlugin
}
catch (Exception exception)
{
- exception.printStackTrace();
+ exception.printStackTrace();
}
finally
{
@@ -372,13 +367,13 @@ public class CoreClientManager extends MiniPlugin
});
}
}
-
+
public boolean LoadClient(final CoreClient client, final UUID uuid, String ipAddress)
{
- TimingManager.start(client.GetPlayerName() + " LoadClient Total.");
+ TimingManager.start(client.getName() + " LoadClient Total.");
long timeStart = System.currentTimeMillis();
- _clientLoginLock.put(client.GetPlayerName(), new Object());
+ CLIENT_LOGIN_LOCKS.put(client.getName(), new Object());
ClientToken token = null;
Gson gson = new Gson();
@@ -387,33 +382,36 @@ public class CoreClientManager extends MiniPlugin
@Override
public void run()
{
- try {
- client.setAccountId(_repository.login(_loginProcessors, uuid, client.GetPlayerName()));
- } catch (SQLException e) {
+ try
+ {
+ client.setAccountId(_repository.login(_loginProcessors, uuid, client.getName()));
+ }
+ catch (SQLException e)
+ {
// TODO Auto-generated catch block
e.printStackTrace();
}
- _clientLoginLock.remove(client.GetPlayerName());
+ CLIENT_LOGIN_LOCKS.remove(client.getName());
}
});
-
- TimingManager.start(client.GetPlayerName() + " GetClient.");
- String response = _repository.GetClient(client.GetPlayerName(), uuid, ipAddress);
- TimingManager.stop(client.GetPlayerName() + " GetClient.");
- TimingManager.start(client.GetPlayerName() + " Event.");
- token = gson.fromJson(response, ClientToken.class);
-
+ TimingManager.start(client.getName() + " GetClient.");
+ String response = _repository.GetClient(client.getName(), uuid, ipAddress);
+ TimingManager.stop(client.getName() + " GetClient.");
+
+ TimingManager.start(client.getName() + " Event.");
+ token = gson.fromJson(response, ClientToken.class);
+
client.SetRank(Rank.valueOf(token.Rank), false);
-
+
// _repository.updateMysqlRank(uuid.toString(), token.Rank, token.RankPerm, new Timestamp(Date.parse(token.RankExpire)).toString());
-
+
// JSON sql response
Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
- TimingManager.stop(client.GetPlayerName() + " Event.");
+ TimingManager.stop(client.getName() + " Event.");
- TimingManager.start(client.GetPlayerName() + " While Loop.");
- while (_clientLoginLock.containsKey(client.GetPlayerName()) && System.currentTimeMillis() - timeStart < 15000)
+ TimingManager.start(client.getName() + " While Loop.");
+ while (CLIENT_LOGIN_LOCKS.containsKey(client.getName()) && System.currentTimeMillis() - timeStart < 15000)
{
try
{
@@ -424,19 +422,19 @@ public class CoreClientManager extends MiniPlugin
e.printStackTrace();
}
}
- TimingManager.stop(client.GetPlayerName() + " While Loop.");
-
- if (_clientLoginLock.containsKey(client.GetPlayerName()))
+ TimingManager.stop(client.getName() + " While Loop.");
+
+ if (CLIENT_LOGIN_LOCKS.containsKey(client.getName()))
{
System.out.println("MYSQL TOO LONG TO LOGIN....");
}
-
- TimingManager.stop(client.GetPlayerName() + " LoadClient Total.");
-
+
+ TimingManager.stop(client.getName() + " LoadClient Total.");
+
if (client.getAccountId() > 0)
{
PlayerInfo playerInfo = PlayerCache.getInstance().getPlayer(uuid);
-
+
if (playerInfo != null)
{
client.setNetworkSessionLoginTime(playerInfo.getLoginTime());
@@ -444,32 +442,32 @@ public class CoreClientManager extends MiniPlugin
PlayerCache.getInstance().addPlayer(playerInfo);
}
}
-
- return !_clientLoginLock.containsKey(client.GetPlayerName());
+
+ return !CLIENT_LOGIN_LOCKS.containsKey(client.getName());
}
@EventHandler(priority = EventPriority.LOWEST)
public void Login(PlayerLoginEvent event)
{
- synchronized(_clientLock)
+ synchronized (_clientLock)
{
- if (!_clientList.containsKey(event.getPlayer().getName()))
+ if (!_clientList.containsKey(event.getPlayer().getUniqueId()))
{
- _clientList.put(event.getPlayer().getName(), new CoreClient(event.getPlayer().getName()));
+ _clientList.put(event.getPlayer().getUniqueId(), new CoreClient(event.getPlayer().getName(), event.getPlayer().getUniqueId()));
}
}
- CoreClient client = Get(event.getPlayer().getName());
-
- if (client == null || client.GetRank() == null)
- {
- event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "There was an error logging you in. Please reconnect.");
- return;
- }
-
- client.SetPlayer(event.getPlayer());
-
- // Reserved Slot Check
+ CoreClient client = Get(event.getPlayer().getUniqueId());
+
+ if (client == null || client.GetRank() == null)
+ {
+ event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "There was an error logging you in. Please reconnect.");
+ return;
+ }
+
+ client.SetPlayer(event.getPlayer());
+
+ // Reserved Slot Check
if (Bukkit.getOnlinePlayers().size() >= Bukkit.getServer().getMaxPlayers())
{
if (client.GetRank().has(event.getPlayer(), Rank.ULTRA, false))
@@ -478,27 +476,29 @@ public class CoreClientManager extends MiniPlugin
event.setResult(PlayerLoginEvent.Result.ALLOWED);
return;
}
-
+
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "This server is full and no longer accepts players.");
}
}
-
+
@EventHandler
public void Kick(PlayerKickEvent event)
{
if (event.getReason().contains("You logged in from another location"))
{
- _duplicateLoginGlitchPreventionList.add(event.getPlayer().getName());
- Bukkit.getScheduler().runTask(_plugin, new Runnable() {
- public void run() {
- if(!_clientList.containsKey(event.getPlayer().getName())) return;
- Player p = _clientList.get(event.getPlayer().getName()).GetPlayer();
- p.kickPlayer("You're already logged in.");
- }
+ _duplicateLoginGlitchPreventionList.add(event.getPlayer().getUniqueId());
+ Bukkit.getScheduler().runTask(_plugin, new Runnable()
+ {
+ public void run()
+ {
+ if (!_clientList.containsKey(event.getPlayer().getUniqueId())) return;
+ Player p = _clientList.get(event.getPlayer().getUniqueId()).GetPlayer();
+ p.kickPlayer("You're already logged in.");
+ }
});
}
}
-
+
@EventHandler(priority = EventPriority.MONITOR)
public void Quit(PlayerQuitEvent event)
{
@@ -509,11 +509,11 @@ public class CoreClientManager extends MiniPlugin
// PlayerKick -> old
// PlayerQuit -> old
// Then it glitches because it added new, but then removed old afterwards since its based on name as key.
-
- if (!_duplicateLoginGlitchPreventionList.contains(event.getPlayer().getName()))
+
+ if (!_duplicateLoginGlitchPreventionList.contains(event.getPlayer().getUniqueId()))
{
- Del(event.getPlayer().getName(), _clientList.get(event.getPlayer().getName()).getAccountId());
- _duplicateLoginGlitchPreventionList.remove(event.getPlayer().getName());
+ Del(event.getPlayer().getName(), event.getPlayer().getUniqueId(), _clientList.get(event.getPlayer().getUniqueId()).getAccountId());
+ _duplicateLoginGlitchPreventionList.remove(event.getPlayer().getUniqueId());
}
}
@@ -525,14 +525,14 @@ public class CoreClientManager extends MiniPlugin
{
if (_plugin.getServer().getPlayer(name) != null)
{
- CoreClient client = Get(name);
+ CoreClient client = Get(name);
client.SetRank(newRank, false);
}
}
}, name, uuid, rank, perm);
}
-
+
public void SaveRank(final Callback callback, final String name, final UUID uuid, Rank rank, boolean perm)
{
_repository.saveRank(new Callback()
@@ -541,17 +541,17 @@ public class CoreClientManager extends MiniPlugin
{
if (_plugin.getServer().getPlayer(name) != null)
{
- CoreClient client = Get(name);
+ CoreClient client = Get(name);
client.SetRank(newRank, false);
}
-
+
if (callback != null)
callback.run(newRank);
}
}, name, uuid, rank, perm);
}
-
+
public void checkPlayerNameExact(final Callback callback, final String playerName)
{
_repository.matchPlayerName(new Callback>()
@@ -570,7 +570,7 @@ public class CoreClientManager extends MiniPlugin
}
}, playerName);
}
-
+
public void checkPlayerName(final Player caller, final String playerName, final Callback callback)
{
_repository.matchPlayerName(new Callback>()
@@ -617,51 +617,51 @@ public class CoreClientManager extends MiniPlugin
}
}, playerName);
}
-
+
// DONT USE THIS IN PRODUCTION...its for enjin listener -someone you despise but definitely not me (defek7)
public UUID loadUUIDFromDB(String name)
{
return _repository.getClientUUID(name);
}
-
+
@EventHandler
public void cleanGlitchedClients(UpdateEvent event)
{
if (event.getType() != UpdateType.SLOW)
return;
-
- synchronized(_clientLock)
+
+ synchronized (_clientLock)
{
- for (Iterator> clientIterator = _clientList.entrySet().iterator(); clientIterator.hasNext();)
+ for (Iterator> clientIterator = _clientList.entrySet().iterator(); clientIterator.hasNext(); )
{
CoreClient client = clientIterator.next().getValue(); // rawr, needed this for custom data - william
Player clientPlayer = client.GetPlayer();
-
+
if (clientPlayer != null && !clientPlayer.isOnline())
{
clientIterator.remove();
-
+
if (clientPlayer != null)
{
- _plugin.getServer().getPluginManager().callEvent(new ClientUnloadEvent(clientPlayer.getName(), client.getAccountId()));
+ _plugin.getServer().getPluginManager().callEvent(new ClientUnloadEvent(clientPlayer.getName(), clientPlayer.getUniqueId(), client.getAccountId()));
}
}
}
}
}
-
+
@EventHandler
public void debug(UpdateEvent event)
{
if (event.getType() != UpdateType.SLOWER)
return;
-
+
// System.out.println("=====");
// System.out.println("Connecting : " + _clientsConnecting.get());
// System.out.println("Processing : " + _clientsProcessing.get());
// System.out.println("=====");
}
-
+
public void addStoredProcedureLoginProcessor(ILoginProcessor processor)
{
_loginProcessors.add(processor);
@@ -672,7 +672,7 @@ public class CoreClientManager extends MiniPlugin
CoreClient client = Get(player);
if (client == null)
return false;
-
+
return client.GetRank().has(rank);
}
}
\ No newline at end of file
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/ILoginProcessor.java b/Plugins/Mineplex.Core/src/mineplex/core/account/ILoginProcessor.java
index 7c7db7911..6aa25a27b 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/ILoginProcessor.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/ILoginProcessor.java
@@ -2,12 +2,13 @@ package mineplex.core.account;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.UUID;
public interface ILoginProcessor
{
String getName();
- void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException;
+ void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException;
String getQuery(int accountId, String uuid, String name);
}
\ No newline at end of file
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/event/ClientUnloadEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/account/event/ClientUnloadEvent.java
index d0d2d467a..47325e2c1 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/event/ClientUnloadEvent.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/event/ClientUnloadEvent.java
@@ -3,36 +3,45 @@ package mineplex.core.account.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+import java.util.UUID;
+
public class ClientUnloadEvent extends Event
{
- private static final HandlerList handlers = new HandlerList();
-
- private String _name;
- private int _accountId;
+ private static final HandlerList handlers = new HandlerList();
- public ClientUnloadEvent(String name, int accountId)
- {
- _name = name;
- _accountId = accountId;
- }
-
- public String GetName()
- {
- return _name;
- }
+ private String _name;
+ private UUID _uuid;
+ private int _accountId;
- public int getAccountId()
- {
- return _accountId;
- }
+ public ClientUnloadEvent(String name, UUID uuid, int accountId)
+ {
+ _name = name;
+ _accountId = accountId;
+ this._uuid = uuid;
+ }
- public HandlerList getHandlers()
- {
- return handlers;
- }
-
- public static HandlerList getHandlerList()
- {
- return handlers;
- }
+ public String GetName()
+ {
+ return _name;
+ }
+
+ public UUID getUniqueId()
+ {
+ return this._uuid;
+ }
+
+ public int getAccountId()
+ {
+ return _accountId;
+ }
+
+ public HandlerList getHandlers()
+ {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList()
+ {
+ return handlers;
+ }
}
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 e00cd1b21..daea474e6 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java
@@ -113,7 +113,7 @@ public class AccountRepository extends MinecraftRepository
for (ILoginProcessor loginProcessor : loginProcessors)
{
- loginProcessor.processLoginResultSet(name, finalId, statement.getResultSet());
+ loginProcessor.processLoginResultSet(name, uuid, finalId, statement.getResultSet());
statement.getMoreResults();
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java
index 5cdc68527..dbd63549c 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java
@@ -18,6 +18,8 @@ import mineplex.core.incognito.IncognitoManager;
import mineplex.core.stats.StatsManager;
import mineplex.core.stats.event.StatChangeEvent;
+import java.util.UUID;
+
public class AchievementManager extends MiniPlugin
{
private IncognitoManager _incognitoManager;
@@ -44,16 +46,16 @@ public class AchievementManager extends MiniPlugin
public AchievementData get(Player player, Achievement type)
{
- return get(player.getName(), type);
+ return get(player.getUniqueId(), type);
}
- public AchievementData get(String playerName, Achievement type)
+ public AchievementData get(UUID playerUUID, Achievement type)
{
int exp = 0;
for (String stat : type.getStats())
{
- exp += _statsManager.Get(playerName).getStat(stat);
+ exp += _statsManager.Get(playerUUID).getStat(stat);
}
return type.getLevelData(exp);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
index 2bd3903b3..ebcc16e82 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
@@ -1,59 +1,110 @@
package mineplex.core.antihack;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.GameMode;
-import org.bukkit.Material;
-import org.bukkit.Sound;
-import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.player.PlayerMoveEvent;
-import org.bukkit.event.player.PlayerQuitEvent;
-import org.bukkit.event.player.PlayerTeleportEvent;
-import org.bukkit.event.player.PlayerVelocityEvent;
-import org.bukkit.event.server.ServerListPingEvent;
-import org.bukkit.plugin.java.JavaPlugin;
-
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.AtomicDouble;
+import com.mineplex.anticheat.api.GameEndEvent;
+import com.mineplex.anticheat.api.GameStartEvent;
+import com.mineplex.anticheat.api.MineplexLink;
+import com.mineplex.anticheat.api.PlayerViolationEvent;
+import mineplex.core.Managers;
import mineplex.core.MiniPlugin;
+import mineplex.core.PlayerSelector;
+import mineplex.core.ReflectivelyCreateMiniPlugin;
+import mineplex.core.account.CoreClient;
import mineplex.core.account.CoreClientManager;
+import mineplex.core.antihack.actions.AntiHackAction;
+import mineplex.core.antihack.banwave.BanWaveManager;
import mineplex.core.antihack.types.Fly;
import mineplex.core.antihack.types.Idle;
import mineplex.core.antihack.types.Reach;
import mineplex.core.antihack.types.Speed;
+import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
-import mineplex.core.common.util.C;
-import mineplex.core.common.util.F;
-import mineplex.core.common.util.UtilEnt;
-import mineplex.core.common.util.UtilInv;
-import mineplex.core.common.util.UtilMath;
-import mineplex.core.common.util.UtilPlayer;
-import mineplex.core.common.util.UtilServer;
-import mineplex.core.common.util.UtilTime;
+import mineplex.core.common.util.*;
+import mineplex.core.disguise.DisguiseManager;
+import mineplex.core.disguise.disguises.DisguiseBase;
import mineplex.core.portal.Portal;
+import mineplex.core.preferences.Preference;
import mineplex.core.preferences.PreferencesManager;
+import mineplex.core.punish.Category;
import mineplex.core.punish.Punish;
+import mineplex.core.punish.PunishClient;
+import mineplex.core.punish.Punishment;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
+import mineplex.serverdata.commands.ServerCommandManager;
+import net.minecraft.server.v1_8_R3.*;
+import org.bukkit.*;
+import org.bukkit.Material;
+import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.player.*;
+import org.bukkit.event.server.ServerListPingEvent;
+import org.bukkit.plugin.ServicePriority;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+import org.bukkit.scheduler.BukkitTask;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+@ReflectivelyCreateMiniPlugin
public class AntiHack extends MiniPlugin
{
- public static AntiHack Instance;
+ public static final Map CHECKS = ImmutableMap.of(
+ "Killaura (Type A)", new CheckThresholds("Kill Aura", 25, 50),
+ "Killaura (Type B)", new CheckThresholds("High CPS", 0, Integer.MAX_VALUE),
+ "Killaura (Type C)", new CheckThresholds("Reach", Integer.MAX_VALUE, Integer.MAX_VALUE),
+ "Killaura (Type D)", new CheckThresholds("Kill Aura", 1000, 1500),
+ "BadPackets", new CheckThresholds("Regen", 1000, 2000)
+ );
+
+ public static final String NAME = "Chiss";
+ public static final String USER_HAS_BEEN_BANNED = F.main("GWEN", "%s has been banned. I am always watching");
+ public static final String USER_HAS_BEEN_BANNED_BANWAVE = USER_HAS_BEEN_BANNED;
+
+ private static final int VL_DIFF_BEFORE_RENOTIFY = 999999;
+ private static final int MAX_STALKED_PLAYERS = 3;
+ private static final int STALK_COOLDOWN_TIME_SECONDS = 5;
+ private static final int MIN_STALK_TIME = 10 * 20;
+ private static final int MAX_STALK_TIME = 20 * 20;
+ private static final int MAX_MIN_DIFF = MAX_STALK_TIME - MIN_STALK_TIME;
+ private static final Function STALK_END_PROBABILITY_EQUATION = x ->
+ {
+ return 1.0/ MAX_MIN_DIFF * x; // linear equation with points (0, 0) and (diff, 1)
+ };
+
+ private final Cache _cooldown = CacheBuilder.newBuilder()
+ .concurrencyLevel(1)
+ .expireAfterWrite(30, TimeUnit.SECONDS)
+ .build();
+
+ private final Cache _stalkingCooldown = CacheBuilder.newBuilder()
+ .concurrencyLevel(1)
+ .expireAfterWrite(STALK_COOLDOWN_TIME_SECONDS, TimeUnit.SECONDS)
+ .build();
+ private final List _stalking = new ArrayList<>();
+
+ private final String _thisServer;
private boolean _enabled = true;
private boolean _strict = false;
private boolean _kick = true;
- public Punish Punish;
- public Portal Portal;
- private PreferencesManager _preferences;
- private CoreClientManager _clientManager;
+ public Portal Portal = require(Portal.class);
+ private PreferencesManager _preferences = require(PreferencesManager.class);
+ private CoreClientManager _clientManager = require(CoreClientManager.class);
//Record Offenses
private HashMap>> _offense = new HashMap>>();
@@ -63,16 +114,16 @@ public class AntiHack extends MiniPlugin
//Player Info
private HashSet _velocityEvent = new HashSet();
- private HashMap _lastMoveEvent = new HashMap();
-
+ private HashMap _lastMoveEvent = new HashMap();
+
private HashSet _hubAttempted = new HashSet();
//Hack Requirements
- public int FloatHackTicks = 10;
- public int HoverHackTicks = 4;
+ public int FloatHackTicks = 10;
+ public int HoverHackTicks = 4;
public int RiseHackTicks = 6;
public int SpeedHackTicks = 6;
- public int IdleTime = 20000;
+ public int IdleTime = 20000;
public int KeepOffensesFor = 30000;
@@ -81,19 +132,25 @@ public class AntiHack extends MiniPlugin
public ArrayList _movementDetectors;
public ArrayList _combatDetectors;
-
+
private AntiHackRepository _repository;
- protected AntiHack(JavaPlugin plugin, Punish punish, Portal portal, PreferencesManager preferences, CoreClientManager clientManager)
+ private List _guardians = new ArrayList<>();
+
+ private Predicate _filter = player -> true;
+
+ private Set _pendingBan = new HashSet<>();
+
+ @SuppressWarnings("Convert2streamapi")
+ private AntiHack()
{
- super("AntiHack", plugin);
+ super("AntiHack");
- Punish = punish;
- Portal = portal;
- _preferences = preferences;
- _clientManager = clientManager;
+ DisguiseManager disguiseManager = require(DisguiseManager.class);
- _repository = new AntiHackRepository(plugin.getConfig().getString("serverstatus.name"));
+ this._thisServer = UtilServer.getServerNameFromConfig();
+
+ _repository = new AntiHackRepository(this._thisServer);
_repository.initialize();
_movementDetectors = new ArrayList();
@@ -102,13 +159,598 @@ public class AntiHack extends MiniPlugin
_movementDetectors.add(new Fly(this));
_movementDetectors.add(new Idle(this));
_movementDetectors.add(new Speed(this));
-
+
_combatDetectors.add(new Reach(this));
+
+ Bukkit.getServicesManager().register(MineplexLink.class, new MineplexLink()
+ {
+ @Override
+ public EntityType getActiveDisguise(Player player)
+ {
+ DisguiseBase disguise = disguiseManager.getActiveDisguise(player);
+ return disguise != null ? disguise.getDisguiseType() : null;
+ }
+
+ @Override
+ public boolean isSpectator(Player player)
+ {
+ return UtilPlayer.isSpectator(player);
+ }
+ }, this._plugin, ServicePriority.Normal);
+
+ ServerCommandManager.getInstance().registerCommandType(MajorViolationCommand.class, violation ->
+ {
+ IChatBaseComponent component = getMinimalMessage(violation);
+
+ for (Player player : Bukkit.getOnlinePlayers())
+ {
+ if (player.getName().equals("Spoobncoobr"))
+ {
+ ((CraftPlayer) player).getHandle().sendMessage(getDetailedMessage(violation));
+
+ } else if (_clientManager.Get(player).GetRank().has(Rank.HELPER) && (violation.getOriginatingServer().equals(_thisServer) || Managers.get(PreferencesManager.class).get(player).isActive(Preference.GLOBAL_GWEN_REPORTS)))
+ {
+ ((CraftPlayer) player).getHandle().sendMessage(component);
+ }
+ }
+ });
+
+ this._plugin.getServer().getScheduler().runTaskTimer(this._plugin, () ->
+ {
+ for (AntiHackGuardian guardian : this._guardians)
+ {
+ if (guardian.getTarget() != null && !guardian.getTarget().isOnline())
+ {
+ this._stalking.remove(guardian.getTarget().getUniqueId());
+ guardian.stopTargeting();
+ }
+ else if (guardian.getTargetingTime() > MIN_STALK_TIME)
+ {
+ double threshold = STALK_END_PROBABILITY_EQUATION.apply(guardian.getTargetingTime() - MIN_STALK_TIME);
+ if (Math.random() <= threshold)
+ {
+ this._stalking.remove(guardian.getTarget().getUniqueId());
+ _stalkingCooldown.put(guardian.getTarget().getUniqueId(), true);
+ guardian.stopTargeting();
+ }
+ }
+ guardian.tick();
+ }
+ }, 0L, 1L);
+
+ this._plugin.getServer().getScheduler().runTaskTimer(this._plugin, () ->
+ {
+ if (_stalking.size() >= MAX_STALKED_PLAYERS)
+ {
+ return;
+ }
+
+ if (_guardians.size() == 0)
+ {
+ return;
+ }
+
+ List targets = PlayerSelector.selectPlayers(PlayerSelector.and(
+ PlayerSelector.NOT_VANISHED,
+ PlayerSelector.hasAnyRank(false,
+ Rank.ALL,
+ Rank.ULTRA,
+ Rank.HERO,
+ Rank.LEGEND,
+ Rank.TITAN,
+ Rank.TWITCH,
+ Rank.YOUTUBE_SMALL,
+ Rank.YOUTUBE,
+ Rank.MEDIA,
+ Rank.ADMIN,
+ Rank.DEVELOPER,
+ Rank.OWNER,
+ Rank.LT
+ ),
+ player -> !_stalking.contains(player.getUniqueId()),
+ player -> _stalkingCooldown.getIfPresent(player.getUniqueId()) == null,
+ _filter
+ ));
+
+ while (_stalking.size() < MAX_STALKED_PLAYERS && targets.size() > 0)
+ {
+ Player target = targets.remove(ThreadLocalRandom.current().nextInt(targets.size()));
+
+ int start = ThreadLocalRandom.current().nextInt(_guardians.size());
+
+ for (int i = start, j = 0; j < _guardians.size(); i++, j++)
+ {
+ if (i >= _guardians.size())
+ {
+ i -= _guardians.size();
+ }
+ AntiHackGuardian guardian = _guardians.get(i);
+ if (!guardian.isTargeting())
+ {
+ guardian.target(target);
+ _stalking.add(target.getUniqueId());
+ break;
+ }
+ }
+ }
+ }, 0L, 20L);
+
+ require(BanWaveManager.class);
}
- public static void Initialize(JavaPlugin plugin, Punish punish, Portal portal, PreferencesManager preferences, CoreClientManager clientManager)
+ private IChatBaseComponent getDetailedMessage(MajorViolationCommand violation)
{
- Instance = new AntiHack(plugin, punish, portal, preferences, clientManager);
+ return new ChatComponentText("")
+ .addSibling(
+ new ChatComponentText("A")
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.AQUA)
+ .setRandom(true)
+ )
+ )
+ .addSibling(
+ new ChatComponentText(" GWEN > ")
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.RED)
+ .setBold(true)
+ )
+ )
+ .addSibling(
+ new ChatComponentText(violation.getPlayerName())
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.GOLD)
+ )
+ )
+ .addSibling(
+ new ChatComponentText(" failed " + violation.getHackType() + " VL" + violation.getViolations() + " in server ")
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.YELLOW)
+ )
+ )
+ .addSibling(
+ new ChatComponentText(
+ violation.getOriginatingServer()
+ )
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.YELLOW)
+ .setChatClickable(
+ new ChatClickable(
+ ChatClickable.EnumClickAction.RUN_COMMAND,
+ "/server " + violation.getOriginatingServer()
+ )
+ )
+ .setChatHoverable(
+ new ChatHoverable(
+ ChatHoverable.EnumHoverAction.SHOW_TEXT,
+ new ChatComponentText("Teleport to " + violation.getOriginatingServer())
+ )
+ )
+ )
+ )
+ .addSibling(
+ new ChatComponentText(": " + violation.getMessage() + ". Please investigate!")
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.YELLOW)
+ )
+ );
+ }
+
+ private IChatBaseComponent getMinimalMessage(MajorViolationCommand violation)
+ {
+ IChatBaseComponent component = new ChatComponentText("")
+ .addSibling(
+ new ChatComponentText("A")
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.AQUA)
+ .setRandom(true)
+ )
+ )
+ .addSibling(
+ new ChatComponentText(" GWEN > ")
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.RED)
+ .setBold(true)
+ )
+ )
+ .addSibling(
+ new ChatComponentText(violation.getPlayerName())
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.GOLD)
+ )
+ )
+ .addSibling(
+ new ChatComponentText(" suspected of ")
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.YELLOW)
+ )
+ )
+ .addSibling(CHECKS.get(violation.getHackType()).format(violation.getViolations()));
+
+ if (!violation.getOriginatingServer().equals(this._thisServer))
+ {
+ component
+ .addSibling(
+ new ChatComponentText(" in ")
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.YELLOW)
+ )
+ )
+ .addSibling(
+ new ChatComponentText(violation.getOriginatingServer())
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.AQUA)
+ .setChatClickable(
+ new ChatClickable(
+ ChatClickable.EnumClickAction.RUN_COMMAND,
+ "/server " + violation.getOriginatingServer()
+ )
+ )
+ .setChatHoverable(
+ new ChatHoverable(
+ ChatHoverable.EnumHoverAction.SHOW_TEXT,
+ new ChatComponentText("Teleport to " + violation.getOriginatingServer())
+ )
+ )
+ )
+ );
+ }
+
+ return component.addSibling(
+ new ChatComponentText(". Please investigate!")
+ .setChatModifier(
+ new ChatModifier()
+ .setColor(EnumChatFormat.YELLOW)
+ )
+ );
+ }
+
+ public void registerFilter(Predicate filter)
+ {
+ if (filter == null)
+ {
+ this._filter = player -> true;
+ }
+ else
+ {
+ this._filter = filter;
+ }
+ }
+
+ public void registerGuardian(AntiHackGuardian guardian)
+ {
+ this._guardians.add(guardian);
+ }
+
+ public void clearGuardians()
+ {
+ this._guardians.forEach(AntiHackGuardian::remove);
+ this._guardians.clear();
+ this._stalking.clear();
+ this._stalkingCooldown.cleanUp();
+ }
+
+ public void runBanAnimation(Player player, Runnable after)
+ {
+ if (_pendingBan.add(player))
+ {
+ float oldWalkSpeed = player.getWalkSpeed();
+ player.setWalkSpeed(0);
+ player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 999999, -10));
+
+ double radius = 4;
+ double heightAdj = 8;
+
+ double baseDeg = 18;
+
+ Location center = player.getLocation().add(0, heightAdj, 0);
+ AntiHackGuardian north = new AntiHackGuardian(center.clone().add(0, 0, -radius), 0, 0, 0, 0, 0, 0);
+ AntiHackGuardian east = new AntiHackGuardian(center.clone().add(radius, 0, 0), 0, 0, 0, 0, 0, 0);
+ AntiHackGuardian south = new AntiHackGuardian(center.clone().add(0, 0, radius), 0, 0, 0, 0, 0, 0);
+ AntiHackGuardian west = new AntiHackGuardian(center.clone().add(-radius, 0, 0), 0, 0, 0, 0, 0, 0);
+
+ UtilEnt.CreatureLook(east.getEntity(), player);
+ UtilEnt.CreatureLook(west.getEntity(), player);
+ UtilEnt.CreatureLook(south.getEntity(), player);
+ UtilEnt.CreatureLook(north.getEntity(), player);
+
+ Function magic = seconds ->
+ {
+ return Math.pow(2, seconds - 5);
+ };
+
+ runSyncLater(() ->
+ {
+ north.shoot(player);
+ east.shoot(player);
+ south.shoot(player);
+ west.shoot(player);
+
+ // We get 5 seconds, or 100 ticks
+ AtomicInteger timer = new AtomicInteger(5);
+ AtomicReference task = new AtomicReference<>();
+
+ AtomicDouble cNorth = new AtomicDouble(270);
+ AtomicDouble cEast = new AtomicDouble(0);
+ AtomicDouble cSouth = new AtomicDouble(90);
+ AtomicDouble cWest = new AtomicDouble(180);
+
+ task.set(runSyncTimer(() ->
+ {
+ timer.getAndIncrement();
+ if (timer.get() > 100)
+ {
+ task.get().cancel();
+
+ player.removePotionEffect(PotionEffectType.JUMP);
+ player.setWalkSpeed(oldWalkSpeed);
+ Location location = player.getLocation();
+
+ UtilParticle.PlayParticle(UtilParticle.ParticleType.HUGE_EXPLOSION, player.getLocation(), 3f, 3f, 3f, 0, 32, UtilParticle.ViewDist.MAX, UtilServer.getPlayers());
+
+ after.run();
+
+ _pendingBan.remove(player);
+
+ north.shoot(null);
+ south.shoot(null);
+ east.shoot(null);
+ west.shoot(null);
+ UtilEnt.CreatureLook(north.getEntity(), location);
+ UtilEnt.CreatureLook(south.getEntity(), location);
+ UtilEnt.CreatureLook(east.getEntity(), location);
+ UtilEnt.CreatureLook(west.getEntity(), location);
+ runSyncLater(() ->
+ {
+ north.remove();
+ south.remove();
+ east.remove();
+ west.remove();
+ }, 40L);
+ return;
+ }
+
+ double seconds = timer.get() / 20.0;
+
+ double rate = magic.apply(seconds) * 3 * baseDeg;
+
+ player.getLocation(center);
+ center.add(0, heightAdj, 0);
+
+ {
+ cNorth.addAndGet(rate);
+ north.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cNorth.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cNorth.get())));
+ }
+ {
+ cSouth.addAndGet(rate);
+ south.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cSouth.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cSouth.get())));
+ }
+ {
+ cEast.addAndGet(rate);
+ east.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cEast.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cEast.get())));
+ }
+ {
+ cWest.addAndGet(rate);
+ west.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cWest.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cWest.get())));
+ }
+ }, 5, 1));
+ }, 20);
+ }
+ }
+
+ public void doBan(Player player, String message)
+ {
+ runSync(() ->
+ {
+ CoreClient coreClient = _clientManager.Get(player);
+
+ if (coreClient.GetRank().has(Rank.TWITCH))
+ {
+ require(Punish.class).AddPunishment(coreClient.getName(), Category.Hacking, message, AntiHack.NAME, 3, true, -1, true);
+ }
+ else
+ {
+ runBanAnimation(player, () ->
+ {
+ require(Punish.class).AddPunishment(coreClient.getName(), Category.Hacking, message, AntiHack.NAME, 3, true, -1, true);
+ announceBan(player);
+ });
+ }
+ });
+ }
+
+ public void doBanWave(Player player, String message)
+ {
+ runSync(() ->
+ {
+ int totalPunishments = getPunishments(player);
+ int daysBanned = getDaysBanned(player);
+ CoreClient coreClient = _clientManager.Get(player);
+ if (coreClient.GetRank().has(Rank.TWITCH))
+ {
+ require(Punish.class).AddPunishment(coreClient.getName(), Category.Hacking, message, AntiHack.NAME, totalPunishments + 1, true, daysBanned == -1 ? -1 : TimeUnit.DAYS.toHours(daysBanned), true);
+ }
+ else
+ {
+ runBanAnimation(player, () ->
+ {
+ require(Punish.class).AddPunishment(coreClient.getName(), Category.Hacking, message, AntiHack.NAME, totalPunishments + 1, true, daysBanned == -1 ? -1 : TimeUnit.DAYS.toHours(daysBanned), true);
+ announceBanwave(player);
+ });
+ }
+ });
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void on(PlayerMoveEvent event)
+ {
+ if (_pendingBan.contains(event.getPlayer()) && UtilMath.offset2d(event.getFrom().getBlock().getLocation(), event.getTo().getBlock().getLocation()) >= 1)
+ {
+ event.setCancelled(true);
+ event.getPlayer().teleport(event.getFrom().getBlock().getLocation().add(0, 1, 0));
+ }
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void on(PlayerInteractEvent event)
+ {
+ if (_pendingBan.contains(event.getPlayer()))
+ {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void on(PlayerToggleFlightEvent event)
+ {
+ if (_pendingBan.contains(event.getPlayer()))
+ {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void on(PlayerCommandPreprocessEvent event)
+ {
+ if (_pendingBan.contains(event.getPlayer()))
+ {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void on(PlayerViolationEvent event)
+ {
+ AntiHackAction.getAction(event.getCheckClass()).handle(event);
+ }
+
+ public void announceBan(Player player)
+ {
+ Bukkit.getServer().broadcastMessage(String.format(USER_HAS_BEEN_BANNED, player.getName()));
+ }
+
+ public void announceBanwave(Player player)
+ {
+ Bukkit.getServer().broadcastMessage(String.format(USER_HAS_BEEN_BANNED_BANWAVE, player.getName()));
+ }
+
+ public int getPunishments(Player player)
+ {
+ PunishClient punishClient = require(Punish.class).GetClient(player.getName());
+
+ int totalPunishments = 0;
+
+ if (punishClient.GetPunishments().containsKey(Category.Hacking))
+ {
+ for (Punishment punishment : punishClient.GetPunishments().get(Category.Hacking))
+ {
+ if (punishment.GetAdmin().equalsIgnoreCase(NAME))
+ {
+ totalPunishments++;
+ }
+ }
+ }
+
+ return totalPunishments;
+ }
+
+ public int getDaysBanned(Player player)
+ {
+ int totalPunishments = getPunishments(player);
+
+ int daysBanned = 0;
+
+ switch (totalPunishments)
+ {
+ case 0:
+ daysBanned = 7;
+ break;
+ case 1:
+ daysBanned = 30;
+ break;
+ case 2:
+ default:
+ daysBanned = -1;
+ }
+
+ return daysBanned;
+ }
+
+ @Override
+ public void addCommands()
+ {
+ if (UtilServer.isTestServer())
+ {
+ addCommand(new CommandBase(this, Rank.DEVELOPER, "acon")
+ {
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ if (caller.getUniqueId().toString().equals("b86b54da-93dd-46f9-be33-27bd92aa36d7"))
+ {
+ enableNewAnticheat();
+ UtilPlayer.message(caller, F.main(getName(), "Enabled new anticheat"));
+ }
+ }
+ });
+ addCommand(new CommandBase(this, Rank.DEVELOPER, "acoff")
+ {
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ if (caller.getUniqueId().toString().equals("b86b54da-93dd-46f9-be33-27bd92aa36d7"))
+ {
+ disableNewAnticheat();
+ UtilPlayer.message(caller, F.main(getName(), "Disabled new anticheat"));
+ }
+ }
+ });
+ addCommand(new CommandBase(this, Rank.DEVELOPER, "testban")
+ {
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ if (caller.getUniqueId().toString().equals("b86b54da-93dd-46f9-be33-27bd92aa36d7"))
+ {
+ if (args.length > 0)
+ {
+ Player p = Bukkit.getPlayerExact(args[0]);
+ if (p != null)
+ {
+ runBanAnimation(p, () ->
+ {
+ String reason = C.cRed + C.Bold + "You are banned for permanent by " + NAME +
+ "\n" + C.cWhite + "Seems to be speeding up time. (" + ThreadLocalRandom.current().nextInt(200, 400) + " packets/150 ms)" +
+ "\n" + C.cDGreen + "Unfairly banned? Appeal at " + C.cGreen + "www.mineplex.com/appeals";
+ p.kickPlayer(reason);
+
+ announceBan(p);
+ });
+ }
+ else
+ {
+ UtilPlayer.message(caller, F.main(getName(), "Could not find player"));
+ }
+ }
+ else
+ {
+ UtilPlayer.message(caller, F.main(getName(), "No player specified"));
+ }
+ }
+ }
+ });
+ }
}
@EventHandler
@@ -193,17 +835,17 @@ public class AntiHack extends MiniPlugin
{
if (player.equals(other))
continue;
-
+
if (other.getGameMode() != GameMode.SURVIVAL || UtilPlayer.isSpectator(player))
continue;
-
+
if (other.getVehicle() != null)
continue;
-
+
if (UtilMath.offset(player, other) < 2)
return true;
}
-
+
if (player.isFlying() || ((CraftPlayer) player).getHandle().isGliding() || player.isInsideVehicle() || player.getGameMode() != GameMode.SURVIVAL || UtilPlayer.isSpectator(player))
{
return true;
@@ -263,16 +905,8 @@ public class AntiHack extends MiniPlugin
total += _offense.get(player).get(curType).size();
}
-
- //Inform
- for (Player admin : UtilServer.getPlayers())
- if (_clientManager.Get(admin).GetRank().has(Rank.MODERATOR) && _preferences.Get(admin).ShowMacReports)
- {
- UtilPlayer.message(admin, "#" + total + ": " + C.cRed + C.Bold + player.getName() + " suspected for " + type + ".");
- }
-
// Print (Debug)
- System.out.println("[Offense] #" + total + ": "+ player.getName() + " received suspicion for " + type + ".");
+ System.out.println("[Offense] #" + total + ": " + player.getName() + " received suspicion for " + type + ".");
}
@EventHandler
@@ -284,11 +918,11 @@ public class AntiHack extends MiniPlugin
if (event.getType() != UpdateType.SEC)
return;
- for (Iterator>>> playerIterator = _offense.entrySet().iterator(); playerIterator.hasNext();)
+ for (Iterator>>> playerIterator = _offense.entrySet().iterator(); playerIterator.hasNext(); )
{
Entry>> entry = playerIterator.next();
Player player = entry.getKey();
-
+
String out = "";
int total = 0;
@@ -315,7 +949,7 @@ public class AntiHack extends MiniPlugin
out = out.substring(0, out.length() - 2);
String severity = "Low";
-
+
if (total > (_strict ? 6 : 18))
severity = "Extreme";
else if (total > (_strict ? 4 : 12))
@@ -325,7 +959,7 @@ public class AntiHack extends MiniPlugin
//Send Report
sendReport(player, out, severity);
-
+
if (severity.equalsIgnoreCase("Extreme"))
{
playerIterator.remove();
@@ -334,6 +968,32 @@ public class AntiHack extends MiniPlugin
}
}
+ @EventHandler
+ public void onHack(PlayerViolationEvent event)
+ {
+ if (event.shouldTellStaff())
+ {
+ String key = event.getPlayer().getName() + "." + event.getHackType() + "." + CHECKS.get(event.getHackType()).getSeverity(event.getViolations()).toString();
+ Integer pastVl = this._cooldown.getIfPresent(key);
+ if (pastVl != null)
+ {
+ if (event.getViolations() - pastVl > VL_DIFF_BEFORE_RENOTIFY)
+ {
+ this._cooldown.put(key, event.getViolations());
+ MajorViolationCommand command = new MajorViolationCommand(_thisServer, event.getPlayer().getName(), event.getHackType(), event.getViolations(), event.getMessage());
+ ServerCommandManager.getInstance().publishCommand(command);
+ }
+ }
+ else
+ {
+ MajorViolationCommand command = new MajorViolationCommand(_thisServer, event.getPlayer().getName(), event.getHackType(), event.getViolations(), event.getMessage());
+ ServerCommandManager.getInstance().publishCommand(command);
+
+ this._cooldown.put(key, event.getViolations());
+ }
+ }
+ }
+
public void sendReport(Player player, String report, String severity)
{
if (severity.equals("Extreme"))
@@ -351,42 +1011,6 @@ public class AntiHack extends MiniPlugin
}
}
- //Auto-Kick
- if (!handled &&
- _clientManager.Get(player).GetRank() != Rank.YOUTUBE &&
- _clientManager.Get(player).GetRank() != Rank.YOUTUBE_SMALL &&
- _clientManager.Get(player).GetRank() != Rank.TWITCH)
- {
- player.playSound(player.getLocation(), Sound.ENDERDRAGON_GROWL, 2f, 0.5f);
-
- if (_kick || _hubAttempted.remove(player))
- {
- player.kickPlayer(
- C.cGold + "Mineplex Anti-Cheat" + "\n" +
- C.cWhite + "You were kicked for suspicious movement." + "\n" +
- C.cWhite + "Cheating may result in a " + C.cRed + "Permanent Ban" + C.cWhite + "." + "\n" +
- C.cWhite + "If you were not cheating, you will not be banned."
- );
- }
- else
- {
- _hubAttempted.add(player);
-
- UtilPlayer.message(player, C.cGold + C.Strike + "---------------------------------------------");
- UtilPlayer.message(player, "");
- UtilPlayer.message(player, C.cGold + "Mineplex Anti-Cheat");
- UtilPlayer.message(player, "");
- UtilPlayer.message(player, "You were kicked from the game for suspicious movement.");
- UtilPlayer.message(player, "Cheating may result in a " + C.cRed + "Permanent Ban" + C.cWhite + ".");
- UtilPlayer.message(player, "If you were not cheating, you will not be banned.");
- UtilPlayer.message(player, "");
- UtilPlayer.message(player, C.cGold + C.Strike + "---------------------------------------------");
- Portal.sendPlayerToServer(player, "Lobby");
- }
-
- UtilServer.broadcast(F.main("MAC", player.getName() + " was kicked for suspicious movement."));
- }
-
//Record
ServerListPingEvent event = new ServerListPingEvent(null, Bukkit.getServer().getMotd(), Bukkit.getServer().getOnlinePlayers().size(), Bukkit.getServer().getMaxPlayers());
getPluginManager().callEvent(event);
@@ -420,7 +1044,7 @@ public class AntiHack extends MiniPlugin
{
resetAll(player, true);
}
-
+
private void resetAll(Player player, boolean removeOffenses)
{
_ignore.remove(player);
@@ -432,7 +1056,7 @@ public class AntiHack extends MiniPlugin
for (Detector detector : _movementDetectors)
detector.Reset(player);
-
+
for (Detector detector : _combatDetectors)
detector.Reset(player);
}
@@ -446,12 +1070,12 @@ public class AntiHack extends MiniPlugin
if (event.getType() != UpdateType.SLOW)
return;
- for (Iterator> playerIterator = _ignore.entrySet().iterator(); playerIterator.hasNext();)
+ for (Iterator> playerIterator = _ignore.entrySet().iterator(); playerIterator.hasNext(); )
{
Player player = playerIterator.next().getKey();
if (!player.isOnline() || player.isDead() || !player.isValid())
- {
+ {
playerIterator.remove();
_velocityEvent.remove(player);
@@ -461,19 +1085,19 @@ public class AntiHack extends MiniPlugin
for (Detector detector : _movementDetectors)
detector.Reset(player);
-
+
for (Detector detector : _combatDetectors)
detector.Reset(player);
}
}
-
- for (Iterator playerIterator = _hubAttempted.iterator(); playerIterator.hasNext();)
+
+ for (Iterator playerIterator = _hubAttempted.iterator(); playerIterator.hasNext(); )
{
Player player = playerIterator.next();
if (!player.isOnline() || !player.isValid())
- {
+ {
playerIterator.remove();
}
}
@@ -503,11 +1127,23 @@ public class AntiHack extends MiniPlugin
{
return _strict;
}
-
+
public void setKick(boolean kick)
{
_kick = kick;
System.out.println("MAC Kick: " + kick);
}
+
+ public void enableNewAnticheat()
+ {
+ UtilServer.CallEvent(new GameStartEvent());
+ System.out.println("Enabled new anticheat");
+ }
+
+ public void disableNewAnticheat()
+ {
+ UtilServer.CallEvent(new GameEndEvent());
+ System.out.println("Disabled new anticheat");
+ }
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackGuardian.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackGuardian.java
new file mode 100644
index 000000000..4f9da5912
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackGuardian.java
@@ -0,0 +1,395 @@
+package mineplex.core.antihack;
+
+import com.mineplex.spigot.ChunkAddEntityEvent;
+import mineplex.core.Managers;
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.common.Rank;
+import mineplex.core.common.util.UtilEnt;
+import mineplex.core.common.util.UtilServer;
+import mineplex.core.disguise.DisguiseManager;
+import mineplex.core.disguise.disguises.DisguiseGuardian;
+import mineplex.core.event.StackerEvent;
+import net.minecraft.server.v1_8_R3.EntityArmorStand;
+import net.minecraft.server.v1_8_R3.EntityPlayer;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
+import org.bukkit.craftbukkit.v1_8_R3.entity.CraftArmorStand;
+import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
+import org.bukkit.entity.ArmorStand;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.EntitySpawnEvent;
+import org.bukkit.util.Vector;
+
+import java.util.Random;
+import java.util.UUID;
+import java.util.function.Function;
+
+public class AntiHackGuardian implements Listener
+{
+ private static final boolean DEBUG = false;
+
+ private static final double DELTA_MOVE_PER_TICK = 0.2;
+
+ private static final Function MAGICAL_FUNCTION = in ->
+ {
+ return Math.pow(100, in - 1);
+ };
+
+ protected Random _random = new Random();
+
+ private Location _center;
+
+ private double _targetX;
+ private double _targetY;
+ private double _targetZ;
+
+ private int _ticksUntilReset;
+
+ private ArmorStand _armorStand;
+ private EntityArmorStand _nmsEntity;
+
+ private DisguiseGuardian _disguise;
+
+ private UUID _entityUUID;
+
+ private Player _target;
+ private int _stalkTime;
+
+ private final double MAX_DISTANCE_X;
+ private final double MIN_DISTANCE_X;
+ private final double MAX_DISTANCE_Y;
+ private final double MIN_DISTANCE_Y;
+ private final double MAX_DISTANCE_Z;
+ private final double MIN_DISTANCE_Z;
+
+ private final double CENTER_X;
+ private final double CENTER_Y;
+ private final double CENTER_Z;
+
+ public AntiHackGuardian(Location center, int maxX, int minX, int maxY, int minY, int maxZ, int minZ)
+ {
+ UtilServer.RegisterEvents(this);
+
+ this.MAX_DISTANCE_X = maxX;
+ this.MIN_DISTANCE_X = minX;
+ this.MAX_DISTANCE_Y = maxY;
+ this.MIN_DISTANCE_Y = minY;
+ this.MAX_DISTANCE_Z = maxZ;
+ this.MIN_DISTANCE_Z = minZ;
+
+ this.CENTER_X = MIN_DISTANCE_X + ((MAX_DISTANCE_X - MIN_DISTANCE_X) / 2.0);
+ this.CENTER_Y = MIN_DISTANCE_Y + ((MAX_DISTANCE_Y - MIN_DISTANCE_Y) / 2.0);
+ this.CENTER_Z = MIN_DISTANCE_Z + ((MAX_DISTANCE_Z - MIN_DISTANCE_Z) / 2.0);
+
+ //debug("Spawning ArmorStand at " + center + "");
+
+ CoreClientManager clientManager = Managers.get(CoreClientManager.class);
+ DisguiseManager disguiseManager = Managers.get(DisguiseManager.class);
+
+ this._center = center;
+ this._center.getChunk().load();
+
+ this._armorStand = (ArmorStand) new EntityArmorStand(((CraftWorld) this._center.getWorld()).getHandle(), this._center.getX(), this._center.getY(), this._center.getZ()).getBukkitEntity();
+ this._armorStand.setGravity(false);
+ this._armorStand.setVisible(false);
+ this._armorStand.setRemoveWhenFarAway(false);
+ this._nmsEntity = ((CraftArmorStand) this._armorStand).getHandle();
+ this._nmsEntity.maxNoDamageTicks = 86400;
+ this._nmsEntity.noDamageTicks = 86400;
+
+ this._entityUUID = this._armorStand.getUniqueId();
+
+ this._disguise = new DisguiseGuardian(this._armorStand);
+ this._disguise.setHideIfNotDisguised(true);
+
+ disguiseManager.disguise(this._disguise, player ->
+ {
+ // Don't let Builder -> Admin see it
+ Rank rank = clientManager.Get(player).GetRank();
+ if (rank.has(Rank.MAPDEV))
+ {
+ if (!rank.has(Rank.ADMIN))
+ {
+ return false;
+ }
+ }
+ if (rank == Rank.EVENT)
+ return false;
+ return true;
+ });
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false)
+ public void onSpawn(EntitySpawnEvent event)
+ {
+ if (event.getEntity() instanceof ArmorStand)
+ {
+ event.setCancelled(false);
+ }
+ }
+
+ @EventHandler
+ public void onLoad(ChunkAddEntityEvent event)
+ {
+ if (event.getEntity().getUniqueId().equals(this._entityUUID))
+ {
+ this._armorStand = (ArmorStand) event.getEntity();
+ this._nmsEntity = ((CraftArmorStand) this._armorStand).getHandle();
+ }
+ }
+
+ @EventHandler
+ public void onStack(StackerEvent event)
+ {
+ if (event.getEntity().getUniqueId().equals(this._entityUUID))
+ {
+ event.setCancelled(true);
+ }
+ }
+
+ public void tick()
+ {
+ if (this._nmsEntity.dead || !this._nmsEntity.valid)
+ {
+ //debug("Skipping because " + this._armorStand.isDead() + " " + this._armorStand.isValid());
+ return;
+ }
+
+ if (this._target == null)
+ {
+ regularTick();
+ }
+ else
+ {
+ this._stalkTime++;
+ targetTick();
+ }
+ //debug("Ticking " + this._armorStand + " " + this._armorStand.isDead() + " " + this._armorStand.getLocation() + " " + this._ticksUntilReset);
+ }
+
+ private void regularTick()
+ {
+ if (this._ticksUntilReset <= 0)
+ {
+ reset();
+ }
+
+ //debug("===== Begin Calculations =====");
+
+
+ //debug("Target: " + this._targetX + " " + this._targetY + " " + this._targetZ);
+ //debug("Start: " + this._armorStand.getLocation());
+ double deltaX = _targetX - _nmsEntity.locX;
+ double deltaY = _targetY - _nmsEntity.locY;
+ double deltaZ = _targetZ - _nmsEntity.locZ;
+
+ //debug("Delta Location: " + deltaX + " " + deltaY + " "+ deltaZ);
+
+ double dx = 0;
+ if (deltaX > 0.1) dx = DELTA_MOVE_PER_TICK;
+ else if (deltaX < -0.1) dx = -DELTA_MOVE_PER_TICK;
+ double dy = 0;
+ if (deltaY > 0.1) dy = DELTA_MOVE_PER_TICK;
+ else if (deltaY < -0.1) dy = -DELTA_MOVE_PER_TICK;
+ double dz = 0;
+ if (deltaZ > 0.1) dz = DELTA_MOVE_PER_TICK;
+ else if (deltaZ < -0.1) dz = -DELTA_MOVE_PER_TICK;
+
+
+ _nmsEntity.locX += dx;
+ _nmsEntity.locY += dy;
+ _nmsEntity.locZ += dz;
+
+ //debug("Dest: " + this._nmsEntity.locX + " " + this._nmsEntity.locY + " " + this._nmsEntity.locZ);
+ //debug("===== End Calculations =====");
+
+ // Only send look update every second
+ if (this._nmsEntity.ticksLived % 20 == 0)
+ {
+ UtilEnt.CreatureLook(_armorStand, _nmsEntity.locX, _nmsEntity.locY, _nmsEntity.locZ, _targetX, _targetY, _targetZ);
+ }
+
+ this._ticksUntilReset--;
+ }
+
+ private void targetTick()
+ {
+ //debug("===== Stalking " + this._target.getName() + " =====");
+ EntityPlayer entityPlayer = ((CraftPlayer) this._target).getHandle();
+
+ Vector direction = this._target.getLocation().getDirection().normalize().multiply(-6);
+
+ this._nmsEntity.locX = entityPlayer.locX + direction.getX();
+ this._nmsEntity.locZ = entityPlayer.locZ + direction.getZ();
+ this._nmsEntity.locY = entityPlayer.locY + 10.0 + nextDouble(-1.0, 1.0);
+
+ UtilEnt.CreatureLook(_armorStand, _nmsEntity.locX, _nmsEntity.locY, _nmsEntity.locZ, entityPlayer.locX, entityPlayer.locY, entityPlayer.locZ);
+ }
+
+ public void reset()
+ {
+ //debug("======= BEGIN RESET ======");
+ final double x = _nmsEntity.locX;
+ final double y = _nmsEntity.locY;
+ final double z = _nmsEntity.locZ;
+
+ double cx = 0, cy = 0, cz = 0;
+ if (x > CENTER_X)
+ cx = (x - CENTER_X) / (MAX_DISTANCE_X - CENTER_X);
+ else if (x < CENTER_X)
+ cx = (CENTER_X - x) / (CENTER_X - MIN_DISTANCE_X);
+ if (y > CENTER_Y)
+ cy = (y - CENTER_Y) / (MAX_DISTANCE_Y - CENTER_Y);
+ else if (y < CENTER_Y)
+ cy = (CENTER_Y - y) / (CENTER_Y - MIN_DISTANCE_Y);
+ if (z > CENTER_Z)
+ cz = (z - CENTER_Z) / (MAX_DISTANCE_Z - CENTER_Z);
+ else if (z < CENTER_Z)
+ cz = (CENTER_Z - z) / (CENTER_Z - MIN_DISTANCE_Z);
+
+ cx = MAGICAL_FUNCTION.apply(cx) * (x > CENTER_X ? -(MAX_DISTANCE_X - CENTER_X) : (CENTER_X - MIN_DISTANCE_X));
+ cy = MAGICAL_FUNCTION.apply(cy) * (y > CENTER_Y ? -(MAX_DISTANCE_Y - CENTER_Y) : (CENTER_Y - MIN_DISTANCE_Y));
+ cz = MAGICAL_FUNCTION.apply(cz) * (z > CENTER_Z ? -(MAX_DISTANCE_Z - CENTER_Z) : (CENTER_Z - MIN_DISTANCE_Z));
+
+ //debug("Start: " + this._armorStand.getLocation());
+ //debug("Changes: " + cx + " " + cy + " " + cz);
+
+ int ex = nextInt(8, 12);
+ int ey = nextInt(0, 3);
+ int ez = nextInt(8, 12);
+
+ if (_random.nextBoolean())
+ ex = -ex;
+ if (_random.nextBoolean())
+ ey = -ey;
+ if (_random.nextBoolean())
+ ez = -ez;
+
+ ex += cx;
+ ey += cy;
+ ez += cz;
+
+ int dx = ex;
+ int dy = ey;
+ int dz = ez;
+
+ //debug("Deltas: " + dx + " " + dy + " " + dz);
+
+ this._targetX = x + dx;
+ this._targetY = y + dy;
+ this._targetZ = z + dz;
+ //debug("End: " + this._targetX + " " + this._targetY + " " + this._targetZ);
+
+
+ // If we can't find a good position, just go to the center
+ if (!locCheck())
+ {
+ this._targetX = CENTER_X;
+ this._targetY = CENTER_Y;
+ this._targetZ = CENTER_Z;
+
+ dx = (int) (CENTER_X - x);
+ dy = (int) (CENTER_Y - y);
+ dz = (int) (CENTER_Z - z);
+ }
+
+ double maxDelta = Math.max(Math.max(Math.abs(dx), Math.abs(dy)), Math.abs(dz));
+
+ this._ticksUntilReset = (int) (maxDelta / DELTA_MOVE_PER_TICK);
+
+ // Send look update for new target
+ UtilEnt.CreatureLook(_armorStand, _nmsEntity.locX, _nmsEntity.locY, _nmsEntity.locZ, _targetX, _targetY, _targetZ);
+
+ //debug("Ticks: " + this._ticksUntilReset);
+ //debug("======= END RESET ======");
+ }
+
+ public void target(Player player)
+ {
+ this._target = player;
+ }
+
+ public boolean isTargeting()
+ {
+ return this._target != null;
+ }
+
+ public int getTargetingTime()
+ {
+ return this._stalkTime;
+ }
+
+ public void stopTargeting()
+ {
+ this._target = null;
+ this._stalkTime = 0;
+ reset();
+ }
+
+ public void shoot(Player player)
+ {
+ this._disguise.setTarget(player == null ? 0 : player.getEntityId());
+ Managers.get(DisguiseManager.class).updateDisguise(this._disguise);
+ }
+
+ public Player getTarget()
+ {
+ return this._target;
+ }
+
+ private boolean locCheck()
+ {
+ if (_targetX >= MAX_DISTANCE_X ||
+ _targetX <= MIN_DISTANCE_X ||
+ _targetY >= MAX_DISTANCE_Y ||
+ _targetY <= MIN_DISTANCE_Y ||
+ _targetZ >= MAX_DISTANCE_Z ||
+ _targetZ <= MIN_DISTANCE_Z)
+ return false;
+ return true;
+ }
+
+ public int nextInt(int lower, int upper)
+ {
+ return _random.nextInt(1 + upper - lower) + lower;
+ }
+
+ public double nextDouble(double lower, double upper)
+ {
+ return lower + (upper - lower) * _random.nextDouble();
+ }
+
+ public void debug(String s)
+ {
+ if (DEBUG) System.out.println(s);
+ }
+
+ public void remove()
+ {
+ this._armorStand.remove();
+ this._target = null;
+ Managers.get(DisguiseManager.class).undisguise(this._disguise);
+ }
+
+ public ArmorStand getEntity()
+ {
+ return this._armorStand;
+ }
+
+ public void moveDelta(double dx, double dy, double dz)
+ {
+ this._nmsEntity.locX += dx;
+ this._nmsEntity.locY += dy;
+ this._nmsEntity.locZ += dz;
+ }
+
+ public void move(double x, double y, double z)
+ {
+ this._nmsEntity.locX = x;
+ this._nmsEntity.locY = y;
+ this._nmsEntity.locZ = z;
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/CheckThresholds.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/CheckThresholds.java
new file mode 100644
index 000000000..b00207db6
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/CheckThresholds.java
@@ -0,0 +1,61 @@
+package mineplex.core.antihack;
+
+import net.minecraft.server.v1_8_R3.ChatComponentText;
+import net.minecraft.server.v1_8_R3.ChatModifier;
+import net.minecraft.server.v1_8_R3.EnumChatFormat;
+import net.minecraft.server.v1_8_R3.IChatBaseComponent;
+
+public class CheckThresholds
+{
+ private final String _friendlyName;
+ private final int _med;
+ private final int _high;
+
+ public CheckThresholds(String friendlyName, int med, int high)
+ {
+ _friendlyName = friendlyName;
+ _med = med;
+ _high = high;
+ }
+
+ public String getFriendlyName()
+ {
+ return _friendlyName;
+ }
+
+ public IChatBaseComponent format(int violationLevel)
+ {
+ EnumChatFormat color = getSeverity(violationLevel)._color;
+ return new ChatComponentText(_friendlyName).setChatModifier(new ChatModifier().setColor(color));
+ }
+
+ public Severity getSeverity(int violationLevel)
+ {
+ if (violationLevel >= _high)
+ {
+ return Severity.HIGH;
+
+ } else if (violationLevel >= _med)
+ {
+ return Severity.MEDIUM;
+
+ } else
+ {
+ return Severity.LOW;
+ }
+ }
+
+ public enum Severity
+ {
+ LOW(EnumChatFormat.GREEN),
+ MEDIUM(EnumChatFormat.GOLD),
+ HIGH(EnumChatFormat.RED),
+ ;
+ private final EnumChatFormat _color;
+
+ Severity(EnumChatFormat color)
+ {
+ _color = color;
+ }
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/MajorViolationCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/MajorViolationCommand.java
new file mode 100644
index 000000000..8ed58a419
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/MajorViolationCommand.java
@@ -0,0 +1,46 @@
+package mineplex.core.antihack;
+
+import mineplex.serverdata.commands.ServerCommand;
+
+public class MajorViolationCommand extends ServerCommand
+{
+ private final String _thisServer;
+ private final String _playerName;
+ private final String _hackType;
+ private final int _violations;
+ private final String _message;
+
+ public MajorViolationCommand(String thisServer, String playerName, String hackType, int violations, String message)
+ {
+ this._thisServer = thisServer;
+ this._playerName = playerName;
+ this._hackType = hackType;
+ this._violations = violations;
+ this._message = message;
+ }
+
+ public String getOriginatingServer()
+ {
+ return _thisServer;
+ }
+
+ public String getPlayerName()
+ {
+ return _playerName;
+ }
+
+ public String getHackType()
+ {
+ return _hackType;
+ }
+
+ public int getViolations()
+ {
+ return _violations;
+ }
+
+ public String getMessage()
+ {
+ return _message;
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/AntiHackAction.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/AntiHackAction.java
new file mode 100644
index 000000000..689f57f7b
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/AntiHackAction.java
@@ -0,0 +1,46 @@
+package mineplex.core.antihack.actions;
+
+import com.mineplex.anticheat.api.PlayerViolationEvent;
+import com.mineplex.anticheat.checks.combat.KillauraTypeA;
+import mineplex.core.common.util.UtilServer;
+import org.bukkit.event.Listener;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public abstract class AntiHackAction implements Listener
+{
+ private static final Map, AntiHackAction> ACTIONS = new HashMap<>();
+ private static final AntiHackAction NOOP_ACTION = new NoopAction();
+
+ private static final Date NEXT_BAN_WAVE = new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5));
+
+ static
+ {
+ ACTIONS.put(KillauraTypeA.class, new ImmediateBanAction(200));
+ }
+
+ private int _vl;
+
+ AntiHackAction(int vl)
+ {
+ this._vl = vl;
+
+ UtilServer.RegisterEvents(this);
+ }
+
+ public abstract void handle(PlayerViolationEvent event);
+
+ public int getMinVl()
+ {
+ return this._vl;
+ }
+
+ public static AntiHackAction getAction(Class> checkClass)
+ {
+ AntiHackAction action = ACTIONS.getOrDefault(checkClass, NOOP_ACTION);
+ return action;
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/BanwaveAction.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/BanwaveAction.java
new file mode 100644
index 000000000..64df22984
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/BanwaveAction.java
@@ -0,0 +1,35 @@
+package mineplex.core.antihack.actions;
+
+import com.mineplex.anticheat.api.PlayerViolationEvent;
+import mineplex.core.Managers;
+import mineplex.core.antihack.banwave.BanWaveManager;
+import mineplex.core.common.util.UtilServer;
+
+import java.util.Date;
+
+class BanwaveAction extends AntiHackAction
+{
+ private Date nextBanWave;
+
+ BanwaveAction(Date nextBanWave, int vl)
+ {
+ super(vl);
+ this.nextBanWave = nextBanWave;
+ }
+
+ @Override
+ public void handle(PlayerViolationEvent event)
+ {
+ if (event.getViolations() >= this.getMinVl())
+ {
+ Managers.get(BanWaveManager.class).insertBanWaveInfo(
+ event.getPlayer(),
+ nextBanWave.getTime(),
+ event.getCheckClass(),
+ event.getMessage(),
+ event.getViolations(),
+ UtilServer.getServerNameFromConfig()
+ );
+ }
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/ImmediateBanAction.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/ImmediateBanAction.java
new file mode 100644
index 000000000..668d82389
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/ImmediateBanAction.java
@@ -0,0 +1,28 @@
+package mineplex.core.antihack.actions;
+
+import com.mineplex.anticheat.api.PlayerViolationEvent;
+import mineplex.core.Managers;
+import mineplex.core.antihack.AntiHack;
+import mineplex.core.common.util.UtilServer;
+
+class ImmediateBanAction extends AntiHackAction
+{
+ ImmediateBanAction(int vl)
+ {
+ super(vl);
+ }
+
+ @Override
+ public void handle(PlayerViolationEvent event)
+ {
+ if (event.getViolations() >= this.getMinVl())
+ {
+ String server = UtilServer.getServerName();
+ if (server.contains("-"))
+ {
+ server = server.substring(0, server.indexOf('-'));
+ }
+ Managers.get(AntiHack.class).doBan(event.getPlayer(), "[GWEN] Hacking - " + AntiHack.CHECKS.get(event.getHackType()).getFriendlyName() + " [" + server + "]");
+ }
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/MixedAction.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/MixedAction.java
new file mode 100644
index 000000000..14066a4d7
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/MixedAction.java
@@ -0,0 +1,49 @@
+package mineplex.core.antihack.actions;
+
+import com.mineplex.anticheat.api.PlayerViolationEvent;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+public class MixedAction extends AntiHackAction
+{
+ private List _actions = new ArrayList<>();
+ private Map> _punished = new HashMap<>();
+
+ public MixedAction(AntiHackAction firstAction, AntiHackAction... actions)
+ {
+ super(firstAction.getMinVl());
+ this._actions.add(firstAction);
+ this._actions.addAll(Arrays.asList(actions));
+ }
+
+
+ @Override
+ public void handle(PlayerViolationEvent event)
+ {
+ for (int i = this._actions.size() - 1; i >= 0; i--)
+ {
+ AntiHackAction action = this._actions.get(i);
+ if (action.getMinVl() <= event.getViolations())
+ {
+ if (_punished.computeIfAbsent(event.getPlayer().getUniqueId(), key -> new HashSet<>()).add(action))
+ {
+ action.handle(event);
+ }
+ break;
+ }
+ }
+ }
+
+ public int getMinVl()
+ {
+ return this._actions.get(0).getMinVl();
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/NoopAction.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/NoopAction.java
new file mode 100644
index 000000000..38794c630
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/NoopAction.java
@@ -0,0 +1,17 @@
+package mineplex.core.antihack.actions;
+
+import com.mineplex.anticheat.api.PlayerViolationEvent;
+
+public class NoopAction extends AntiHackAction
+{
+ NoopAction()
+ {
+ super(Integer.MAX_VALUE);
+ }
+
+ @Override
+ public void handle(PlayerViolationEvent event)
+ {
+
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveInfo.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveInfo.java
new file mode 100644
index 000000000..c73b544a6
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveInfo.java
@@ -0,0 +1,157 @@
+package mineplex.core.antihack.banwave;
+
+public class BanWaveInfo
+{
+ /**
+ * The unique id for this BanWaveInfo
+ */
+ private int _id;
+
+ /**
+ * The account id for this BanWaveInfo
+ */
+ private int _accountId;
+
+ /**
+ * The time in milliseconds at which to ban this user
+ */
+ private long _timeToBan;
+
+ /**
+ * Whether this BanWaveInfo has been executed
+ */
+ private boolean _banned;
+
+ /**
+ * The hack type
+ */
+ private String _hackType;
+
+ /**
+ * The ban message
+ */
+ private String _message;
+
+ /**
+ * The violation level
+ */
+ private int _vl;
+
+ /**
+ * The server on which the user was flagged
+ */
+ private String _server;
+
+ public int getId()
+ {
+ return _id;
+ }
+
+ public void setId(int id)
+ {
+ _id = id;
+ }
+
+ public int getAccountId()
+ {
+ return _accountId;
+ }
+
+ public void setAccountId(int accountId)
+ {
+ _accountId = accountId;
+ }
+
+ public long getTimeToBan()
+ {
+ return _timeToBan;
+ }
+
+ public void setTimeToBan(long timeToBan)
+ {
+ _timeToBan = timeToBan;
+ }
+
+ public boolean isBanned()
+ {
+ return _banned;
+ }
+
+ public void setBanned(boolean banned)
+ {
+ _banned = banned;
+ }
+
+ public String getHackType()
+ {
+ return _hackType;
+ }
+
+ public void setHackType(String hackType)
+ {
+ _hackType = hackType;
+ }
+
+ public String getMessage()
+ {
+ return _message;
+ }
+
+ public void setMessage(String message)
+ {
+ _message = message;
+ }
+
+ public int getVl()
+ {
+ return _vl;
+ }
+
+ public void setVl(int vl)
+ {
+ _vl = vl;
+ }
+
+ public String getServer()
+ {
+ return _server;
+ }
+
+ public void setServer(String server)
+ {
+ _server = server;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ BanWaveInfo that = (BanWaveInfo) o;
+
+ if (_id != that._id) return false;
+ if (_accountId != that._accountId) return false;
+ if (_timeToBan != that._timeToBan) return false;
+ if (_banned != that._banned) return false;
+ if (_vl != that._vl) return false;
+ if (_hackType != null ? !_hackType.equals(that._hackType) : that._hackType != null) return false;
+ if (_message != null ? !_message.equals(that._message) : that._message != null) return false;
+ return _server != null ? _server.equals(that._server) : that._server == null;
+
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = _id;
+ result = 31 * result + _accountId;
+ result = 31 * result + (int) (_timeToBan ^ (_timeToBan >>> 32));
+ result = 31 * result + (_banned ? 1 : 0);
+ result = 31 * result + (_hackType != null ? _hackType.hashCode() : 0);
+ result = 31 * result + (_message != null ? _message.hashCode() : 0);
+ result = 31 * result + _vl;
+ result = 31 * result + (_server != null ? _server.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java
new file mode 100644
index 000000000..8b39d9ac0
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java
@@ -0,0 +1,75 @@
+package mineplex.core.antihack.banwave;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.ReflectivelyCreateMiniPlugin;
+import mineplex.core.account.CoreClient;
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.antihack.AntiHack;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.player.PlayerJoinEvent;
+
+import java.util.List;
+
+@ReflectivelyCreateMiniPlugin
+public class BanWaveManager extends MiniPlugin
+{
+ private final BanWaveRepository _repository = new BanWaveRepository();
+
+ private BanWaveManager()
+ {
+ super("BanWaveManager");
+ }
+
+ @EventHandler
+ public void onJoin(PlayerJoinEvent event)
+ {
+ runAsync(() ->
+ {
+ CoreClient client = require(CoreClientManager.class).Get(event.getPlayer());
+
+ List infos = _repository.getBanWaveInfo(client.getAccountId());
+
+ long now = System.currentTimeMillis();
+
+ boolean banned = false;
+ for (BanWaveInfo info : infos)
+ {
+ if (info.getTimeToBan() < now && !info.isBanned())
+ {
+ banned = true;
+ require(AntiHack.class).doBanWave(event.getPlayer(), info.getMessage());
+ break;
+ }
+ }
+
+ if (banned)
+ {
+ for (BanWaveInfo info : infos)
+ {
+ _repository.flagDone(info);
+ }
+ }
+ });
+ }
+
+ public void insertBanWaveInfo(Player player, long timeToBan, Class> checkClass, String message, int vl, String server)
+ {
+ insertBanWaveInfo(player, timeToBan, checkClass, message, vl, server, null);
+ }
+
+ public void insertBanWaveInfo(Player player, long timeToBan, Class> checkClass, String message, int vl, String server, Runnable after)
+ {
+ runAsync(() ->
+ {
+ CoreClient client = require(CoreClientManager.class).Get(player);
+
+ this._repository.insertBanWaveInfo(client.getAccountId(), timeToBan, checkClass.getName(), message, vl, server);
+
+ if (after != null)
+ {
+ after.run();
+ }
+ });
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java
new file mode 100644
index 000000000..7b8650d35
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java
@@ -0,0 +1,90 @@
+package mineplex.core.antihack.banwave;
+
+import mineplex.core.common.util.UtilServer;
+import mineplex.core.database.MinecraftRepository;
+import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.column.ColumnInt;
+import mineplex.serverdata.database.column.ColumnLong;
+import mineplex.serverdata.database.column.ColumnVarChar;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BanWaveRepository extends MinecraftRepository
+{
+ private static final String TABLE_NAME = "banwave";
+
+ private static final String INITIALIZE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
+ "id INT AUTO_INCREMENT, " +
+ "accountId INT NOT NULL, " +
+ "timeToBan BIGINT UNSIGNED NOT NULL, " +
+ "banned TINYINT DEFAULT '0', " +
+ "hacktype VARCHAR(64), " +
+ "message VARCHAR(255), " +
+ "vl INT, " +
+ "server VARCHAR(32), " +
+ "PRIMARY KEY (id), " +
+ "INDEX (accountId))";
+ private static final String QUERY_BY_ACCOUNT = "SELECT * FROM " + TABLE_NAME + " WHERE accountId = ?";
+ private static final String INSERT_INTO_TABLE = "INSERT INTO " + TABLE_NAME + " (accountId, timeToBan, hacktype, message, vl, server) VALUES (?, ?, ?, ?, ?, ?)";
+ private static final String FLAG_DONE = "UPDATE " + TABLE_NAME + " SET banned = 1 WHERE id = ?";
+
+ BanWaveRepository()
+ {
+ super(UtilServer.getPlugin(), DBPool.getAccount());
+ }
+
+ @Override
+ protected void initialize()
+ {
+ executeUpdate(INITIALIZE_TABLE);
+ }
+
+ @Override
+ protected void update()
+ {
+
+ }
+
+ List getBanWaveInfo(int accountId)
+ {
+ List banWaveInfo = new ArrayList<>();
+
+ executeQuery(QUERY_BY_ACCOUNT, resultSet ->
+ {
+ while (resultSet.next())
+ {
+ BanWaveInfo info = new BanWaveInfo();
+ info.setId(resultSet.getInt(1));
+ info.setAccountId(resultSet.getInt(2));
+ info.setTimeToBan(resultSet.getLong(3));
+ info.setBanned(resultSet.getInt(4) == 1);
+ info.setHackType(resultSet.getString(5));
+ info.setMessage(resultSet.getString(6));
+ info.setVl(resultSet.getInt(7));
+ info.setServer(resultSet.getString(8));
+
+ banWaveInfo.add(info);
+ }
+ }, new ColumnInt("accountId", accountId));
+
+ return banWaveInfo;
+ }
+
+ void insertBanWaveInfo(int accountId, long timeToBan, String hackType, String message, int vl, String server)
+ {
+ executeInsert(INSERT_INTO_TABLE, null,
+ new ColumnInt("accountId", accountId),
+ new ColumnLong("timeToBan", timeToBan),
+ new ColumnVarChar("hacktype", 64, hackType),
+ new ColumnVarChar("message", 255, message),
+ new ColumnInt("vl", vl),
+ new ColumnVarChar("server", 32, server)
+ );
+ }
+
+ void flagDone(BanWaveInfo info)
+ {
+ executeUpdate(FLAG_DONE, new ColumnInt("id", info.getId()));
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antispam/AntiSpamManager.java b/Plugins/Mineplex.Core/src/mineplex/core/antispam/AntiSpamManager.java
new file mode 100644
index 000000000..ce8ce600b
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antispam/AntiSpamManager.java
@@ -0,0 +1,54 @@
+package mineplex.core.antispam;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.antispam.repository.AntiSpamRepository;
+import mineplex.core.status.ServerStatusManager;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.player.AsyncPlayerChatEvent;
+
+/**
+ * @author Shaun Bennett
+ */
+public class AntiSpamManager extends MiniPlugin
+{
+ private final String _pluginName;
+ private final String _serverName;
+ private final String _region;
+ private final AntiSpamRepository _repository;
+
+ public AntiSpamManager()
+ {
+ super("AntiSpam");
+
+ _pluginName = getPlugin().getClass().getSimpleName();
+ _repository = new AntiSpamRepository();
+
+ ServerStatusManager serverStatusManager = require(ServerStatusManager.class);
+ if (serverStatusManager != null)
+ {
+ _serverName = serverStatusManager.getCurrentServerName();
+ _region = serverStatusManager.getRegion().name();
+ }
+ else
+ {
+ _serverName = "Unknown";
+ _region = "Unknown";
+ }
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void onChat(AsyncPlayerChatEvent event)
+ {
+ // Only listen to async events, as non async events are fake messages
+ if (event.isAsynchronous())
+ {
+ Player player = event.getPlayer();
+ String message = event.getMessage();
+ ChatPayload payload = new ChatPayload(player.getName(), player.getUniqueId().toString(), _region, _serverName, message, System.currentTimeMillis());
+ // Run our API call async to the chat message (prevents blocking chat message)
+ runAsync(() -> _repository.logMessage(_pluginName, payload));
+ }
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antispam/ChatPayload.java b/Plugins/Mineplex.Core/src/mineplex/core/antispam/ChatPayload.java
new file mode 100644
index 000000000..bec9550c0
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antispam/ChatPayload.java
@@ -0,0 +1,126 @@
+package mineplex.core.antispam;
+
+/**
+ * @author Shaun Bennett
+ */
+public class ChatPayload
+{
+ private String _playerName;
+ private String _uuid;
+ private String _region;
+ private String _server;
+ private String _message;
+ private long _time;
+
+ public ChatPayload(String playerName, String uuid, String region, String server, String message, long time)
+ {
+ _playerName = playerName;
+ _uuid = uuid;
+ _region = region;
+ _server = server;
+ _message = message;
+ _time = time;
+ }
+
+ public String getPlayerName()
+ {
+ return _playerName;
+ }
+
+ public void setPlayerName(String playerName)
+ {
+ _playerName = playerName;
+ }
+
+ public String getUuid()
+ {
+ return _uuid;
+ }
+
+ public void setUuid(String uuid)
+ {
+ _uuid = uuid;
+ }
+
+ public String getMessage()
+ {
+ return _message;
+ }
+
+ public void setMessage(String message)
+ {
+ _message = message;
+ }
+
+ public String getServer()
+ {
+ return _server;
+ }
+
+ public void setServer(String server)
+ {
+ _server = server;
+ }
+
+ public long getTime()
+ {
+ return _time;
+ }
+
+ public void setTime(long time)
+ {
+ _time = time;
+ }
+
+ public String getRegion()
+ {
+ return _region;
+ }
+
+ public void setRegion(String region)
+ {
+ _region = region;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ChatPayload payload = (ChatPayload) o;
+
+ if (_time != payload._time) return false;
+ if (!_playerName.equals(payload._playerName)) return false;
+ if (!_uuid.equals(payload._uuid)) return false;
+ if (!_region.equals(payload._region)) return false;
+ if (!_server.equals(payload._server)) return false;
+ return _message.equals(payload._message);
+
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = _playerName.hashCode();
+ result = 31 * result + _uuid.hashCode();
+ result = 31 * result + _region.hashCode();
+ result = 31 * result + _server.hashCode();
+ result = 31 * result + _message.hashCode();
+ result = 31 * result + (int) (_time ^ (_time >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "ChatPayload{" +
+ "_playerName='" + _playerName + '\'' +
+ ", _uuid='" + _uuid + '\'' +
+ ", _region='" + _region + '\'' +
+ ", _server='" + _server + '\'' +
+ ", _message='" + _message + '\'' +
+ ", _time=" + _time +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antispam/repository/AntiSpamRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/antispam/repository/AntiSpamRepository.java
new file mode 100644
index 000000000..42e9ddf15
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antispam/repository/AntiSpamRepository.java
@@ -0,0 +1,26 @@
+package mineplex.core.antispam.repository;
+
+import com.google.gson.Gson;
+import mineplex.core.antispam.ChatPayload;
+import mineplex.core.common.api.ApiEndpoint;
+import mineplex.core.common.api.ApiHost;
+import mineplex.core.common.api.ApiResponse;
+import mineplex.core.thread.ThreadPool;
+
+import java.util.Random;
+
+/**
+ * @author Shaun Bennett
+ */
+public class AntiSpamRepository extends ApiEndpoint
+{
+ public AntiSpamRepository()
+ {
+ super(ApiHost.ANTISPAM, "/chat");
+ }
+
+ public ApiResponse logMessage(String source, ChatPayload payload)
+ {
+ return getWebCall().post("/" + source, ApiResponse.class, payload);
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManager.java b/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManager.java
index 804ba1931..c0768500e 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManager.java
@@ -4,6 +4,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
import mineplex.core.MiniDbClientPlugin;
import mineplex.core.account.CoreClientManager;
@@ -67,15 +68,15 @@ public class BenefitManager extends MiniDbClientPlugin
}
@Override
- protected BenefitData addPlayer(String player)
+ protected BenefitData addPlayer(UUID uuid)
{
return new BenefitData();
}
@Override
- public void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException
+ public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
{
- Set(playerName, _repository.retrievePlayerBenefitData(resultSet));
+ Set(uuid, _repository.retrievePlayerBenefitData(resultSet));
}
@Override
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestore.java b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestore.java
index cbffb8a05..bea07b8e5 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestore.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestore.java
@@ -160,7 +160,13 @@ public class BlockRestore extends MiniPlugin
public void add(Block block, int toID, byte toData, int fromID, byte fromData, long expireTime, boolean restoreOnBreak)
{
if (!contains(block)) getBlocks().put(block, new BlockRestoreData(block, toID, toData, fromID, fromData, expireTime, 0, restoreOnBreak));
- else getData(block).update(toID, toData, expireTime);
+ else
+ {
+ if (getData(block) != null)
+ {
+ getData(block).update(toID, toData, expireTime);
+ }
+ }
}
public void snow(Block block, byte heightAdd, byte heightMax, long expireTime, long meltDelay, int heightJumps)
@@ -168,7 +174,8 @@ public class BlockRestore extends MiniPlugin
//Fill Above
if (((block.getTypeId() == 78 && block.getData() >= (byte)7) || block.getTypeId() == 80) && getData(block) != null)
{
- getData(block).update(78, heightAdd, expireTime, meltDelay);
+ if (getData(block) != null)
+ getData(block).update(78, heightAdd, expireTime, meltDelay);
if (heightJumps > 0) snow(block.getRelative(BlockFace.UP), heightAdd, heightMax, expireTime, meltDelay, heightJumps - 1);
if (heightJumps == -1) snow(block.getRelative(BlockFace.UP), heightAdd, heightMax, expireTime, meltDelay, -1);
@@ -213,8 +220,11 @@ public class BlockRestore extends MiniPlugin
//Snow
if (!contains(block))
getBlocks().put(block, new BlockRestoreData(block, 78, (byte) Math.max(0, heightAdd - 1), block.getTypeId(), block.getData(), expireTime, meltDelay, false));
- else
- getData(block).update(78, heightAdd, expireTime, meltDelay);
+ else
+ {
+ if (getData(block) != null)
+ getData(block).update(78, heightAdd, expireTime, meltDelay);
+ }
}
public boolean contains(Block block)
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java
index 9a22c4358..534362923 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java
@@ -6,6 +6,7 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
+import org.bukkit.block.BlockState;
public class BlockRestoreData
{
@@ -23,6 +24,8 @@ public class BlockRestoreData
protected long _meltDelay = 0;
protected long _meltLast = 0;
+ protected BlockState _fromState;
+
protected HashMap _pad = new HashMap();
protected boolean _restoreOnBreak;
@@ -30,6 +33,7 @@ public class BlockRestoreData
public BlockRestoreData(Block block, int toID, byte toData, int fromID, byte fromData, long expireDelay, long meltDelay, boolean restoreOnBreak)
{
_block = block;
+ _fromState = block.getState();
_fromID = fromID;
_fromData = fromData;
@@ -163,6 +167,8 @@ public class BlockRestoreData
public void restore()
{
_block.setTypeIdAndData(_fromID, _fromData, true);
+ _fromState.update();
+
handleLilypad(true);
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreMap.java b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreMap.java
index fb123e315..37ac4bb86 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreMap.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreMap.java
@@ -41,9 +41,14 @@ public class BlockRestoreMap
public void addBlockData(BlockData blockData)
{
Block block = blockData.Block;
-
- if (!_blocks[block.getY()].containsKey(block))
- _blocks[block.getY()].put(block, blockData);
+
+ if (block.getY() > 0 && block.getY() < _blocks.length)
+ {
+ if (!_blocks[block.getY()].containsKey(block))
+ {
+ _blocks[block.getY()].put(block, blockData);
+ }
+ }
_changedBlocks.add(blockData.Block);
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java
index f31e9ce0a..9d373e031 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java
@@ -14,7 +14,6 @@ import mineplex.core.bonuses.gui.BonusGui;
import mineplex.core.bonuses.gui.SpinGui;
import mineplex.core.bonuses.redis.VoteHandler;
import mineplex.core.bonuses.redis.VotifierCommand;
-import mineplex.core.boosters.BoosterManager;
import mineplex.core.common.Rank;
import mineplex.core.common.util.*;
import mineplex.core.common.util.UtilParticle.ParticleType;
@@ -35,6 +34,7 @@ import mineplex.core.recharge.Recharge;
import mineplex.core.reward.RewardManager;
import mineplex.core.stats.StatsManager;
import mineplex.core.status.ServerStatusManager;
+import mineplex.core.thank.ThankManager;
import mineplex.core.treasure.TreasureType;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@@ -123,7 +123,7 @@ public class BonusManager extends MiniClientPlugin implements I
private StatsManager _statsManager;
private FacebookManager _facebookManager;
private YoutubeManager _youtubeManager;
- private BoosterManager _boosterManager;
+ private ThankManager _thankManager;
public boolean _enabled;
private Npc _carlNpc;
private AnimationCarl _animation;
@@ -162,7 +162,7 @@ public class BonusManager extends MiniClientPlugin implements I
updateOffSet();
}
- public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, ServerStatusManager statusManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, StatsManager statsManager, InventoryManager inventoryManager, PetManager petManager, FacebookManager facebookManager, YoutubeManager youtubeManager, GadgetManager gadgetManager, BoosterManager boosterManager)
+ public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, ServerStatusManager statusManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, StatsManager statsManager, InventoryManager inventoryManager, PetManager petManager, FacebookManager facebookManager, YoutubeManager youtubeManager, GadgetManager gadgetManager, ThankManager thankManager)
{
super("Bonus", plugin);
_repository = new BonusRepository(plugin, this, donationManager);
@@ -171,7 +171,7 @@ public class BonusManager extends MiniClientPlugin implements I
_npcManager = npcManager;
_hologramManager = hologramManager;
_inventoryManager = inventoryManager;
- _boosterManager = boosterManager;
+ _thankManager = thankManager;
_rewardManager = new RewardManager(_clientManager, _donationManager, _inventoryManager, petManager, statsManager, gadgetManager);
@@ -825,7 +825,7 @@ public class BonusManager extends MiniClientPlugin implements I
if (entity.equals(_carlNpc.getEntity()))
{
updateDailyStreak(event.getPlayer());
- new BonusGui(_plugin, event.getPlayer(), this, _rewardManager, _facebookManager, _youtubeManager, _boosterManager).openInventory();
+ new BonusGui(_plugin, event.getPlayer(), this, _rewardManager, _facebookManager, _youtubeManager, _thankManager).openInventory();
}
}
@@ -841,7 +841,7 @@ public class BonusManager extends MiniClientPlugin implements I
if (event.getEntity().equals(_carlNpc.getEntity()))
{
updateDailyStreak(player);
- new BonusGui(_plugin, player, this, _rewardManager, _facebookManager, _youtubeManager, _boosterManager).openInventory();
+ new BonusGui(_plugin, player, this, _rewardManager, _facebookManager, _youtubeManager, _thankManager).openInventory();
}
}
}
@@ -908,7 +908,7 @@ public class BonusManager extends MiniClientPlugin implements I
if (canDaily(player)) availableRewards++;
if (getPollManager().getNextPoll(_pollManager.Get(player), _clientManager.Get(player).GetRank()) != null) availableRewards++;
if (!_facebookManager.hasRedeemed(player)) availableRewards++;
- if (_boosterManager.getTipManager().Get(player).getTips() > 0) availableRewards++;
+ if (_thankManager.Get(player).getThankToClaim() > 0) availableRewards++;
Hologram hologram;
@@ -987,7 +987,7 @@ public class BonusManager extends MiniClientPlugin implements I
}
@Override
- protected BonusClientData addPlayer(String player)
+ protected BonusClientData addPlayer(UUID uuid)
{
return new BonusClientData();
}
@@ -1011,7 +1011,7 @@ public class BonusManager extends MiniClientPlugin implements I
@EventHandler
public void UnloadPlayer(final ClientUnloadEvent event)
{
- final BonusClientData clientData = Get(event.GetName());
+ final BonusClientData clientData = Get(event.getUniqueId());
if (clientData.getHologram() != null)
clientData.getHologram().stop();
@@ -1183,9 +1183,9 @@ public class BonusManager extends MiniClientPlugin implements I
}
@Override
- public void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException
+ public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
{
- Set(playerName, _repository.loadData(accountId, resultSet));
+ Set(uuid, _repository.loadData(accountId, resultSet));
}
@Override
@@ -1194,8 +1194,9 @@ public class BonusManager extends MiniClientPlugin implements I
return "SELECT * FROM bonus WHERE accountId = '" + accountId + "';";
}
- public BoosterManager getBoosterManager()
+ public ThankManager getThankManager()
{
- return _boosterManager;
+ return _thankManager;
}
+
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java
index 649f964e3..7ed6615fd 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java
@@ -1,6 +1,5 @@
package mineplex.core.bonuses.commands;
-import mineplex.core.boosters.BoosterManager;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
@@ -18,7 +17,7 @@ public class GuiCommand extends CommandBase
@Override
public void Execute(Player caller, String[] args)
{
- new BonusGui(Plugin.getPlugin(), caller, Plugin, Plugin.getRewardManager(), Plugin.getFacebookManager(), Plugin.getYoutubeManager(), Plugin.getBoosterManager()).openInventory();
+ new BonusGui(Plugin.getPlugin(), caller, Plugin, Plugin.getRewardManager(), Plugin.getFacebookManager(), Plugin.getYoutubeManager(), Plugin.getThankManager()).openInventory();
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java
index a8fef8c82..d5beff79e 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java
@@ -2,10 +2,10 @@ package mineplex.core.bonuses.gui;
import mineplex.core.bonuses.BonusManager;
import mineplex.core.bonuses.gui.buttons.*;
-import mineplex.core.boosters.BoosterManager;
import mineplex.core.facebook.FacebookManager;
import mineplex.core.gui.SimpleGui;
import mineplex.core.reward.RewardManager;
+import mineplex.core.thank.ThankManager;
import mineplex.core.youtube.YoutubeManager;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
@@ -15,7 +15,7 @@ public class BonusGui extends SimpleGui
private BonusManager manager;
- public BonusGui(Plugin plugin, Player player, BonusManager manager, RewardManager rewardManager, FacebookManager facebookManager, YoutubeManager youtubeManager, BoosterManager boosterManager)
+ public BonusGui(Plugin plugin, Player player, BonusManager manager, RewardManager rewardManager, FacebookManager facebookManager, YoutubeManager youtubeManager, ThankManager thankManager)
{
super(plugin, player, player.getName() + "'s Bonuses", 5 * 9);
@@ -35,7 +35,7 @@ public class BonusGui extends SimpleGui
setItem(23, new TwitterButton(player));
- setItem(25, new ClaimTipsButton(getPlugin(), player, this, manager, boosterManager));
+ setItem(25, new ClaimTipsButton(getPlugin(), player, this, manager, thankManager));
setItem(31, new CarlSpinButton(getPlugin(), player, manager, rewardManager));
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/ClaimTipsButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/ClaimTipsButton.java
index a0d53216e..9121b1bda 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/ClaimTipsButton.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/ClaimTipsButton.java
@@ -1,41 +1,28 @@
package mineplex.core.bonuses.gui.buttons;
-import java.util.ArrayList;
-
-import mineplex.core.boosters.BoosterManager;
-import mineplex.core.common.CurrencyType;
+import mineplex.core.bonuses.BonusManager;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
-import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
-import mineplex.core.common.util.UtilTime;
-import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.gui.GuiItem;
import mineplex.core.gui.ItemRefresher;
import mineplex.core.gui.pages.LoadingWindow;
import mineplex.core.gui.pages.TimedMessageWindow;
import mineplex.core.itemstack.ItemStackFactory;
+import mineplex.core.recharge.Recharge;
import mineplex.core.shop.item.ShopItem;
-import mineplex.core.updater.UpdateType;
-import mineplex.core.updater.event.UpdateEvent;
-import mineplex.core.bonuses.BonusAmount;
-import mineplex.core.bonuses.BonusClientData;
-import mineplex.core.bonuses.BonusManager;
-import mineplex.core.bonuses.StreakRecord;
-
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.DyeColor;
-import org.bukkit.Material;
-import org.bukkit.Sound;
+import mineplex.core.thank.ThankManager;
+import org.bukkit.*;
import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
+import java.util.ArrayList;
+
public class ClaimTipsButton implements GuiItem, Listener
{
private ItemStack _item;
@@ -45,12 +32,12 @@ public class ClaimTipsButton implements GuiItem, Listener
private ItemRefresher _gui;
private BonusManager _bonusManager;
- private BoosterManager _boosterManager;
+ private ThankManager _thankManager;
- public ClaimTipsButton(Plugin plugin, Player player, ItemRefresher gui, BonusManager bonusManager, BoosterManager boosterManager)
+ public ClaimTipsButton(Plugin plugin, Player player, ItemRefresher gui, BonusManager bonusManager, ThankManager thankManager)
{
_bonusManager = bonusManager;
- _boosterManager = boosterManager;
+ _thankManager = thankManager;
_player = player;
_plugin = plugin;
_gui = gui;
@@ -72,12 +59,17 @@ public class ClaimTipsButton implements GuiItem, Listener
@Override
public void click(ClickType clickType)
{
+ if (!Recharge.Instance.use(_player, "Claim Tips Button", 1000, false, false))
+ {
+ return;
+ }
+
if (isAvailable()) {
_item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing...");
refreshItem();
new LoadingWindow(getPlugin(), getPlayer(), 6*9);
- _boosterManager.getTipManager().claimTips(getPlayer(), claimed -> {
- if (claimed > 0)
+ _thankManager.claimThanks(getPlayer(), claimThankResult -> {
+ if (claimThankResult != null && claimThankResult.getClaimed() > 0)
{
// Woo, success!
setItem();
@@ -87,17 +79,17 @@ public class ClaimTipsButton implements GuiItem, Listener
new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.LIME.getData(), 1, ChatColor.GREEN + "Amplifier Thanks Collected"), "Thanks Collected", 6*9, 20*3, getGui()).openInventory();
}
- UtilPlayer.message(getPlayer(), F.main("Carl", "You collected " + F.currency(CurrencyType.TREASURE_SHARD, claimed) + " from Amplifiers!"));
+ UtilPlayer.message(getPlayer(), F.main("Carl", "You collected " + F.currency(GlobalCurrency.TREASURE_SHARD, claimThankResult.getClaimed()) + " from " + F.elem(claimThankResult.getUniqueThanks()) + " players!"));
// Pending explosions are strange.. Not sure why we are using strings. Either way, lets display a rank reward effect
_bonusManager.addPendingExplosion(getPlayer(), "RANK");
getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f);
}
- else if (claimed == 0)
+ else if (claimThankResult != null && claimThankResult.getClaimed() == 0)
{
// No tips to claim
if (getPlayer().getOpenInventory() != null)
{
- new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.RED.getData(), 1, ChatColor.RED + "No Thanks to Claim!"), "You have no thanks to claim!", 6*9, 20*3, getGui()).openInventory();
+ new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.RED.getData(), 1, ChatColor.RED + "No Thanks to Claim!"), "You have no thank to claim!", 6*9, 20*3, getGui()).openInventory();
}
UtilPlayer.message(getPlayer(), F.main("Carl", "You have no rewards to claim!"));
@@ -133,7 +125,7 @@ public class ClaimTipsButton implements GuiItem, Listener
if (isAvailable())
{
material = Material.EMERALD;
- itemName = C.cGreen + C.Bold + "Game Amplifiers";
+ itemName = C.cGreen + C.Bold + "Thank Rewards";
lore.add(" ");
lore.add(C.cYellow + "Your Rewards");
lore.add(" " + C.cWhite + getTips() + " Treasure Shards");
@@ -143,10 +135,11 @@ public class ClaimTipsButton implements GuiItem, Listener
else
{
material = Material.REDSTONE_BLOCK;
- itemName = C.cRed + C.Bold + "Game Amplifiers";
+ itemName = C.cRed + C.Bold + "Thank Rewards";
lore.add(" ");
- lore.add(C.cGray + "Use Amplifiers to earn rewards");
+ lore.add(C.cGray + "Earn Thank Rewards from players using /thank");
+ lore.add(C.cGray + "on you, or by enabling Game Amplifiers.");
lore.add(" ");
lore.add(C.cWhite + "Get Amplifiers at " + C.cGreen + "mineplex.com/shop");
}
@@ -167,7 +160,7 @@ public class ClaimTipsButton implements GuiItem, Listener
private int getTips()
{
- return _boosterManager.getTipManager().Get(getPlayer()).getTips();
+ return _thankManager.Get(_player).getThankToClaim();
}
private boolean isAvailable()
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java
index ebc150b6c..f46ceca73 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java
@@ -13,6 +13,7 @@ import mineplex.core.gui.ItemRefresher;
import mineplex.core.gui.pages.LoadingWindow;
import mineplex.core.gui.pages.TimedMessageWindow;
import mineplex.core.itemstack.ItemStackFactory;
+import mineplex.core.recharge.Recharge;
import mineplex.core.shop.item.ShopItem;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@@ -69,6 +70,11 @@ public class DailyBonusButton implements GuiItem, Listener
@Override
public void click(ClickType clickType)
{
+ if (!Recharge.Instance.use(_player, "Carl Daily Bonus", 1000, false, false))
+ {
+ return;
+ }
+
if (isAvailable()) {
_item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing...");
refreshItem();
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java
index dfb707a05..29054f2a6 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java
@@ -17,6 +17,7 @@ import mineplex.core.gui.pages.TimedMessageWindow;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.poll.Poll;
import mineplex.core.poll.PollManager;
+import mineplex.core.recharge.Recharge;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -109,6 +110,11 @@ public class PollButton extends SimpleGui implements GuiItem {
@Override
public void click(ClickType clickType)
{
+ if (!Recharge.Instance.use(getPlayer(), "Poll Main Button", 1000, false, false))
+ {
+ return;
+ }
+
if (_poll == null)
{
getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 1.6f);
@@ -195,6 +201,11 @@ public class PollButton extends SimpleGui implements GuiItem {
@Override
public void click(ClickType clickType)
{
+ if (!Recharge.Instance.use(getPlayer(), "Poll Answer Button", 1000, false, false))
+ {
+ return;
+ }
+
_create = true;
_pollManager.answerPoll(getPlayer(), _poll, num + 1);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java
index 1f525f36b..31541dc59 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java
@@ -13,6 +13,7 @@ import mineplex.core.gui.ItemRefresher;
import mineplex.core.gui.pages.LoadingWindow;
import mineplex.core.gui.pages.TimedMessageWindow;
import mineplex.core.itemstack.ItemStackFactory;
+import mineplex.core.recharge.Recharge;
import mineplex.core.shop.item.ShopItem;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@@ -78,6 +79,11 @@ public class RankBonusButton implements GuiItem, Listener {
@Override
public void click(ClickType clickType)
{
+ if (!Recharge.Instance.use(_player, "Claim Rank Bonus", 1000, false, false))
+ {
+ return;
+ }
+
if (isAvailable() && _bonusManager.isPastAugust()) {
_item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing...");
refreshItem();
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/YoutubeButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/YoutubeButton.java
index dd741b450..4a7b1b10e 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/YoutubeButton.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/YoutubeButton.java
@@ -5,6 +5,7 @@ import mineplex.core.common.jsonchat.JsonMessage;
import mineplex.core.common.util.C;
import mineplex.core.gui.GuiItem;
import mineplex.core.itemstack.ItemBuilder;
+import mineplex.core.recharge.Recharge;
import mineplex.core.youtube.YoutubeManager;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -59,6 +60,11 @@ public class YoutubeButton implements GuiItem
@Override
public void click(ClickType clickType)
{
+ if (!Recharge.Instance.use(_player, "Use Youtube Button", 1000, false, false))
+ {
+ return;
+ }
+
_player.closeInventory();
final String message;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterManager.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterManager.java
index 4254f6594..eec3e3c22 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterManager.java
@@ -1,6 +1,5 @@
package mineplex.core.boosters;
-import com.mojang.authlib.properties.PropertyMap;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.boosters.command.BoosterCommand;
@@ -10,7 +9,7 @@ import mineplex.core.boosters.event.BoosterItemGiveEvent;
import mineplex.core.boosters.event.BoosterUpdateEvent;
import mineplex.core.boosters.gui.BoosterShop;
import mineplex.core.boosters.redis.BoosterUpdateRepository;
-import mineplex.core.boosters.tips.BoosterTipManager;
+import mineplex.core.boosters.tips.BoosterThankManager;
import mineplex.core.common.util.C;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UtilGear;
@@ -19,12 +18,12 @@ import mineplex.core.common.util.UtilServer;
import mineplex.core.donation.DonationManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.itemstack.ItemStackFactory;
+import mineplex.core.thank.ThankManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
-import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
@@ -64,8 +63,8 @@ public class BoosterManager extends MiniPlugin
private CoreClientManager _clientManager;
private DonationManager _donationManager;
private InventoryManager _inventoryManager;
+ private BoosterThankManager _boosterThankManager;
- private BoosterTipManager _tipManager;
private BoosterShop _shop;
private String _boosterGroup;
@@ -74,7 +73,7 @@ public class BoosterManager extends MiniPlugin
private long _cacheLastUpdated;
private Map> _boosterCache = new HashMap<>();
- public BoosterManager(JavaPlugin plugin, String boosterGroup, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager)
+ public BoosterManager(JavaPlugin plugin, String boosterGroup, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, ThankManager thankManager)
{
super("Booster Manager", plugin);
@@ -84,7 +83,7 @@ public class BoosterManager extends MiniPlugin
_donationManager = donationManager;
_inventoryManager = inventoryManager;
- _tipManager = new BoosterTipManager(plugin, clientManager, donationManager);
+ _boosterThankManager = new BoosterThankManager(plugin, clientManager, thankManager);
_shop = new BoosterShop(this, clientManager, donationManager);
try
@@ -335,9 +334,9 @@ public class BoosterManager extends MiniPlugin
handleBoosterUpdate(event.getBoosterMap());
}
- public BoosterTipManager getTipManager()
+ public BoosterThankManager getBoosterThankManager()
{
- return _tipManager;
+ return _boosterThankManager;
}
/**
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterProcessor.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterProcessor.java
index 0cc567715..23ae2e6eb 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterProcessor.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterProcessor.java
@@ -6,6 +6,7 @@ import mineplex.core.common.util.UtilTime;
import mineplex.core.shop.confirmation.ConfirmationCallback;
import mineplex.core.shop.confirmation.ConfirmationProcessor;
import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
/**
* @author Shaun Bennett
@@ -21,6 +22,9 @@ public class BoosterProcessor implements ConfirmationProcessor
_player = player;
}
+ @Override
+ public void init(Inventory inventory) {}
+
@Override
public void process(ConfirmationCallback callback)
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterRepository.java
index a057c4071..25e8c2c64 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/BoosterRepository.java
@@ -7,6 +7,7 @@ import com.google.gson.JsonObject;
import com.mojang.authlib.properties.PropertyMap;
import mineplex.core.common.api.ApiEndpoint;
import mineplex.core.common.api.ApiFieldNamingStrategy;
+import mineplex.core.common.api.ApiHost;
import mineplex.core.common.api.ApiResponse;
import java.util.Arrays;
@@ -23,7 +24,7 @@ public class BoosterRepository extends ApiEndpoint
{
public BoosterRepository()
{
- super("/booster", new GsonBuilder().setFieldNamingStrategy(new ApiFieldNamingStrategy())
+ super(ApiHost.AMPLIFIERS, "/booster", new GsonBuilder().setFieldNamingStrategy(new ApiFieldNamingStrategy())
// .registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer())
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").create());
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/command/BoosterCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/command/BoosterCommand.java
index 216130e12..44a429ac6 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/boosters/command/BoosterCommand.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/command/BoosterCommand.java
@@ -15,11 +15,12 @@ public class BoosterCommand extends MultiCommandBase
{
public BoosterCommand(BoosterManager plugin)
{
- super(plugin, Rank.DEVELOPER, "amplifier", "booster");
+ super(plugin, Rank.ALL, "amplifier", "booster");
AddCommand(new AddCommand(plugin));
AddCommand(new GuiCommand(plugin));
AddCommand(new ReloadCommand(plugin));
+ AddCommand(new ThankCommand(plugin));
}
@Override
@@ -27,5 +28,6 @@ public class BoosterCommand extends MultiCommandBase
{
UtilPlayer.message(caller, F.help("amplifier add ", "Add an amplifier to that group", Rank.DEVELOPER));
UtilPlayer.message(caller, F.help("amplifier gui", "Open Amplifier GUI", Rank.DEVELOPER));
+ UtilPlayer.message(caller, F.help("amplifier thank ", "Thank an Amplifier for a specific Booster Group", Rank.ALL));
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/command/ThankCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/command/ThankCommand.java
new file mode 100644
index 000000000..b6a379fc0
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/command/ThankCommand.java
@@ -0,0 +1,74 @@
+package mineplex.core.boosters.command;
+
+import mineplex.core.boosters.Booster;
+import mineplex.core.boosters.BoosterManager;
+import mineplex.core.boosters.tips.BoosterThankManager;
+import mineplex.core.boosters.tips.TipAddResult;
+import mineplex.core.command.CommandBase;
+import mineplex.core.common.Rank;
+import mineplex.core.common.currency.GlobalCurrency;
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilPlayer;
+import org.apache.commons.lang3.StringUtils;
+import org.bukkit.Sound;
+import org.bukkit.entity.Player;
+
+/**
+ * @author Shaun Bennett
+ */
+public class ThankCommand extends CommandBase
+{
+ public ThankCommand(BoosterManager plugin)
+ {
+ super(plugin, Rank.ALL, "thank");
+ }
+
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ if (args == null || args.length == 0)
+ {
+ // try to thank the current amplifier group
+ String boosterGroup = Plugin.getBoosterGroup();
+ if (boosterGroup == null || boosterGroup.length() <= 0)
+ {
+ UtilPlayer.message(caller, F.main("Amplifier", "You must specify an Amplifier Group"));
+ return;
+ }
+
+ attemptToTipGroup(caller, boosterGroup);
+ }
+ else
+ {
+ String boosterGroup = StringUtils.join(args, ' ');
+ attemptToTipGroup(caller, boosterGroup);
+ }
+ }
+
+ private void attemptToTipGroup(Player caller, String boosterGroup)
+ {
+ Booster booster = Plugin.getActiveBooster(boosterGroup);
+ if (booster == null)
+ {
+ // Give a friendly oops message
+ UtilPlayer.message(caller, F.main("Amplifier", "There was an error handling your request. Try again later"));
+ return;
+ }
+ else
+ {
+ Plugin.getBoosterThankManager().addTip(caller, booster, result ->
+ {
+ if (result == TipAddResult.SUCCESS)
+ {
+ UtilPlayer.message(caller, F.main("Tip", "You thanked " + F.name(booster.getPlayerName()) + ". They earned " + F.currency(GlobalCurrency.TREASURE_SHARD, BoosterThankManager.TIP_FOR_SPONSOR) + " and you got "
+ + F.currency(GlobalCurrency.TREASURE_SHARD, BoosterThankManager.TIP_FOR_TIPPER)) + " in return!");
+ caller.playSound(caller.getLocation(), Sound.LEVEL_UP, 1f, 1f);
+ }
+ else if (result.getFriendlyMessage() != null)
+ {
+ UtilPlayer.message(caller, F.main("Amplifier", result.getFriendlyMessage()));
+ }
+ });
+ }
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/gui/BoosterPage.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/gui/BoosterPage.java
index 3a6315ec9..9e4ae655f 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/boosters/gui/BoosterPage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/gui/BoosterPage.java
@@ -4,7 +4,6 @@ import mineplex.core.account.CoreClientManager;
import mineplex.core.boosters.Booster;
import mineplex.core.boosters.BoosterManager;
import mineplex.core.boosters.BoosterProcessor;
-import mineplex.core.common.Pair;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilTime;
import mineplex.core.donation.DonationManager;
@@ -115,8 +114,7 @@ public class BoosterPage extends ShopPageBase
ShopItem booster = new ShopItem(Material.SUGAR, "Game Amplifier", lore.toArray(new String[0]), 0, false, false);
BoosterProcessor processor = new BoosterProcessor(getPlugin(), getPlayer());
- ConfirmationPage page = new ConfirmationPage<>(getPlugin(), getShop(),
- getClientManager(), getDonationManager(), getPlayer(), this, processor, booster);
+ ConfirmationPage page = new ConfirmationPage<>(getPlayer(), this, processor, booster);
getShop().openPageForPlayer(getPlayer(), page);
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankManager.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankManager.java
new file mode 100644
index 000000000..c3ae99372
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankManager.java
@@ -0,0 +1,93 @@
+package mineplex.core.boosters.tips;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.boosters.Booster;
+import mineplex.core.common.util.Callback;
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.recharge.Recharge;
+import mineplex.core.thank.ThankManager;
+import mineplex.core.thank.ThankResult;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+
+/**
+ * This class handles "thanking" Amplifiers. This is a way of rewarding players for activating Amplifiers.
+ *
+ * @author Shaun Bennett
+ */
+public class BoosterThankManager extends MiniPlugin
+{
+ public static final int TIP_FOR_SPONSOR = 5;
+ public static final int TIP_FOR_TIPPER = 5;
+
+ private BoosterThankRepository _repository;
+ private CoreClientManager _clientManager;
+ private ThankManager _thankManager;
+
+ public BoosterThankManager(JavaPlugin plugin, CoreClientManager clientManager, ThankManager thankManager)
+ {
+ super("Amplifier Thanks", plugin);
+
+ _clientManager = clientManager;
+ _repository = new BoosterThankRepository(plugin);
+ _thankManager = thankManager;
+ }
+
+ /**
+ * Attempt to "Thank" an Amplifier. This checks with {@link BoosterThankRepository} if a player hasn't already
+ * thanked that Amplifier. If they havent, we proceed to use {@link ThankManager} to send a thank you to the player
+ * who activated that Amplifier.
+ *
+ * @param player The player sending the thanks
+ * @param booster The Amplifier to be thanked
+ * @param callback Callback with the result of sending the thanks
+ */
+ public void addTip(Player player, Booster booster, Callback callback)
+ {
+ if (!Recharge.Instance.use(player, "Amplifier Thanks", 1000 * 5, false, false))
+ {
+ UtilPlayer.message(player, F.main("Amplifier", "Please wait before trying that again"));
+ callback.run(TipAddResult.ON_COOLDOWN);
+ return;
+ }
+
+ int accountId = _clientManager.getAccountId(player);
+
+ // Break out if client manager has a bad account id
+ if (accountId == -1)
+ {
+ callback.run(TipAddResult.INVALID_ACCOUNT_ID);
+ return;
+ }
+
+ // You can't tip yourself, silly!
+ if (accountId == booster.getAccountId())
+ {
+ callback.run(TipAddResult.CANNOT_TIP_SELF);
+ return;
+ }
+
+ runAsync(() ->
+ {
+ if (_repository.checkAmplifierThank(accountId, booster.getId()))
+ {
+ // We can thank that amplifier!
+ _thankManager.thankPlayer(booster.getPlayerName(), booster.getAccountId(), player.getName(), accountId,
+ TIP_FOR_SPONSOR, TIP_FOR_TIPPER, "Amplifier", true, thankResult ->
+ runSync(() -> callback.run(fromThankResult(thankResult))));
+ }
+ else
+ {
+ runSync(() -> callback.run(TipAddResult.ALREADY_TIPPED_BOOSTER));
+ }
+ });
+ }
+
+
+ private TipAddResult fromThankResult(ThankResult result)
+ {
+ return result == ThankResult.SUCCESS ? TipAddResult.SUCCESS : TipAddResult.UNKNOWN_ERROR;
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankRepository.java
new file mode 100644
index 000000000..8fd26265e
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterThankRepository.java
@@ -0,0 +1,52 @@
+package mineplex.core.boosters.tips;
+
+import mineplex.core.database.MinecraftRepository;
+import mineplex.database.routines.AddTip;
+import mineplex.database.routines.CheckAmplifierThank;
+import mineplex.database.routines.ClaimTips;
+import mineplex.serverdata.database.DBPool;
+import mineplex.serverdata.database.RepositoryBase;
+import mineplex.serverdata.database.column.ColumnInt;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+
+/**
+ * @author Shaun Bennett
+ */
+public class BoosterThankRepository extends MinecraftRepository
+{
+ public BoosterThankRepository(JavaPlugin plugin)
+ {
+ super(plugin, DBPool.getAccount());
+ }
+
+ /**
+ * Checks the database if an accountId is allowed to thank a specific Amplifier.
+ * This will return true and update the database if the thank is okay, or false
+ * if that account ID has already thanked that Amplifier ID.
+ *
+ * @param accountId Account ID of the player trying to thank the Amplifier
+ * @param amplifierId The ID of the Amplifier the player is trying to thank
+ * @return True if the account id can thank the amplifier id, false otherwise
+ */
+ public boolean checkAmplifierThank(int accountId, int amplifierId)
+ {
+ CheckAmplifierThank checkAmplifierThank = new CheckAmplifierThank();
+ checkAmplifierThank.setInAccountId(accountId);
+ checkAmplifierThank.setInAmplifierId(amplifierId);
+ checkAmplifierThank.execute(jooq().configuration());
+ return checkAmplifierThank.getCanThank() == 1;
+ }
+
+ @Override
+ protected void initialize()
+ {
+
+ }
+
+ @Override
+ protected void update()
+ {
+
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterTipManager.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterTipManager.java
deleted file mode 100644
index be7f28ca9..000000000
--- a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterTipManager.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package mineplex.core.boosters.tips;
-
-import mineplex.core.MiniDbClientPlugin;
-import mineplex.core.account.CoreClientManager;
-import mineplex.core.boosters.Booster;
-import mineplex.core.common.util.Callback;
-import mineplex.core.donation.DonationManager;
-import mineplex.core.recharge.Recharge;
-import org.bukkit.entity.Player;
-import org.bukkit.plugin.java.JavaPlugin;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * @author Shaun Bennett
- */
-public class BoosterTipManager extends MiniDbClientPlugin
-{
- public static final int TIP_FOR_SPONSOR = 5;
- public static final int TIP_FOR_TIPPER = 5;
-
- private BoosterTipRepository _repository;
- private DonationManager _donationManager;
-
- public BoosterTipManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager)
- {
- super("Amplifier Thanks", plugin, clientManager);
-
- _donationManager = donationManager;
- _repository = new BoosterTipRepository(plugin);
- }
-
- public void addTip(Player player, Booster booster, Callback callback)
- {
- if (!Recharge.Instance.use(player, "Amplifier Thanks", 1000 * 60 * 10, true, false))
- {
- callback.run(TipAddResult.ON_COOLDOWN);
- return;
- }
-
- int accountId = ClientManager.getAccountId(player);
-
- // Break out if client manager has a bad account id
- if (accountId == -1)
- {
- callback.run(TipAddResult.INVALID_ACCOUNT_ID);
- return;
- }
-
- // You can't tip yourself, silly!
- if (accountId == booster.getAccountId())
- {
- callback.run(TipAddResult.CANNOT_TIP_SELF);
- return;
- }
-
- runAsync(() -> {
- TipAddResult result;
- if (_repository.addTip(accountId, booster.getAccountId(), booster.getId(), TIP_FOR_SPONSOR))
- {
- _donationManager.rewardCoinsUntilSuccess(null, "Tips", player.getName(), accountId, TIP_FOR_TIPPER);
- result = TipAddResult.SUCCESS;
- }
- else
- result = TipAddResult.ALREADY_TIPPED_BOOSTER;
-
- runSync(() -> callback.run(result));
- });
- }
-
- /**
- * Claim all tips for a player and add those tips to their account (Treasure Shards)
- * This will call a database routine that handles the tip process.
- *
- * The callback will return -1 on a failed attempt or 0 if there was no tips to claim
- * @param player The player with tips to claim
- * @param callback Callback returning the amount of tips claimed
- */
- public void claimTips(Player player, Callback callback)
- {
- String playerName = player.getName();
- int accountId = ClientManager.getAccountId(player);
-
- if (accountId == -1)
- {
- // uh oh, invalid account id!
- if (callback != null) callback.run(-1);
- }
-
- runAsync(() -> {
- int tips = _repository.claimTips(accountId);
- runSync(() -> {
- if (tips > 0)
- {
- _donationManager.rewardCoinsUntilSuccess(null, "Tips", playerName, accountId, tips);
- }
-
- // Reset tips back to 0
- if (Get(player) != null) Get(player).setTips(0);
- if (callback != null) callback.run(tips);
- });
- });
- }
-
- @Override
- public String getQuery(int accountId, String uuid, String name)
- {
- return "SELECT tips FROM Account.accountTip WHERE accountTip.accountId = " + accountId + ";";
- }
-
- @Override
- protected PlayerTipData addPlayer(String player)
- {
- return new PlayerTipData();
- }
-
- @Override
- public void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException
- {
- PlayerTipData data = new PlayerTipData();
-
- while (resultSet.next())
- {
- data.setTips(resultSet.getInt(1));
- }
-
- Set(playerName, data);
- }
-}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterTipRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterTipRepository.java
deleted file mode 100644
index 6ece1a5b2..000000000
--- a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/BoosterTipRepository.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package mineplex.core.boosters.tips;
-
-import mineplex.core.database.MinecraftRepository;
-import mineplex.database.routines.AddTip;
-import mineplex.database.routines.ClaimTips;
-import mineplex.serverdata.database.DBPool;
-import mineplex.serverdata.database.RepositoryBase;
-import mineplex.serverdata.database.column.ColumnInt;
-import org.bukkit.entity.Player;
-import org.bukkit.plugin.java.JavaPlugin;
-
-/**
- * @author Shaun Bennett
- */
-public class BoosterTipRepository extends MinecraftRepository
-{
- public static String LOG_TIP = "INSERT INTO Account.accountTipLogs (accountId, boosterId) VALUES (?, ?)";
- public static String ADD_TIP = "INSERT INTO Account.accountTip (accountId, tips) VALUES (?, ?) ON DUPLICATE KEY UPDATE tips = tips + ?";
-
- public BoosterTipRepository(JavaPlugin plugin)
- {
- super(plugin, DBPool.getAccount());
- }
-
- public boolean addTip(int tipperId, int receiverId, int boosterId, int tipAmount)
- {
- AddTip addTip = new AddTip();
- addTip.setTipperAccountId(tipperId);
- addTip.setBoosterAccountId(receiverId);
- addTip.setBoosterId(boosterId);
- addTip.setTipAmount(tipAmount);
- addTip.execute(jooq().configuration());
- return addTip.getSuccess() == 1;
- }
-
- public int claimTips(int accountId)
- {
- ClaimTips claimTips = new ClaimTips();
- claimTips.setAccountId_in(accountId);
- claimTips.execute(jooq().configuration());
- return claimTips.getTipsClaimed();
- }
-
- @Override
- protected void initialize()
- {
-
- }
-
- @Override
- protected void update()
- {
-
- }
-}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/TipAddResult.java b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/TipAddResult.java
index 965a8e738..aa657b6e2 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/TipAddResult.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/boosters/tips/TipAddResult.java
@@ -7,6 +7,7 @@ public enum TipAddResult
{
ALREADY_TIPPED_BOOSTER("You have already thanked this Amplifier!"),
INVALID_ACCOUNT_ID("Uh oh, something went wrong. Try relogging"),
+ UNKNOWN_ERROR("An error occurred. Try again later"),
CANNOT_TIP_SELF("You can't thank yourself, silly!"),
ON_COOLDOWN(null),
SUCCESS(null);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/Fountain.java b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/Fountain.java
index 471bfe8e2..2bf237c43 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/Fountain.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/Fountain.java
@@ -12,19 +12,13 @@ import mineplex.core.donation.DonationManager;
import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
import mineplex.core.stats.StatsManager;
-import mineplex.core.thread.ThreadPool;
-import mineplex.core.updater.UpdateType;
-import mineplex.core.updater.event.UpdateEvent;
import mineplex.serverdata.Region;
import mineplex.serverdata.redis.counter.GoalCounter;
import mineplex.serverdata.redis.counter.GoalCounterListener;
import mineplex.serverdata.servers.ConnectionData;
import org.bukkit.Bukkit;
import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
import java.io.File;
import java.io.IOException;
@@ -63,7 +57,7 @@ public class Fountain implements GoalCounterListener
_name = name;
_dataKey = dataKey;
_location = location;
- _hologram = new Hologram(hologramManager, location.clone().add(4, 3, -3), name).start();
+ _hologram = new Hologram(hologramManager, new Location(location.getWorld(), -23, 75, 3), name).start();
_counter = new GoalCounter(writeConnection, readConnection, region, dataKey, goal);
_counter.addListener(this);
_brawlActive = false;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/FountainManager.java b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/FountainManager.java
index d141e1997..8fb7009fe 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/FountainManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/FountainManager.java
@@ -3,17 +3,13 @@ package mineplex.core.brawl.fountain;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.command.FountainCommand;
-import mineplex.core.brawl.fountain.gui.FountainShop;
import mineplex.core.common.util.C;
-import mineplex.core.common.util.UtilServer;
-import mineplex.core.common.util.UtilWorld;
import mineplex.core.donation.DonationManager;
import mineplex.core.hologram.HologramManager;
import mineplex.core.stats.StatsManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.serverdata.Region;
-import mineplex.serverdata.redis.counter.Counter;
import mineplex.serverdata.servers.ConnectionData;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -22,12 +18,9 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
-import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.plugin.java.JavaPlugin;
-import java.io.File;
-
/**
* @author Shaun Bennett
*/
@@ -55,7 +48,7 @@ public class FountainManager extends MiniPlugin
int goal = 70000000;//!new File("eu.dat").exists() ? 200000000 : 20000000;
_gemFountain = new Fountain(new ConnectionData("10.3.203.80", 6379, ConnectionData.ConnectionType.MASTER, "USRedis"),
new ConnectionData("10.3.203.80", 6377, ConnectionData.ConnectionType.SLAVE, "USRedis"), Region.ALL,
- new Location(world, -32.5, 72, -23.5), new Location(world, -43.5, 67, -38.5),
+ new Location(world, -25.5, 73, 19.5), new Location(world, -35.5, 69, 1.5),
C.cGreen + "Gem Fountain", "GemFountain_01", goal, this, clientManager, donationManager, _hologramManager, _statsManager);
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/GemFountainSalesPackage.java b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/GemFountainSalesPackage.java
index 6018772f0..d0ba3e882 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/GemFountainSalesPackage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/GemFountainSalesPackage.java
@@ -1,9 +1,8 @@
package mineplex.core.brawl.fountain;
-import mineplex.core.common.CurrencyType;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.shop.item.SalesPackageBase;
import org.bukkit.Material;
-import org.bukkit.entity.Player;
/**
* @author Shaun Bennett
@@ -14,14 +13,8 @@ public class GemFountainSalesPackage extends SalesPackageBase
{
super("Add " + gems + " Gems", Material.EMERALD, (byte) 0, new String[] {}, gems, 1);
- CurrencyCostMap.put(CurrencyType.GEM, gems);
+ CurrencyCostMap.put(GlobalCurrency.GEM, gems);
KnownPackage = false;
OneTimePurchaseOnly = false;
}
-
- @Override
- public void sold(Player player, CurrencyType currencyType)
- {
-
- }
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/command/AddCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/command/AddCommand.java
index cd1bf65a5..8e108093c 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/command/AddCommand.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/command/AddCommand.java
@@ -2,8 +2,8 @@ package mineplex.core.brawl.fountain.command;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.command.CommandBase;
-import mineplex.core.common.CurrencyType;
import mineplex.core.common.Rank;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
@@ -53,7 +53,7 @@ public class AddCommand extends CommandBase
UtilPlayer.message(caller, F.main("Fountain", "There was an error processing your request!"));
}
}
- }, caller, "GemFountain.Add", CurrencyType.GEM, amount, false);
+ }, caller, "GemFountain.Add", GlobalCurrency.GEM, amount, false);
}
catch (NumberFormatException ex)
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/gui/FountainPage.java b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/gui/FountainPage.java
index 61d5d8427..dc3fb9c64 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/gui/FountainPage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/gui/FountainPage.java
@@ -4,8 +4,8 @@ import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.Fountain;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.brawl.fountain.gui.button.FountainAddButton;
-import mineplex.core.common.CurrencyType;
import mineplex.core.common.MaterialData;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.shop.item.ShopItem;
@@ -77,7 +77,7 @@ public class FountainPage extends ShopPageBase
if (canAdd)
{
- int playerGems = getDonationManager().Get(getPlayer()).GetGems();
+ int playerGems = getDonationManager().Get(getPlayer()).getBalance(GlobalCurrency.GEM);
ShopItem add1 = new ShopItem(Material.EMERALD, "Add 100 Gems", new String[]{}, 1, playerGems < 100, false);
ShopItem add2 = new ShopItem(Material.EMERALD, "Add 1,000 Gems", new String[]{}, 64, playerGems < 1000, false);
ShopItem add3 = new ShopItem(Material.EMERALD_BLOCK, "Add 10,000 Gems", new String[]{}, 1, playerGems < 10000, false);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/gui/button/FountainAddButton.java b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/gui/button/FountainAddButton.java
index c37c8c551..3dcc6ebd7 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/gui/button/FountainAddButton.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/brawl/fountain/gui/button/FountainAddButton.java
@@ -1,13 +1,12 @@
package mineplex.core.brawl.fountain.gui.button;
-import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.brawl.fountain.GemFountainSalesPackage;
import mineplex.core.brawl.fountain.gui.FountainPage;
-import mineplex.core.brawl.fountain.gui.FountainShop;
-import mineplex.core.common.CurrencyType;
+import mineplex.core.common.currency.GlobalCurrency;
+import mineplex.core.shop.confirmation.ConfirmationPage;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.SalesPackageBase;
-import mineplex.core.shop.page.ConfirmationPage;
+import mineplex.core.shop.item.SalesPackageProcessor;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@@ -30,13 +29,10 @@ public class FountainAddButton implements IButton
@Override
public void onClick(Player player, ClickType clickType)
{
- _page.getShop().openPageForPlayer(player, new ConfirmationPage(_page.getPlugin(), _page.getShop(), _page.getClientManager(), _page.getDonationManager(), new Runnable()
+ _page.getShop().openPageForPlayer(player, new ConfirmationPage<>(player, _page, new SalesPackageProcessor(player, GlobalCurrency.GEM, _salesPackage, _page.getDonationManager(), () ->
{
- public void run()
- {
- _page.getPlugin().getGemFountain().increment(player, _gems, null);
- _page.refresh();
- }
- }, _page, _salesPackage, CurrencyType.GEM, player));
+ _page.getPlugin().getGemFountain().increment(player, _gems, null);
+ _page.refresh();
+ }), _salesPackage.buildIcon()));
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java
index effa0f484..c1857b7dc 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java
@@ -1,40 +1,5 @@
package mineplex.core.chat;
-import java.io.BufferedReader;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.UUID;
-import java.util.function.Function;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.commons.lang3.Validate;
-import org.bukkit.block.Sign;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.EventPriority;
-import org.bukkit.event.block.SignChangeEvent;
-import org.bukkit.event.player.AsyncPlayerChatEvent;
-import org.bukkit.event.player.PlayerCommandPreprocessEvent;
-import org.bukkit.event.player.PlayerQuitEvent;
-import org.bukkit.plugin.java.JavaPlugin;
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.json.simple.JSONValue;
-
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.achievement.AchievementManager;
@@ -49,10 +14,44 @@ import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilText;
import mineplex.core.common.util.UtilTime;
import mineplex.core.incognito.IncognitoManager;
+import mineplex.core.preferences.Preference;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
+import org.apache.commons.lang3.Validate;
+import org.bukkit.block.Sign;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.block.SignChangeEvent;
+import org.bukkit.event.player.AsyncPlayerChatEvent;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+import java.util.function.Function;
public class Chat extends MiniPlugin
{
@@ -69,7 +68,6 @@ public class Chat extends MiniPlugin
private int _chatSlow = 0;
private long _silenced = 0;
- private boolean _threeSecondDelay = true;
private List> _highPriorityFilters = new ArrayList<>();
private List> _lowPriorityFilters = new ArrayList<>();
@@ -213,7 +211,7 @@ public class Chat extends MiniPlugin
{
for (Iterator playerIterator = event.getRecipients().iterator(); playerIterator.hasNext();)
{
- if (!_preferences.Get(playerIterator.next()).ShowChat)
+ if (!_preferences.get(playerIterator.next()).isActive(Preference.SHOW_CHAT))
playerIterator.remove();
}
}
@@ -349,15 +347,6 @@ public class Chat extends MiniPlugin
event.setCancelled(true);
return;
}
- else if (_threeSecondDelay &&
- _clientManager.Get(sender).GetRank() == Rank.ALL &&
- _achievements.getMineplexLevelNumber(sender, Rank.ALL) < 25 &&
- !Recharge.Instance.use(sender, "All Chat Message", 3000, false, false))
- {
- UtilPlayer.message(sender, C.cYellow + "You can only chat once every 3 seconds to prevent spam.");
- UtilPlayer.message(sender, C.cYellow + "Buy a Rank at " + C.cGreen + "www.mineplex.com/shop" + C.cYellow + " to remove this limit!");
- event.setCancelled(true);
- }
else if (!_clientManager.Get(sender).GetRank().has(Rank.MODERATOR) &&
!Recharge.Instance.use(sender, "Chat Message", 400, false, false))
{
@@ -645,11 +634,6 @@ public class Chat extends MiniPlugin
_playerLastMessage.remove(event.getPlayer().getUniqueId());
}
- public void setThreeSecondDelay(boolean b)
- {
- _threeSecondDelay = b;
- }
-
/**
* If the function returns Boolean.TRUE then the message will be CANCELLED.
*/
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/CosmeticShop.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/CosmeticShop.java
index 271dbe895..94ec614e7 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/CosmeticShop.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/CosmeticShop.java
@@ -1,25 +1,23 @@
package mineplex.core.cosmetic.ui;
-import mineplex.core.cosmetic.ui.page.*;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.plugin.messaging.PluginMessageListener;
-
import mineplex.core.account.CoreClientManager;
-import mineplex.core.common.CurrencyType;
import mineplex.core.cosmetic.CosmeticManager;
+import mineplex.core.cosmetic.ui.page.GadgetPage;
+import mineplex.core.cosmetic.ui.page.Menu;
+import mineplex.core.cosmetic.ui.page.PetTagPage;
import mineplex.core.donation.DonationManager;
import mineplex.core.gadget.event.ItemGadgetOutOfAmmoEvent;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
-import mineplex.core.updater.UpdateType;
-import mineplex.core.updater.event.UpdateEvent;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.plugin.messaging.PluginMessageListener;
public class CosmeticShop extends ShopBase implements PluginMessageListener
{
public CosmeticShop(CosmeticManager plugin, CoreClientManager clientManager, DonationManager donationManager, String name)
{
- super(plugin, clientManager, donationManager, name, CurrencyType.GEM, CurrencyType.TREASURE_SHARD);
+ super(plugin, clientManager, donationManager, name);
plugin.getPlugin().getServer().getMessenger().registerIncomingPluginChannel(plugin.getPlugin(), "MC|ItemName", this);
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/MountButton.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/MountButton.java
index c41b9915a..3d1039572 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/MountButton.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/button/MountButton.java
@@ -1,15 +1,13 @@
package mineplex.core.cosmetic.ui.button;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
-
-import mineplex.core.shop.item.IButton;
-import mineplex.core.shop.page.ConfirmationPage;
-import mineplex.core.common.CurrencyType;
-import mineplex.core.cosmetic.CosmeticManager;
-import mineplex.core.cosmetic.ui.CosmeticShop;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.cosmetic.ui.page.MountPage;
import mineplex.core.mount.Mount;
+import mineplex.core.shop.confirmation.ConfirmationPage;
+import mineplex.core.shop.item.IButton;
+import mineplex.core.shop.item.SalesPackageProcessor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.ClickType;
public class MountButton implements IButton
{
@@ -25,13 +23,10 @@ public class MountButton implements IButton
@Override
public void onClick(final Player player, ClickType clickType)
{
- _page.getShop().openPageForPlayer(player, new ConfirmationPage(_page.getPlugin(), _page.getShop(), _page.getClientManager(), _page.getDonationManager(), new Runnable()
+ _page.getShop().openPageForPlayer(player, new ConfirmationPage<>(player, _page, new SalesPackageProcessor(player, GlobalCurrency.TREASURE_SHARD, _mount, _page.getDonationManager(), () ->
{
- public void run()
- {
- _page.getPlugin().getInventoryManager().addItemToInventory(null, player, _mount.getName(), 1);
- _page.refresh();
- }
- }, _page, _mount, CurrencyType.TREASURE_SHARD, player));
+ _page.getPlugin().getInventoryManager().addItemToInventory(null, player, _mount.getName(), 1);
+ _page.refresh();
+ }), _mount.buildIcon()));
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/CostumePage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/CostumePage.java
index 525594815..218390e2c 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/CostumePage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/CostumePage.java
@@ -1,12 +1,7 @@
package mineplex.core.cosmetic.ui.page;
-import org.bukkit.Material;
-import org.bukkit.Sound;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
-
import mineplex.core.account.CoreClientManager;
-import mineplex.core.common.CurrencyType;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.cosmetic.ui.CosmeticShop;
@@ -19,6 +14,10 @@ import mineplex.core.gadget.types.ItemGadget;
import mineplex.core.gadget.types.OutfitGadget;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.ShopItem;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.ClickType;
/**
* Created by shaun on 14-09-15.
@@ -38,7 +37,7 @@ public class CostumePage extends GadgetPage
for (Gadget gadget : getPlugin().getGadgetManager().getGadgets(GadgetType.COSTUME))
{
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -1)
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -1)
continue;
OutfitGadget outfitGadget = ((OutfitGadget) gadget);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java
index b56d4cf8e..a5c62b29c 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java
@@ -1,12 +1,29 @@
package mineplex.core.cosmetic.ui.page;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.common.currency.GlobalCurrency;
+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 mineplex.core.common.util.banner.CountryFlag;
+import mineplex.core.cosmetic.CosmeticManager;
+import mineplex.core.cosmetic.ui.CosmeticShop;
+import mineplex.core.cosmetic.ui.button.GadgetButton;
+import mineplex.core.cosmetic.ui.button.activate.ActivateGadgetButton;
+import mineplex.core.cosmetic.ui.button.deactivate.DeactivateGadgetButton;
+import mineplex.core.donation.DonationManager;
import mineplex.core.gadget.event.GadgetChangeEvent;
+import mineplex.core.gadget.gadgets.morph.MorphBlock;
+import mineplex.core.gadget.types.Gadget;
+import mineplex.core.gadget.types.GadgetType;
+import mineplex.core.gadget.types.HatGadget;
+import mineplex.core.gadget.types.ItemGadget;
+import mineplex.core.shop.confirmation.ConfirmationPage;
+import mineplex.core.shop.item.IButton;
+import mineplex.core.shop.item.SalesPackageProcessor;
+import mineplex.core.shop.item.ShopItem;
+import mineplex.core.shop.page.ShopPageBase;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@@ -14,26 +31,9 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BannerMeta;
import org.bukkit.inventory.meta.ItemMeta;
-import mineplex.core.account.CoreClientManager;
-import mineplex.core.common.CurrencyType;
-import mineplex.core.common.util.C;
-import mineplex.core.common.util.F;
-import mineplex.core.common.util.UtilPlayer;
-import mineplex.core.cosmetic.CosmeticManager;
-import mineplex.core.cosmetic.ui.CosmeticShop;
-import mineplex.core.cosmetic.ui.button.activate.ActivateGadgetButton;
-import mineplex.core.cosmetic.ui.button.deactivate.DeactivateGadgetButton;
-import mineplex.core.cosmetic.ui.button.GadgetButton;
-import mineplex.core.donation.DonationManager;
-import mineplex.core.gadget.gadgets.morph.MorphBlock;
-import mineplex.core.gadget.types.Gadget;
-import mineplex.core.gadget.types.GadgetType;
-import mineplex.core.gadget.types.HatGadget;
-import mineplex.core.gadget.types.ItemGadget;
-import mineplex.core.shop.item.IButton;
-import mineplex.core.shop.item.ShopItem;
-import mineplex.core.shop.page.ConfirmationPage;
-import mineplex.core.shop.page.ShopPageBase;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
public class GadgetPage extends ShopPageBase
{
@@ -50,7 +50,7 @@ public class GadgetPage extends ShopPageBase
for (Gadget gadget : getPlugin().getGadgetManager().getGadgets(GadgetType.ITEM))
{
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -3)
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -3)
continue;
addGadget(gadget, slot);
@@ -105,64 +105,64 @@ public class GadgetPage extends ShopPageBase
if (!gadget.ownsGadget(getPlayer()))
{
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -1)
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -1)
{
//Nothing
}
//Chest Unlocks
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -2 || gadget.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -2 || gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Treasure Chests");
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -3)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -3)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Winter Holiday Treasure");
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -4)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -4)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Halloween Pumpkin Treasure");
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -5)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -5)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Easter Holiday Treasure");
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -6)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -6)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Valentines Gifts");
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -7)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -7)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Purchased from shop.mineplex.com");
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -8)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -8)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Freedom Chests");
}
//Rank Unlocks
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -10)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -10)
{
itemLore.add(C.cBlack);
itemLore.add(C.cAqua + "Unlocked with Ultra Rank");
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -11)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -11)
{
itemLore.add(C.cBlack);
itemLore.add(C.cPurple + "Unlocked with Hero Rank");
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -12)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -12)
{
itemLore.add(C.cBlack);
itemLore.add(C.cGreen + "Unlocked with Legend Rank");
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -13)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -13)
{
itemLore.add(C.cBlack);
itemLore.add(C.cRed + "Unlocked with Titan Rank");
@@ -178,12 +178,12 @@ public class GadgetPage extends ShopPageBase
itemLore.add(C.cWhite + "You own " + C.cGreen + getPlugin().getInventoryManager().Get(getPlayer()).getItemCount(gadget.getName()));
// boolean canAffordAmmo = true;
-// if (itemGadget.getAmmo().getCost(CurrencyType.Coins) > 0)
+// if (itemGadget.getAmmo().getCost(GlobalCurrency.Coins) > 0)
// {
// itemLore.add(C.cBlack);
-// itemLore.add(C.cWhite + ((ItemGadget)gadget).getAmmo().getDisplayName() + " for " + C.cYellow + ((ItemGadget)gadget).getAmmo().getCost(CurrencyType.Coins) + " Coins");
+// itemLore.add(C.cWhite + ((ItemGadget)gadget).getAmmo().getDisplayName() + " for " + C.cYellow + ((ItemGadget)gadget).getAmmo().getCost(GlobalCurrency.Coins) + " Coins");
//
-// if (getDonationManager().Get(getPlayer().getName()).GetBalance(CurrencyType.Coins) >= itemGadget.getAmmo().getCost(CurrencyType.Coins))
+// if (getDonationManager().Get(getPlayer().getName()).getBalance(GlobalCurrency.Coins) >= itemGadget.getAmmo().getCost(GlobalCurrency.Coins))
// {
// itemLore.add(C.cGreen + "Right-Click To Purchase");
// }
@@ -239,26 +239,26 @@ public class GadgetPage extends ShopPageBase
}
else
{
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
- itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + gadget.getCost(CurrencyType.TREASURE_SHARD) + " Treasure Shards");
+ itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + gadget.getCost(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).GetBalance(CurrencyType.TREASURE_SHARD) >= gadget.getCost(CurrencyType.TREASURE_SHARD))
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer()).getBalance(GlobalCurrency.TREASURE_SHARD) >= gadget.getCost(GlobalCurrency.TREASURE_SHARD))
{
itemLore.add(C.cBlack);
- itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + gadget.getCost(CurrencyType.TREASURE_SHARD) + " Treasure Shards");
+ itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + gadget.getCost(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).GetBalance(CurrencyType.TREASURE_SHARD) >= gadget.getCost(CurrencyType.TREASURE_SHARD))
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer()).getBalance(GlobalCurrency.TREASURE_SHARD) >= gadget.getCost(GlobalCurrency.TREASURE_SHARD))
{
itemLore.add(C.cBlack);
itemLore.add(C.cGreen + "Click to Purchase");
addButton(slot, new ShopItem(Material.INK_SACK, (byte) 8, gadget.getName(), itemLore.toArray(new String[itemLore.size()]), 1, true, false).hideInfo(), new GadgetButton(gadget, this));
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
itemLore.add(C.cRed + "Not enough Treasure Shards.");
@@ -291,7 +291,7 @@ public class GadgetPage extends ShopPageBase
if (gadget.getGadgetType() == GadgetType.ARROW_TRAIL || gadget.getGadgetType() == GadgetType.DEATH
|| gadget.getGadgetType() == GadgetType.PARTICLE || gadget.getGadgetType() == GadgetType.DOUBLE_JUMP)
{
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -8)
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -8)
{
gadgetItemStack = CountryFlag.USA.getBanner();
BannerMeta bannerMeta = (BannerMeta) gadgetItemStack.getItemMeta();
@@ -314,7 +314,7 @@ public class GadgetPage extends ShopPageBase
if (gadget.getGadgetType() == GadgetType.ARROW_TRAIL || gadget.getGadgetType() == GadgetType.DEATH
|| gadget.getGadgetType() == GadgetType.PARTICLE || gadget.getGadgetType() == GadgetType.DOUBLE_JUMP)
{
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) == -8)
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) == -8)
{
gadgetItemStack = CountryFlag.USA.getBanner();
BannerMeta bannerMeta = (BannerMeta) gadgetItemStack.getItemMeta();
@@ -329,20 +329,20 @@ public class GadgetPage extends ShopPageBase
}
else
{
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
- itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + gadget.getCost(CurrencyType.TREASURE_SHARD) + " Treasure Shards");
+ itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + gadget.getCost(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
- if (gadget.getCost(CurrencyType.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).GetBalance(CurrencyType.TREASURE_SHARD) >= gadget.getCost(CurrencyType.TREASURE_SHARD))
+ if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer()).getBalance(GlobalCurrency.TREASURE_SHARD) >= gadget.getCost(GlobalCurrency.TREASURE_SHARD))
{
itemLore.add(C.cBlack);
itemLore.add(C.cGreen + "Click to Purchase");
addButton(slot, new ShopItem(Material.INK_SACK, (byte) 8, gadget.getName(), itemLore.toArray(new String[itemLore.size()]), 1, true, false).hideInfo(), new GadgetButton(gadget, this));
}
- else if (gadget.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ else if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
itemLore.add(C.cRed + "Not enough Treasure Shards.");
@@ -363,7 +363,7 @@ public class GadgetPage extends ShopPageBase
{
ItemGadget itemGadget = (ItemGadget)gadget;
- if (itemGadget.getAmmo().getCost(CurrencyType.TREASURE_SHARD) < 0)
+ if (itemGadget.getAmmo().getCost(GlobalCurrency.TREASURE_SHARD) < 0)
return;
}
@@ -372,14 +372,11 @@ public class GadgetPage extends ShopPageBase
UtilPlayer.message(player, F.main("Disguise", "You cant buy things while you are disguised!"));
return;
}
- getShop().openPageForPlayer(getPlayer(), new ConfirmationPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), new Runnable()
+ getShop().openPageForPlayer(getPlayer(), new ConfirmationPage<>(player, this, new SalesPackageProcessor(player, GlobalCurrency.TREASURE_SHARD, (gadget instanceof ItemGadget ? ((ItemGadget) gadget).getAmmo() : gadget), getDonationManager(), () ->
{
- public void run()
- {
- getPlugin().getInventoryManager().addItemToInventory(getPlayer(), gadget.getName(), (gadget instanceof ItemGadget ? ((ItemGadget) gadget).getAmmo().getQuantity() : gadget.getQuantity()));
- refresh();
- }
- }, this, (gadget instanceof ItemGadget ? ((ItemGadget) gadget).getAmmo() : gadget), CurrencyType.TREASURE_SHARD, getPlayer()));
+ getPlugin().getInventoryManager().addItemToInventory(getPlayer(), gadget.getName(), (gadget instanceof ItemGadget ? ((ItemGadget) gadget).getAmmo().getQuantity() : gadget.getQuantity()));
+ refresh();
+ }), gadget.buildIcon()));
}
public void activateGadget(Player player, Gadget gadget)
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 51ed4dd84..4ab38eae7 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
@@ -1,24 +1,26 @@
package mineplex.core.cosmetic.ui.page;
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.List;
-
-import mineplex.core.cosmetic.ui.button.open.*;
-import org.bukkit.Material;
-import org.bukkit.entity.Creature;
-import org.bukkit.entity.EntityType;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
-
import mineplex.core.account.CoreClientManager;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.LineFormat;
-import mineplex.core.common.util.NautHashMap;
import mineplex.core.common.util.UtilText;
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.OpenCostumes;
+import mineplex.core.cosmetic.ui.button.open.OpenDeathAnimations;
+import mineplex.core.cosmetic.ui.button.open.OpenDoubleJump;
+import mineplex.core.cosmetic.ui.button.open.OpenGadgets;
+import mineplex.core.cosmetic.ui.button.open.OpenGameModifiers;
+import mineplex.core.cosmetic.ui.button.open.OpenHats;
+import mineplex.core.cosmetic.ui.button.open.OpenMorphs;
+import mineplex.core.cosmetic.ui.button.open.OpenMounts;
+import mineplex.core.cosmetic.ui.button.open.OpenMusic;
+import mineplex.core.cosmetic.ui.button.open.OpenParticles;
+import mineplex.core.cosmetic.ui.button.open.OpenPets;
+import mineplex.core.cosmetic.ui.button.open.OpenWinEffect;
import mineplex.core.donation.DonationManager;
import mineplex.core.gadget.types.Gadget;
import mineplex.core.gadget.types.GadgetType;
@@ -27,6 +29,16 @@ import mineplex.core.pet.Pet;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.ShopItem;
import mineplex.core.shop.page.ShopPageBase;
+import org.bukkit.Material;
+import org.bukkit.entity.Creature;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.ClickType;
+
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
public class Menu extends ShopPageBase
{
@@ -41,7 +53,7 @@ public class Menu extends ShopPageBase
protected void buildPage()
{
// Treasure Shards
- int treasureShards = getDonationManager().Get(getPlayer()).getCoins();
+ int treasureShards = getDonationManager().Get(getPlayer()).getBalance(GlobalCurrency.TREASURE_SHARD);
List shardLore = new ArrayList();
shardLore.add(" ");
@@ -100,7 +112,7 @@ public class Menu extends ShopPageBase
Mount> mountActive = getPlugin().getMountManager().getActive(getPlayer());
for (Mount> mount : getPlugin().getMountManager().getMounts())
{
- if (getDonationManager().Get(getPlayer().getName()).OwnsUnknownPackage(mount.getName()))
+ if (getDonationManager().Get(getPlayer()).OwnsUnknownPackage(mount.getName()))
{
mountOwned++;
}
@@ -112,7 +124,7 @@ public class Menu extends ShopPageBase
int petMax = 0;
for (Pet pet : getPlugin().getPetManager().getFactory().GetPets())
{
- NautHashMap pets = getPlugin().getPetManager().Get(getPlayer()).getPets();
+ Map pets = getPlugin().getPetManager().Get(getPlayer()).getPets();
if (pets != null && pets.containsKey(pet.getPetType()))
{
petOwned++;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/MountPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/MountPage.java
index bc84607ea..020297748 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/MountPage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/MountPage.java
@@ -1,26 +1,25 @@
package mineplex.core.cosmetic.ui.page;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
-
import mineplex.core.account.CoreClientManager;
-import mineplex.core.common.CurrencyType;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.cosmetic.ui.CosmeticShop;
+import mineplex.core.cosmetic.ui.button.MountButton;
import mineplex.core.cosmetic.ui.button.activate.ActivateMountButton;
import mineplex.core.cosmetic.ui.button.deactivate.DeactivateMountButton;
-import mineplex.core.cosmetic.ui.button.MountButton;
import mineplex.core.donation.DonationManager;
import mineplex.core.mount.Mount;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.ShopItem;
import mineplex.core.shop.page.ShopPageBase;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.ClickType;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
public class MountPage extends ShopPageBase
{
@@ -60,67 +59,67 @@ public class MountPage extends ShopPageBase
itemLore.add(C.cBlack);
itemLore.addAll(Arrays.asList(mount.getDescription()));
- if (!getDonationManager().Get(getPlayer().getName()).OwnsUnknownPackage(mount.getName()))
+ if (!getDonationManager().Get(getPlayer()).OwnsUnknownPackage(mount.getName()))
{
- if (mount.getCost(CurrencyType.TREASURE_SHARD) == -1)
+ if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -1)
{
//Nothing
}
//Chest Unlocks
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -2 || mount.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -2 || mount.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Treasure Chests");
}
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -3)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -3)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Winter Holiday Treasure");
}
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -4)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -4)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Halloween Pumpkin Treasure");
}
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -5)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -5)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Easter Holiday Treasure");
}
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -6)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -6)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Valentines Holiday Treasure");
}
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -7)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -7)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Freedom Chests");
}
//Rank Unlocks
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -10)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -10)
{
itemLore.add(C.cBlack);
itemLore.add(C.cAqua + "Unlocked with Ultra Rank");
}
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -11)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -11)
{
itemLore.add(C.cBlack);
itemLore.add(C.cPurple + "Unlocked with Hero Rank");
}
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -12)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -12)
{
itemLore.add(C.cBlack);
itemLore.add(C.cGreen + "Unlocked with Legend Rank");
}
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) == -13)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) == -13)
{
itemLore.add(C.cBlack);
itemLore.add(C.cRed + "Unlocked with Titan Rank");
}
}
- if (getDonationManager().Get(getPlayer().getName()).OwnsUnknownPackage(mount.getName()))
+ if (getDonationManager().Get(getPlayer()).OwnsUnknownPackage(mount.getName()))
{
if (mount.getActive().containsKey(getPlayer()))
{
@@ -139,20 +138,20 @@ public class MountPage extends ShopPageBase
}
else
{
- if (mount.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ if (mount.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
- itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + mount.getCost(CurrencyType.TREASURE_SHARD) + " Treasure Shards");
+ itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + mount.getCost(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
- if (mount.getCost(CurrencyType.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).GetBalance(CurrencyType.TREASURE_SHARD) >= mount.getCost(CurrencyType.TREASURE_SHARD))
+ if (mount.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer()).getBalance(GlobalCurrency.TREASURE_SHARD) >= mount.getCost(GlobalCurrency.TREASURE_SHARD))
{
itemLore.add(C.cBlack);
itemLore.add(C.cGreen + "Click to Purchase");
addButton(slot, new ShopItem(Material.INK_SACK, (byte) 8, mount.getName(), itemLore.toArray(new String[itemLore.size()]), 1, true, false), new MountButton(mount, this));
}
- else if (mount.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ else if (mount.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
itemLore.add(C.cRed + "Not enough Treasure Shards.");
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetPage.java
index 8ecd60944..77b4c15ee 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetPage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetPage.java
@@ -1,33 +1,16 @@
package mineplex.core.cosmetic.ui.page;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import net.minecraft.server.v1_8_R3.Blocks;
-import net.minecraft.server.v1_8_R3.ChatMessage;
-import net.minecraft.server.v1_8_R3.EntityPlayer;
-import net.minecraft.server.v1_8_R3.Items;
-import net.minecraft.server.v1_8_R3.PacketPlayOutOpenWindow;
-import net.minecraft.server.v1_8_R3.PacketPlayOutSetSlot;
-
-import org.bukkit.Material;
-import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
-import org.bukkit.entity.EntityType;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
-
import mineplex.core.account.CoreClientManager;
-import mineplex.core.common.CurrencyType;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.cosmetic.ui.CosmeticShop;
import mineplex.core.cosmetic.ui.PetSorter;
-import mineplex.core.cosmetic.ui.button.activate.ActivatePetButton;
-import mineplex.core.cosmetic.ui.button.deactivate.DeactivatePetButton;
import mineplex.core.cosmetic.ui.button.PetButton;
import mineplex.core.cosmetic.ui.button.RenamePetButton;
+import mineplex.core.cosmetic.ui.button.activate.ActivatePetButton;
+import mineplex.core.cosmetic.ui.button.deactivate.DeactivatePetButton;
import mineplex.core.donation.DonationManager;
import mineplex.core.pet.Pet;
import mineplex.core.pet.PetExtra;
@@ -35,6 +18,16 @@ import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.ShopItem;
import mineplex.core.shop.page.AnvilContainer;
import mineplex.core.shop.page.ShopPageBase;
+import net.minecraft.server.v1_8_R3.*;
+import org.bukkit.Material;
+import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.ClickType;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
public class PetPage extends ShopPageBase
{
@@ -63,49 +56,49 @@ public class PetPage extends ShopPageBase
//Chest Unlocks
if (!getPlugin().getPetManager().Get(getPlayer()).getPets().containsKey(pet.getPetType()))
{
- if (pet.getCost(CurrencyType.TREASURE_SHARD) == -1)
+ if (pet.getCost(GlobalCurrency.TREASURE_SHARD) == -1)
{
//Nothing
}
- else if (pet.getCost(CurrencyType.TREASURE_SHARD) == -2 || pet.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ else if (pet.getCost(GlobalCurrency.TREASURE_SHARD) == -2 || pet.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Treasure Chests");
}
- else if (pet.getCost(CurrencyType.TREASURE_SHARD) == -3)
+ else if (pet.getCost(GlobalCurrency.TREASURE_SHARD) == -3)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Winter Holiday Treasure");
}
- else if (pet.getCost(CurrencyType.TREASURE_SHARD) == -4)
+ else if (pet.getCost(GlobalCurrency.TREASURE_SHARD) == -4)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Halloween Pumpkin Treasure");
}
- else if (pet.getCost(CurrencyType.TREASURE_SHARD) == -5)
+ else if (pet.getCost(GlobalCurrency.TREASURE_SHARD) == -5)
{
itemLore.add(C.cBlack);
itemLore.add(C.cBlue + "Found in Easter Holiday Treasure");
}
//Rank Unlocks
- else if (pet.getCost(CurrencyType.TREASURE_SHARD) == -10)
+ else if (pet.getCost(GlobalCurrency.TREASURE_SHARD) == -10)
{
itemLore.add(C.cBlack);
itemLore.add(C.cAqua + "Unlocked with Ultra Rank");
}
- else if (pet.getCost(CurrencyType.TREASURE_SHARD) == -11)
+ else if (pet.getCost(GlobalCurrency.TREASURE_SHARD) == -11)
{
itemLore.add(C.cBlack);
itemLore.add(C.cPurple + "Unlocked with Hero Rank");
}
- else if (pet.getCost(CurrencyType.TREASURE_SHARD) == -12)
+ else if (pet.getCost(GlobalCurrency.TREASURE_SHARD) == -12)
{
itemLore.add(C.cBlack);
itemLore.add(C.cGreen + "Unlocked with Legend Rank");
}
- else if (pet.getCost(CurrencyType.TREASURE_SHARD) == -13)
+ else if (pet.getCost(GlobalCurrency.TREASURE_SHARD) == -13)
{
itemLore.add(C.cBlack);
itemLore.add(C.cRed + "Unlocked with Titan Rank");
@@ -145,20 +138,20 @@ public class PetPage extends ShopPageBase
//Not Owned
else
{
- if (pet.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ if (pet.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
- itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + pet.getCost(CurrencyType.TREASURE_SHARD) + " Treasure Shards");
+ itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + pet.getCost(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
-
- if (pet.getCost(CurrencyType.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).GetBalance(CurrencyType.TREASURE_SHARD) >= pet.getCost(CurrencyType.TREASURE_SHARD))
+
+ if (pet.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer()).getBalance(GlobalCurrency.TREASURE_SHARD) >= pet.getCost(GlobalCurrency.TREASURE_SHARD))
{
itemLore.add(C.cBlack);
itemLore.add(C.cGreen + "Click to Purchase");
addButton(slot, new ShopItem(Material.INK_SACK, (byte) 8, pet.getPetName(), itemLore.toArray(new String[itemLore.size()]), 1, true, false), new PetButton(pet, this));
}
- else if (pet.getCost(CurrencyType.TREASURE_SHARD) > 0)
+ else if (pet.getCost(GlobalCurrency.TREASURE_SHARD) > 0)
{
itemLore.add(C.cBlack);
itemLore.add(C.cRed + "Not enough Treasure Shards.");
@@ -194,7 +187,7 @@ public class PetPage extends ShopPageBase
|| getPlugin().getPetManager().getActivePet(getPlayer().getName()).getType() != EntityType.VILLAGER
|| getPlugin().getPetManager().getActivePet(getPlayer().getName()).getType() != EntityType.ZOMBIE)
{
- addButton(slot, new ShopItem(petExtra.GetMaterial(), (byte) 0, "Rename " + getPlugin().getPetManager().getActivePet(getPlayer().getName()).getCustomName() + " for " + C.cYellow + petExtra.getCost(CurrencyType.TREASURE_SHARD) + C.cGreen + " Shards", itemLore.toArray(new String[itemLore.size()]), 1, false, false), new RenamePetButton(this));
+ addButton(slot, new ShopItem(petExtra.GetMaterial(), (byte) 0, "Rename " + getPlugin().getPetManager().getActivePet(getPlayer().getName()).getCustomName() + " for " + C.cYellow + petExtra.getCost(GlobalCurrency.TREASURE_SHARD) + C.cGreen + " Shards", itemLore.toArray(new String[itemLore.size()]), 1, false, false), new RenamePetButton(this));
}
slot++;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetTagPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetTagPage.java
index 27997f3a8..0a5c568fa 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetTagPage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetTagPage.java
@@ -2,7 +2,7 @@ package mineplex.core.cosmetic.ui.page;
import mineplex.cache.player.PlayerCache;
import mineplex.core.account.CoreClientManager;
-import mineplex.core.common.CurrencyType;
+import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
@@ -15,11 +15,12 @@ import mineplex.core.pet.Pet;
import mineplex.core.pet.PetExtra;
import mineplex.core.pet.repository.token.PetChangeToken;
import mineplex.core.pet.repository.token.PetToken;
-import mineplex.core.shop.page.ConfirmationPage;
+import mineplex.core.shop.confirmation.ConfirmationPage;
+import mineplex.core.shop.item.SalesPackageBase;
+import mineplex.core.shop.item.SalesPackageProcessor;
import mineplex.core.shop.page.ShopPageBase;
import net.minecraft.server.v1_8_R3.ItemStack;
import net.minecraft.server.v1_8_R3.Items;
-
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -93,44 +94,42 @@ public class PetTagPage extends ShopPageBase
}
PetExtra tag = new PetExtra("Rename " + _pet.getName() + " to " + _tagName, Material.NAME_TAG, 100);
+ final SalesPackageBase salesPackage = _petPurchase ? _pet : tag;
_pet.setDisplayName(C.cGreen + "Purchase " + _tagName);
-
- getShop().openPageForPlayer(getPlayer(), new ConfirmationPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), new Runnable()
+
+ getShop().openPageForPlayer(getPlayer(), new ConfirmationPage<>(_player, this, new SalesPackageProcessor(_player, GlobalCurrency.TREASURE_SHARD, salesPackage, _donationManager, () ->
{
- public void run()
+ PetChangeToken token = new PetChangeToken();
+
+ if (getClientManager().Get(getPlayer()) != null)
+ token.AccountId = getClientManager().Get(getPlayer()).getAccountId();
+ else
+ token.AccountId = PlayerCache.getInstance().getPlayer(getPlayer().getUniqueId()).getAccountId();
+
+ token.Name = getPlayer().getName();
+ token.PetType = _pet.getPetType().toString();
+ token.PetId = _pet.getPetType().ordinal();
+ token.PetName = _tagName;
+
+ PetToken petToken = new PetToken();
+ petToken.PetType = token.PetType;
+
+ if (_petPurchase)
{
- PetChangeToken token = new PetChangeToken();
-
- if (getClientManager().Get(getPlayer()) != null)
- token.AccountId = getClientManager().Get(getPlayer()).getAccountId();
- else
- token.AccountId = PlayerCache.getInstance().getPlayer(getPlayer().getUniqueId()).getAccountId();
-
- token.Name = getPlayer().getName();
- token.PetType = _pet.getPetType().toString();
- token.PetId = _pet.getPetType().ordinal();
- token.PetName = _tagName;
-
- PetToken petToken = new PetToken();
- petToken.PetType = token.PetType;
-
- if (_petPurchase)
- {
- getPlugin().getPetManager().getRepository().AddPet(token);
- getPlugin().getPetManager().addPetOwnerToQueue(getPlayer().getName(), _pet.getPetType());
- }
- else
- {
- getPlugin().getPetManager().getRepository().UpdatePet(token);
- getPlugin().getPetManager().addRenamePetToQueue(getPlayer().getName(), token.PetName);
- }
-
- getPlugin().getPetManager().Get(getPlayer()).getPets().put(_pet.getPetType(), token.PetName);
-
- getShop().openPageForPlayer(getPlayer(), new Menu(getPlugin(), getShop(), getClientManager(), getDonationManager(), getPlayer()));
+ getPlugin().getPetManager().getRepository().AddPet(token);
+ getPlugin().getPetManager().addPetOwnerToQueue(getPlayer().getName(), _pet.getPetType());
}
- }, null, _petPurchase ? _pet : tag, CurrencyType.TREASURE_SHARD, getPlayer()));
+ else
+ {
+ getPlugin().getPetManager().getRepository().UpdatePet(token);
+ getPlugin().getPetManager().addRenamePetToQueue(getPlayer().getName(), token.PetName);
+ }
+
+ getPlugin().getPetManager().Get(getPlayer()).getPets().put(_pet.getPetType(), token.PetName);
+
+ getShop().openPageForPlayer(getPlayer(), new Menu(getPlugin(), getShop(), getClientManager(), getDonationManager(), getPlayer()));
+ }), salesPackage.buildIcon()));
}
public void SetTagName(String tagName)
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/creature/Creature.java b/Plugins/Mineplex.Core/src/mineplex/core/creature/Creature.java
index e892c9f4d..a759cdcbc 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/creature/Creature.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/creature/Creature.java
@@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import mineplex.core.Managers;
import mineplex.core.MiniPlugin;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.updater.UpdateType;
@@ -55,6 +56,15 @@ public class Creature extends MiniPlugin
return entity;
}
+ public T SpawnEntity(Location location, Class entityType)
+ {
+ _spawnForce = true;
+ T entity = location.getWorld().spawn(location, entityType);
+ _spawnForce = false;
+
+ return entity;
+ }
+
@EventHandler(priority = EventPriority.HIGHEST)
public void eggThrow(PlayerEggThrowEvent event)
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/customdata/CustomDataManager.java b/Plugins/Mineplex.Core/src/mineplex/core/customdata/CustomDataManager.java
index 45893a07d..84e958429 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/customdata/CustomDataManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/customdata/CustomDataManager.java
@@ -2,6 +2,7 @@ package mineplex.core.customdata;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.UUID;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
@@ -26,14 +27,14 @@ public class CustomDataManager extends MiniDbClientPlugin
}
@Override
- public void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException
+ public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
{
PlayerCustomData data = new PlayerCustomData(_repository);
while (resultSet.next())
{
data.setData(_repository.getKey(resultSet.getInt("customDataId")), resultSet.getInt("data"));
}
- Set(playerName, data);
+ Set(uuid, data);
}
@Override
@@ -43,7 +44,7 @@ public class CustomDataManager extends MiniDbClientPlugin
}
@Override
- protected PlayerCustomData addPlayer(String player)
+ protected PlayerCustomData addPlayer(UUID uuid)
{
return new PlayerCustomData(_repository);
}
@@ -56,7 +57,7 @@ public class CustomDataManager extends MiniDbClientPlugin
if (accountId == -1)
return;
- runAsync(() -> _repository.saveData(name, accountId));
+ runAsync(() -> _repository.saveData(name, player.getUniqueId(), accountId));
}
public CorePlayer getCorePlayer(Player player)
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 14600c963..7ef6ad563 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/customdata/repository/CustomDataRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/customdata/repository/CustomDataRepository.java
@@ -4,6 +4,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Map;
+import java.util.UUID;
import mineplex.core.database.MinecraftRepository;
import org.bukkit.plugin.java.JavaPlugin;
@@ -68,9 +69,9 @@ public class CustomDataRepository extends MinecraftRepository
});
}
- public void saveData(String name, int accountId)
+ public void saveData(String name, UUID uuid, int accountId)
{
- PlayerCustomData data = _customDataManager.Get(name);
+ PlayerCustomData data = _customDataManager.Get(uuid);
for (Map.Entry entry : data.getDataMap().entrySet())
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/delayedtask/DelayedTask.java b/Plugins/Mineplex.Core/src/mineplex/core/delayedtask/DelayedTask.java
index d407ec093..cd71bfcca 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/delayedtask/DelayedTask.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/delayedtask/DelayedTask.java
@@ -12,6 +12,8 @@ import mineplex.core.common.util.Callback;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
+import java.util.UUID;
+
public class DelayedTask extends MiniClientPlugin
{
public static DelayedTask Instance;
@@ -58,9 +60,9 @@ public class DelayedTask extends MiniClientPlugin
}
@Override
- protected DelayedTaskClient addPlayer(String player)
+ protected DelayedTaskClient addPlayer(UUID uuid)
{
- return new DelayedTaskClient(Bukkit.getPlayer(player));
+ return new DelayedTaskClient(Bukkit.getPlayer(uuid));
}
public boolean HasTask(Player player, String task)
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseFactory.java b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseFactory.java
index f84a661db..1fa8fca66 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseFactory.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseFactory.java
@@ -35,7 +35,7 @@ public class DisguiseFactory
case PIG_ZOMBIE:
return new DisguisePigZombie(disguised);
case PLAYER:
- return new DisguisePlayer(disguised);
+ throw new UnsupportedOperationException("Player disguises must be initialized via constructor");
case SHEEP:
return new DisguiseSheep(disguised);
case SKELETON:
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java
index be83461c2..282267d2b 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java
@@ -2,27 +2,46 @@ package mineplex.core.disguise;
import com.mineplex.spigot.ChunkAddEntityEvent;
import mineplex.core.MiniPlugin;
-import mineplex.core.common.util.NautHashMap;
-import mineplex.core.common.util.UtilEnt;
+import mineplex.core.PlayerSelector;
+import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.UtilPlayer;
-import mineplex.core.disguise.disguises.*;
+import mineplex.core.common.util.UtilServer;
+import mineplex.core.common.util.UtilTasks;
+import mineplex.core.disguise.disguises.DisguiseBase;
+import mineplex.core.disguise.disguises.DisguiseBlock;
+import mineplex.core.disguise.disguises.DisguiseInsentient;
+import mineplex.core.disguise.disguises.DisguiseLiving;
+import mineplex.core.disguise.disguises.DisguisePlayer;
import mineplex.core.packethandler.IPacketHandler;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.packethandler.PacketInfo;
import mineplex.core.packethandler.PacketVerifier;
-import mineplex.core.timing.TimingManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
-import net.minecraft.server.v1_8_R3.*;
-import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutRelEntityMove;
-import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook;
-import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo.PlayerInfoData;
+import net.minecraft.server.v1_8_R3.BlockBed;
+import net.minecraft.server.v1_8_R3.BlockPosition;
+import net.minecraft.server.v1_8_R3.Blocks;
+import net.minecraft.server.v1_8_R3.Chunk;
+import net.minecraft.server.v1_8_R3.EntityPlayer;
+import net.minecraft.server.v1_8_R3.EntityTrackerEntry;
+import net.minecraft.server.v1_8_R3.EnumDirection;
+import net.minecraft.server.v1_8_R3.MinecraftServer;
+import net.minecraft.server.v1_8_R3.Packet;
+import net.minecraft.server.v1_8_R3.PacketPlayOutBed;
+import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEquipment;
+import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata;
+import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
+import net.minecraft.server.v1_8_R3.PacketPlayOutMapChunk;
+import net.minecraft.server.v1_8_R3.PacketPlayOutNamedEntitySpawn;
+import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo;
+import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
+import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
+import net.minecraft.server.v1_8_R3.PacketPlayOutUpdateAttributes;
+import net.minecraft.server.v1_8_R3.WorldServer;
+import net.minecraft.server.v1_8_R3.WorldSettings;
import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.World;
+import org.bukkit.OfflinePlayer;
import org.bukkit.block.BlockFace;
-import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Entity;
@@ -30,443 +49,285 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
-import org.bukkit.event.player.*;
+import org.bukkit.event.player.PlayerChangedWorldEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
-import org.bukkit.plugin.java.JavaPlugin;
-import java.lang.reflect.Field;
-import java.util.*;
-import java.util.Map.Entry;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.Predicate;
+/*
+ * notes: rabbit jump has been removed (PacketPlayOutEntityStatus) because it didn't work for 1.9+ anyways
+ *
+ * contact samczsun before you make any major changes
+ */
+@ReflectivelyCreateMiniPlugin
public class DisguiseManager extends MiniPlugin implements IPacketHandler
{
- private NautHashMap _spawnPacketMap = new NautHashMap();
- private NautHashMap _movePacketMap = new NautHashMap();
- private NautHashMap _moveTempMap = new NautHashMap();
- private HashSet _goingUp = new HashSet();
- private NautHashMap _entityDisguiseMap = new NautHashMap();
- private NautHashMap> _disguisePlayerMap = new NautHashMap>();
- private HashSet _blockedNames = new HashSet();
- private NautHashMap> _futureDisguises = new NautHashMap>();
- private NautHashMap> _lastRabbitHop = new NautHashMap>();
+ // A map of entityids which are disguised to their respective disguises
+ private Map> _spawnPacketMap = new HashMap<>();
+
+ // The map which stores entity UUIDs once they have been unloaded
+ private Map> _entityDisguiseMap = new HashMap<>();
+
+ // The map of which players should a disguise be shown to
+ private Map> _disguisePlayerMap = new HashMap<>();
+
+ private HashSet _blockedNames = new HashSet<>();
private boolean _handlingPacket = false;
- private Field _xChunk;
- private Field _zChunk;
-
- private Chunk _bedChunk;
- private boolean _bedPackets;
-
-
- public DisguiseManager(JavaPlugin plugin, PacketHandler packetHandler)
+ private DisguiseManager()
{
- super("Disguise Manager", plugin);
+ super("Disguise Manager");
- packetHandler.addPacketHandler(this, PacketPlayOutAnimation.class, PacketPlayOutBed.class,
- PacketPlayOutEntityStatus.class, PacketPlayOutMapChunk.class, PacketPlayOutMapChunkBulk.class,
- PacketPlayOutNamedEntitySpawn.class, PacketPlayOutPlayerInfo.class,
- PacketPlayOutEntity.PacketPlayOutRelEntityMove.class, PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook.class,
- PacketPlayOutSpawnEntity.class, PacketPlayOutEntityVelocity.class, PacketPlayOutEntityDestroy.class,
- PacketPlayOutEntityTeleport.class, PacketPlayOutEntityMetadata.class, PacketPlayOutSpawnEntityLiving.class,
- PacketPlayOutUpdateAttributes.class, PacketPlayOutEntityEquipment.class, PacketPlayOutNamedSoundEffect.class);
+ require(PacketHandler.class)
+ .addPacketHandler(this,
+ PacketPlayOutNamedEntitySpawn.class,
+ PacketPlayOutPlayerInfo.class,
+ PacketPlayOutSpawnEntity.class,
+ PacketPlayOutEntityMetadata.class,
+ PacketPlayOutSpawnEntityLiving.class,
+ PacketPlayOutUpdateAttributes.class,
+ PacketPlayOutEntityEquipment.class
+ );
- try
- {
- _bedChunk = new Chunk(((CraftWorld) Bukkit.getWorlds().get(0)).getHandle(), 0, 0);
- Field cSection = Chunk.class.getDeclaredField("sections");
- cSection.setAccessible(true);
-
- ChunkSection chunkSection = new ChunkSection(0, true);
- Block block = Block.getById(Material.BED_BLOCK.getId());
-
- // block = ((Object[]) ReflectionManager.getNmsField(ReflectionManager.getNmsClass("Block"),"byId")
- // .get(null))[Material.BED_BLOCK.getId()];
-
- for (BlockFace face : new BlockFace[]
- {
- BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH
- })
- {
- int x = 1 + face.getModX();
- int z = 1 + face.getModZ();
-
- chunkSection.setType(x, 0, z, block.fromLegacyData(face.ordinal()));
- chunkSection.a(x, 0, z, 0);
- chunkSection.b(x, 0, z, 0);
- }
-
- ChunkSection[] chunkSections = new ChunkSection[16];
- chunkSections[0] = chunkSection;
- cSection.set(_bedChunk, chunkSections);
-
- // TODO
-// _bedChunk.world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
-
- _xChunk = Chunk.class.getField("locX");
- _xChunk.setAccessible(true);
-
- _zChunk = Chunk.class.getField("locZ");
- _zChunk.setAccessible(true);
- }
- catch (IllegalArgumentException e)
- {
- e.printStackTrace();
- }
- catch (NoSuchFieldException e)
- {
- e.printStackTrace();
- }
- catch (SecurityException e)
- {
- e.printStackTrace();
- }
- catch (IllegalAccessException e)
- {
- e.printStackTrace();
- }
- }
-
- public void addFutureDisguise(DisguiseBase disguise, Player... players)
- {
- final int entityId = UtilEnt.getNewEntityId(false);
-
- _futureDisguises.put(entityId, new HashMap.SimpleEntry(disguise, players));
-
- Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable()
- {
- public void run()
- {
- if (_futureDisguises.containsKey(entityId))
- {
- Entry entry = _futureDisguises.remove(entityId);
-
- Entity entity = UtilEnt.getEntityById(entityId);
-
- if (entity != null)
- {
- entry.getKey().setEntity(entity);
-
- disguise(entry.getKey(), entry.getValue());
- }
- }
- }
- }, 4);
- }
-
- public void addViewerToDisguise(DisguiseBase disguise, Player player, boolean reapply)
- {
- _disguisePlayerMap.get(disguise).add(player);
-
- if (reapply)
- refreshTrackers(disguise.GetEntity().getBukkitEntity(), new Player[]
- {
- player
- });
+ createBedChunk();
}
+ // We want to re-register entities that were reloaded by chunk loading
@EventHandler
- public void ChunkAddEntity(ChunkAddEntityEvent event)
+ public void onEntityAdd(ChunkAddEntityEvent event)
{
- DisguiseBase disguise = _entityDisguiseMap.get(event.getEntity().getUniqueId().toString());
+ LinkedList disguises = _entityDisguiseMap.remove(event.getEntity().getUniqueId());
- if (disguise != null)
+ if (disguises != null)
{
- disguise.setEntity(event.getEntity());
- _spawnPacketMap.put(event.getEntity().getEntityId(), disguise);
- _entityDisguiseMap.remove(event.getEntity().getUniqueId().toString());
-
- if (disguise instanceof DisguiseRabbit)
- {
- _lastRabbitHop.put(disguise.GetEntityId(), new NautHashMap());
- }
- }
- }
-
- @EventHandler
- public void chunkJoin(PlayerJoinEvent event)
- {
- if (!_bedPackets)
- return;
-
- chunkMove(event.getPlayer(), event.getPlayer().getLocation(), null);
- }
-
- private void chunkMove(Player player, Location newLoc, Location oldLoc)
- {
- for (Packet packet : getChunkMovePackets(player, newLoc, oldLoc))
- {
- UtilPlayer.sendPacket(player, packet);
+ disguises.forEach(disguise -> disguise.setEntity(event.getEntity()));
+ _spawnPacketMap.put(event.getEntity().getEntityId(), disguises);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
- public void chunkMove(PlayerMoveEvent event)
- {
- if (!_bedPackets)
- return;
-
- Location to = event.getTo();
- Location from = event.getFrom();
-
- int x1 = getChunk(to.getX());
- int z1 = getChunk(to.getZ());
- int x2 = getChunk(from.getX());
- int z2 = getChunk(from.getZ());
-
- if (x1 != x2 || z1 != z2)
- {
- chunkMove(event.getPlayer(), to, from);
- }
- }
-
- @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
- public void chunkTeleport(PlayerTeleportEvent event)
- {
- if (!_bedPackets)
- return;
-
- Location to = event.getTo();
- Location from = event.getFrom();
-
- if (to.getWorld() == from.getWorld())
- {
- int x1 = getChunk(to.getX());
- int z1 = getChunk(to.getZ());
-
- int x2 = getChunk(from.getX());
- int z2 = getChunk(from.getZ());
-
- if (x1 != x2 || z1 != z2)
- {
- final Player player = event.getPlayer();
- final Location prev = new Location(to.getWorld(), x1, 0, z1);
-
- chunkMove(player, null, from);
-
- Bukkit.getScheduler().scheduleSyncDelayedTask(_plugin, new Runnable()
- {
- public void run()
- {
- if (!player.isOnline())
- {
- return;
- }
-
- Location loc = player.getLocation();
-
- if (player.getWorld() != loc.getWorld())
- {
- return;
- }
-
- int x2 = getChunk(loc.getX());
- int z2 = getChunk(loc.getZ());
-
- if (prev.getBlockX() == x2 && prev.getBlockZ() == z2 && loc.getWorld() == prev.getWorld())
- {
- chunkMove(player, loc, null);
- }
-
- refreshBedTrackers(player);
- }
- });
- }
- }
- }
-
- @EventHandler
- public void ChunkUnload(ChunkUnloadEvent event)
+ public void onEntityRemove(ChunkUnloadEvent event)
{
+ Set careAbout = new HashSet<>();
for (Entity entity : event.getChunk().getEntities())
{
if (_spawnPacketMap.containsKey(entity.getEntityId()))
{
- _entityDisguiseMap.put(entity.getUniqueId().toString(), _spawnPacketMap.get(entity.getEntityId()));
- _spawnPacketMap.remove(entity.getEntityId());
- _lastRabbitHop.remove(entity.getEntityId());
+ careAbout.add(entity);
}
}
- }
- public void clearDisguises()
- {
- _spawnPacketMap.clear();
- _movePacketMap.clear();
- _moveTempMap.clear();
- _goingUp.clear();
- _entityDisguiseMap.clear();
- _disguisePlayerMap.clear();
-
- if (_bedPackets)
+ // Run it a tick later so that if someone else happened to cancel the event, we won't fall for it
+ runSync(() ->
{
- unregisterBedChunk();
- }
- }
-
- private boolean containsSpawnDisguise(Player owner, int entityId)
- {
- return _spawnPacketMap.containsKey(entityId)
- && (_spawnPacketMap.get(entityId).Global || (_disguisePlayerMap.containsKey(_spawnPacketMap.get(entityId)) && _disguisePlayerMap
- .get(_spawnPacketMap.get(entityId)).contains(owner)));
- }
-
- public void disguise(DisguiseBase disguise, boolean refreshTrackers, Player... players)
- {
- if (!disguise.GetEntity().isAlive())
- return;
-
- if (!_bedPackets && disguise instanceof DisguisePlayer && ((DisguisePlayer) disguise).getSleepingDirection() != null)
- {
- _bedPackets = true;
-
- for (Player player : Bukkit.getOnlinePlayers())
+ for (Entity entity : careAbout)
{
- UtilPlayer.sendPacket(player, getBedChunkLoadPackets(player, player.getLocation()));
- }
- }
-
- if (players.length != 0)
- {
- disguise.Global = false;
- }
-
- _spawnPacketMap.put(disguise.GetEntityId(), disguise);
- _disguisePlayerMap.put(disguise, new HashSet());
-
- if (disguise instanceof DisguiseRabbit)
- {
- _lastRabbitHop.put(disguise.GetEntityId(), new NautHashMap());
- }
-
- for (Player player : players)
- addViewerToDisguise(disguise, player, false);
-
- if (disguise.GetEntity() instanceof EntityPlayer && disguise instanceof DisguisePlayer)
- {
- if (!(disguise.GetEntity()).getName().equalsIgnoreCase(((DisguisePlayer) disguise).getName()))
- {
- _blockedNames.add((disguise.GetEntity()).getName());
- }
- }
-
- if (refreshTrackers)
- {
- refreshTrackers(disguise.GetEntity().getBukkitEntity(),
- disguise.Global ? Bukkit.getOnlinePlayers().toArray(new Player[0]) : players);
- }
- }
-
- public void disguise(DisguiseBase disguise, Player... players)
- {
- disguise(disguise, true, players);
- }
-
- public PacketPlayOutMapChunk[] getBedChunkLoadPackets(Player player, Location newLoc)
- {
- prepareChunk(newLoc);
-
- PacketPlayOutMapChunk[] packets = new PacketPlayOutMapChunk[2];
-
- // Make unload
- packets[0] = new PacketPlayOutMapChunk(_bedChunk, true, 0);
-
- // Make load
- packets[1] = new PacketPlayOutMapChunk(_bedChunk, true, '\uffff');
-
- return packets;
- }
-
- public Packet getBedChunkUnloadPacket(Player player, Location oldLoc)
- {
- prepareChunk(oldLoc);
-
- return new PacketPlayOutMapChunk(_bedChunk, true, 0);
- }
-
- private Packet[] getBedPackets(Location recieving, DisguisePlayer playerDisguise)
- {
- try
- {
- PacketPlayOutBed bedPacket = new PacketPlayOutBed();
-
- bedPacket.a = playerDisguise.GetEntityId();
-
- int chunkX = getChunk(recieving.getX());
- int chunkZ = getChunk(recieving.getZ());
-
- bedPacket.b = new BlockPosition((chunkX * 16) + 1 + playerDisguise.getSleepingDirection().getModX(), 0, (chunkZ * 16)
- + 1 + playerDisguise.getSleepingDirection().getModZ());
-
- PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(playerDisguise.GetEntity());
-
- teleportPacket.c += (int) (0.35D * 32);
-
- return new Packet[]
+ if (!entity.isValid())
{
- bedPacket, teleportPacket
- };
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- }
-
- return null;
+ _entityDisguiseMap.put(entity.getUniqueId(), _spawnPacketMap.remove(entity.getEntityId()));
+ }
+ }
+ });
}
- private int getChunk(double block)
+ private boolean containsSpawnDisguise(Player owner, DisguiseBase disguise)
{
- int chunk = (int) Math.floor(block / 16D) - 17;
- chunk -= chunk % 8;
- return chunk;
+ return disguise != null && (_disguisePlayerMap.containsKey(disguise) && _disguisePlayerMap.get(disguise).test(owner));
}
- private ArrayList getChunkMovePackets(Player player, Location newLoc, Location oldLoc)
+ public void disguise(DisguiseBase disguise, Runnable after)
{
- ArrayList packets = new ArrayList();
+ disguise(disguise, after, player -> true);
+ }
- if (newLoc != null)
+ public void disguise(DisguiseBase disguise, Predicate accept)
+ {
+ disguise(disguise, null, accept);
+ }
+
+ public void disguise(DisguiseBase disguise)
+ {
+ disguise(disguise, null, t -> true);
+ }
+
+ public void disguise(DisguiseBase disguise, Runnable after, Predicate accept)
+ {
+ UtilTasks.onMainThread(() ->
{
- packets.addAll(Arrays.asList(getBedChunkLoadPackets(player, newLoc)));
+ // First, add everything to handle future disguises
+ DisguiseBase before = null;
- EntityPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
+ LinkedList