Merge branch 'develop' of ssh://git@github.com/Mineplex-LLC/Minecraft-PC.git into bugfix/pc-120+698

This commit is contained in:
xGamingDudex 2016-08-14 20:09:01 +02:00
commit e71cec874e
379 changed files with 10733 additions and 7001 deletions

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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()));
}
/**

View File

@ -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=");
@ -48,41 +85,31 @@ public class SkinData
_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());
ItemStack item = new ItemStack(Material.SKULL_ITEM, 1, (byte) 3);
SkullMeta meta = (SkullMeta) item.getItemMeta();
NBTTagList textures = new NBTTagList();
textures.add(arrayElement);
GameProfile data = new GameProfile(UUID.randomUUID(), getUnusedSkullName());
data.getProperties().put("textures", getProperty());
NBTTagCompound properties = new NBTTagCompound();
properties.set("textures", textures);
try
{
PROFILE_FIELD.set(meta, data);
}
catch (ReflectiveOperationException t)
{
t.printStackTrace();
}
NBTTagCompound skullOwner = new NBTTagCompound();
skullOwner.set("Properties", properties);
skullOwner.set("Name", new NBTTagString(getUnusedSkullName()));
item.setItemMeta(meta);
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);
return item;
}
public ItemStack getSkull(String name, List<String> lore)
@ -106,4 +133,39 @@ public class SkinData
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<MinecraftProfileTexture.Type, MinecraftProfileTexture> map = Maps.<MinecraftProfileTexture.Type, MinecraftProfileTexture>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;
}
}

View File

@ -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
{
@ -57,6 +55,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)
{
return getTrajectory2d(from.getLocation().toVector(), to.getLocation().toVector());
@ -98,12 +107,19 @@ 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;
@ -116,10 +132,17 @@ public class UtilAlg
public static float GetYaw(Vector vec)
{
double x = vec.getX();
double z = vec.getZ();
return GetYaw(vec.getX(), vec.getY(), vec.getZ());
}
double yaw = Math.toDegrees(Math.atan((-x)/z));
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;

View File

@ -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;
}

View File

@ -938,9 +938,18 @@ public class UtilPlayer
return true;
}
public static void removeAllowedCommands(Player player)
{
if (ALLOWED_COMMANDS.containsKey(player.getUniqueId()))
ALLOWED_COMMANDS.remove(player.getUniqueId());
}
/*
* Returns whether the UUID belongs to a slim skin
*/
public static boolean isSlimSkin(UUID playerUUID)
{
return (playerUUID.hashCode() & 1) == 1;
}
}

View File

@ -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<Player> GetPlayers()
{
return Lists.newArrayList(getPlayers());

View File

@ -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 <T> Consumer<T> onMainThread(Consumer<T> original)
{
return t ->
{
onMainThread(() ->
{
original.accept(t);
});
};
}
}

View File

@ -25,6 +25,11 @@ 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)

View File

@ -44,6 +44,11 @@
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.mineplex</groupId>
<artifactId>anticheat</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>

View File

@ -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<String, NautHashMap<Integer, Integer[]>> _entityMap = new NautHashMap<String, NautHashMap<Integer, Integer[]>>();
private NautHashMap<String, NautHashMap<Integer, String>> _entityNameMap = new NautHashMap<String, NautHashMap<Integer, String>>();
private NautHashMap<String, NautHashMap<Integer, Integer>> _entityRiding = new NautHashMap<String, NautHashMap<Integer, Integer>>();
private Map<UUID, Map<Integer, Integer[]>> _entityMap = new HashMap<>();
private Map<UUID, Map<Integer, String>> _entityNameMap = new HashMap<>();
private Map<UUID, HashMap<Integer, Integer>> _entityRiding = new HashMap<>();
private HashSet<String> _loggedIn = new HashSet<String>();
private HashSet<Integer> _ignoreIds = new HashSet<Integer>();
private Set<UUID> _loggedIn = new HashSet<>();
private Set<Integer> _ignoreIds = new HashSet<>();
private NautHashMap<UUID, Long> _exemptTimeMap = new NautHashMap<UUID, Long>();
private NautHashMap<UUID, NautHashMap<CheckType, Long>> _doubleStrike = new NautHashMap<UUID, NautHashMap<CheckType, Long>>();
private Map<UUID, Long> _exemptTimeMap = new HashMap<>();
private Map<UUID, NautHashMap<CheckType, Long>> _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)
@ -139,7 +142,7 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
if (event.getType() != UpdateType.TICK)
return;
for (Iterator<Entry<UUID, Long>> iterator = _exemptTimeMap.entrySet().iterator(); iterator.hasNext();)
for (Iterator<Entry<UUID, Long>> iterator = _exemptTimeMap.entrySet().iterator(); iterator.hasNext(); )
{
final Entry<UUID, Long> entry = iterator.next();
@ -150,12 +153,12 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
}
for (Iterator<Entry<UUID, NautHashMap<CheckType, Long>>> iterator = _doubleStrike.entrySet().iterator(); iterator
.hasNext();)
.hasNext(); )
{
Entry<UUID, NautHashMap<CheckType, Long>> entry = iterator.next();
for (Iterator<Entry<CheckType, Long>> innerIterator = entry.getValue().entrySet().iterator(); innerIterator
.hasNext();)
.hasNext(); )
{
final Entry<CheckType, Long> entry2 = innerIterator.next();
@ -176,11 +179,11 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler, NCPHook
if (event.getType() != UpdateType.SEC)
return;
for (Iterator<String> iterator = _loggedIn.iterator(); iterator.hasNext();)
for (Iterator<UUID> 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<Integer, Integer[]>());
_entityNameMap.put(owner.getName(), new NautHashMap<Integer, String>());
_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<WatchableObject>) 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<WatchableObject>) 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<WatchableObject>) 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<WatchableObject>) spawnPacket.l.c())
{
PacketPlayInUseEntity usePacket = (PacketPlayInUseEntity) packet;
loop:
for (Entry<Integer, Integer[]> 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<WatchableObject>) 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<Integer, Integer>());
}
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<WatchableObject>) 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<Integer, Integer[]> 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<Integer, Integer>());
}
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
{

View File

@ -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<Class<?>, 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 extends MiniPlugin> T get(Class<T> clazz)
{
Object result = MANAGER_MAP.get(clazz);
return clazz.cast(result);
}
/**
* Gets the given module, and initializes if necessary
* @param clazz
* @param <T>
* @return
*/
public static <T extends MiniPlugin> T require(Class<T> clazz)
{
if (MANAGER_MAP.containsKey(clazz))
{
return get(clazz);
}
try
{
ReflectivelyCreateMiniPlugin annotation = clazz.getAnnotation(ReflectivelyCreateMiniPlugin.class);
if (annotation != null)
{
Constructor<T> 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);
}
}

View File

@ -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<DataType extends Object> extends MiniPlugin
{
private static Object _clientDataLock = new Object();
private static final Object _clientDataLock = new Object();
private NautHashMap<String, DataType> _clientData = new NautHashMap<String, DataType>();
private Map<UUID, DataType> _clientData = new HashMap<>();
public MiniClientPlugin(String moduleName, JavaPlugin plugin)
{
@ -26,18 +28,27 @@ public abstract class MiniClientPlugin<DataType extends Object> 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));
if (!_clientData.containsKey(uuid))
_clientData.put(uuid, addPlayer(uuid));
return _clientData.get(name);
return _clientData.get(uuid);
}
}
@ -45,7 +56,7 @@ public abstract class MiniClientPlugin<DataType extends Object> extends MiniPlug
public DataType Get(Player player)
{
return Get(player.getName());
return Get(player.getUniqueId());
}
protected Collection<DataType> GetValues()
@ -55,16 +66,16 @@ public abstract class MiniClientPlugin<DataType extends Object> 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);
}

View File

@ -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<DataType extends Object> 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()
{

View File

@ -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<String, ICommand>();
_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 extends MiniPlugin> T require(Class<T> clazz)
{
return Managers.require(clazz);
}
}

View File

@ -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<String, HashSet<Integer>> _armorStands = new HashMap<String, HashSet<Integer>>();
private Map<UUID, HashSet<Integer>> _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<String> itel = _armorStands.keySet().iterator();
Iterator<UUID> 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<Integer>());
_armorStands.put(player.getUniqueId(), new HashSet<Integer>());
}
HashSet<Integer> list = _armorStands.get(player.getName());
HashSet<Integer> list = _armorStands.get(player.getUniqueId());
if (packetInfo.getPacket() instanceof PacketPlayOutSpawnEntityLiving)
{

View File

@ -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<Player> selector)
{
List<Player> 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<Player> selectPlayers(Predicate<Player> selector)
{
return Bukkit.getOnlinePlayers().stream().filter(selector).collect(Collectors.<Player>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<Player> 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<Player> 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<Player> 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<Player> inWorld(World world)
{
return entity -> world == null || entity.getWorld().equals(world);
}
/**
* This will return a {@link Predicate} which will return true <b>if and only if</b> all of the supplied Predicates
* return true
* @param predicates The Predicates to test against
* @return The resulting criterion
*/
@SafeVarargs
public static <T> Predicate<T> and(Predicate<T>... predicates)
{
return t ->
{
for (Predicate<T> predicate : predicates)
{
if (!predicate.test(t))
{
return false;
}
}
return true;
};
}
/**
* This will return a {@link Predicate} which will return true <b>if and only if</b> one of the the supplied Predicates
* return true
* @param predicates The Predicates to test against
* @return The resulting criterion
*/
@SafeVarargs
public static <T> Predicate<T> or(Predicate<T>... predicates)
{
return t ->
{
for (Predicate<T> predicate : predicates)
{
if (predicate.test(t))
{
return true;
}
}
return false;
};
}
}

View File

@ -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
{
}

View File

@ -9,31 +9,46 @@ import mineplex.serverdata.Utility;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
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;
}
@ -43,15 +58,15 @@ public class CoreClient
return _player;
}
public void SetPlayer(Player player)
{
_player = player;
}
public void SetPlayer(Player player)
{
_player = player;
}
public int getAccountId()
{
return _accountId;
}
public int getAccountId()
{
return _accountId;
}
public void Delete()
{
@ -123,34 +138,57 @@ public class CoreClient
return _networkSessionLoginTime;
}
public void undisguise()
{
this._disguisedName = null;
this._disguisedSkin = null;
this._disguisedRank = null;
this._disguisedUUID = null;
}
public String getDisguisedAs()
{
return _disguisedAs;
return this._disguisedName;
}
public void setDisguisedAs(String originalName)
public String getDisguisedSkin()
{
this._disguisedAs = originalName;
return this._disguisedSkin;
}
/**
* Only use this method if the client is actually disguised!
* @return
*/
public Rank getDisguisedRank() {
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 Rank getRealOrDisguisedRank()
{
if (this._disguisedRank != null)
{
return this._disguisedRank;
}
return this.GetRank();
}
public void setNetworkSessionLoginTime(long loginTime)

View File

@ -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,16 +49,16 @@ import org.bukkit.plugin.java.JavaPlugin;
public class CoreClientManager extends MiniPlugin
{
private static NautHashMap<String, Object> _clientLoginLock = new NautHashMap<String, Object>();
private static final Map<String, Object> CLIENT_LOGIN_LOCKS = new ConcurrentHashMap<>();
private JavaPlugin _plugin;
private AccountRepository _repository;
private NautHashMap<String, CoreClient> _clientList;
private HashSet<String> _duplicateLoginGlitchPreventionList;
private Map<UUID, CoreClient> _clientList = new HashMap<>();
private HashSet<UUID> _duplicateLoginGlitchPreventionList = new HashSet<>();
private List<ILoginProcessor> _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);
@ -70,9 +76,7 @@ public class CoreClientManager extends MiniPlugin
_plugin = plugin;
_repository = new AccountRepository(plugin, webServer);
_clientList = new NautHashMap<String, CoreClient>();
_duplicateLoginGlitchPreventionList = new HashSet<String>();
WHITELIST_BYPASS = whitelistBypass;
WHITELIST_BYPASS = whitelistBypass;
}
public AccountRepository getRepository()
@ -87,70 +91,69 @@ public class CoreClientManager extends MiniPlugin
addCommand(new TestRank(this));
}
public CoreClient Add(String name)
public CoreClient Add(String name, UUID uuid)
{
CoreClient newClient = null;
CoreClient newClient = new CoreClient(name, uuid);
if (newClient == null)
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()
@ -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
*/
@ -190,7 +194,7 @@ public class CoreClientManager extends MiniPlugin
{
_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)
@ -203,7 +207,7 @@ 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())
{
@ -229,76 +233,67 @@ public class CoreClientManager extends MiniPlugin
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<CoreClient> loadedClient)
{
runAsync(() ->
{
public void run()
AtomicReference<CoreClient> 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();
uuid = UtilGameProfile.getProfileByName(playerName, false, profile -> {}).get().getId();
}
// Fails if not in DB and if duplicate.
UUID uuid = loadUUIDFromDB(playerName);
String response = "";
if (uuid == null)
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();
}
});
}
@ -336,11 +331,11 @@ public class CoreClientManager extends MiniPlugin
response = _repository.getClientByUUID(uuid);
}
token = gson.fromJson(response, ClientToken.class);
token = gson.fromJson(response, ClientToken.class);
CoreClient client = Add(playerName);
CoreClient client = Add(playerName, uuid);
client.SetRank(Rank.valueOf(token.Rank), false);
client.setAccountId(_repository.login(_loginProcessors, uuid, client.GetPlayerName()));
client.setAccountId(_repository.login(_loginProcessors, uuid, client.getName()));
// JSON sql response
Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
@ -375,10 +370,10 @@ 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,22 +382,25 @@ 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.getName() + " GetClient.");
String response = _repository.GetClient(client.getName(), uuid, ipAddress);
TimingManager.stop(client.getName() + " GetClient.");
TimingManager.start(client.GetPlayerName() + " Event.");
token = gson.fromJson(response, ClientToken.class);
TimingManager.start(client.getName() + " Event.");
token = gson.fromJson(response, ClientToken.class);
client.SetRank(Rank.valueOf(token.Rank), false);
@ -410,10 +408,10 @@ public class CoreClientManager extends MiniPlugin
// 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,14 +422,14 @@ public class CoreClientManager extends MiniPlugin
e.printStackTrace();
}
}
TimingManager.stop(client.GetPlayerName() + " While Loop.");
TimingManager.stop(client.getName() + " While Loop.");
if (_clientLoginLock.containsKey(client.GetPlayerName()))
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)
{
@ -445,31 +443,31 @@ public class CoreClientManager extends MiniPlugin
}
}
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());
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;
}
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());
client.SetPlayer(event.getPlayer());
// Reserved Slot Check
// Reserved Slot Check
if (Bukkit.getOnlinePlayers().size() >= Bukkit.getServer().getMaxPlayers())
{
if (client.GetRank().has(event.getPlayer(), Rank.ULTRA, false))
@ -488,13 +486,15 @@ public class CoreClientManager extends MiniPlugin
{
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.");
}
});
}
}
@ -510,10 +510,10 @@ public class CoreClientManager extends MiniPlugin
// 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());
}
}
@ -630,9 +630,9 @@ public class CoreClientManager extends MiniPlugin
if (event.getType() != UpdateType.SLOW)
return;
synchronized(_clientLock)
synchronized (_clientLock)
{
for (Iterator<Entry<String, CoreClient>> clientIterator = _clientList.entrySet().iterator(); clientIterator.hasNext();)
for (Iterator<Entry<UUID, CoreClient>> clientIterator = _clientList.entrySet().iterator(); clientIterator.hasNext(); )
{
CoreClient client = clientIterator.next().getValue(); // rawr, needed this for custom data - william
Player clientPlayer = client.GetPlayer();
@ -643,7 +643,7 @@ public class CoreClientManager extends MiniPlugin
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()));
}
}
}

View File

@ -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);
}

View File

@ -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 static final HandlerList handlers = new HandlerList();
private String _name;
private int _accountId;
private String _name;
private UUID _uuid;
private int _accountId;
public ClientUnloadEvent(String name, int accountId)
{
_name = name;
_accountId = accountId;
}
public ClientUnloadEvent(String name, UUID uuid, int accountId)
{
_name = name;
_accountId = accountId;
this._uuid = uuid;
}
public String GetName()
{
return _name;
}
public String GetName()
{
return _name;
}
public int getAccountId()
{
return _accountId;
}
public UUID getUniqueId()
{
return this._uuid;
}
public HandlerList getHandlers()
{
return handlers;
}
public int getAccountId()
{
return _accountId;
}
public static HandlerList getHandlerList()
{
return handlers;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -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();
}
}

View File

@ -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);

View File

@ -1,50 +1,130 @@
package mineplex.core.antihack;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
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.PlayerSelector;
import mineplex.core.Managers;
import mineplex.core.MiniPlugin;
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.*;
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.UtilParticle;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.disguise.disguises.DisguiseBase;
import mineplex.core.portal.Portal;
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.ChatClickable;
import net.minecraft.server.v1_8_R3.ChatComponentText;
import net.minecraft.server.v1_8_R3.ChatHoverable;
import net.minecraft.server.v1_8_R3.ChatModifier;
import net.minecraft.server.v1_8_R3.EnumChatFormat;
import net.minecraft.server.v1_8_R3.IChatBaseComponent;
import net.minecraft.server.v1_8_R3.MathHelper;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
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.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.event.player.PlayerVelocityEvent;
import org.bukkit.event.server.ServerListPingEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitTask;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
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 boolean IS_PHASE_TWO = false;
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<Integer, Double> STALK_END_PROBABILITY_EQUATION = x ->
{
return 1.0/ MAX_MIN_DIFF * x; // linear equation with points (0, 0) and (diff, 1)
};
private final Cache<String, Integer> _cooldown = CacheBuilder.newBuilder()
.concurrencyLevel(1)
.expireAfterWrite(30, TimeUnit.SECONDS)
.build();
private final Cache<UUID, Boolean> _stalkingCooldown = CacheBuilder.newBuilder()
.concurrencyLevel(1)
.expireAfterWrite(STALK_COOLDOWN_TIME_SECONDS, TimeUnit.SECONDS)
.build();
private final List<UUID> _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<Player, HashMap<String, ArrayList<Long>>> _offense = new HashMap<Player, HashMap<String, ArrayList<Long>>>();
@ -75,16 +155,22 @@ public class AntiHack extends MiniPlugin
private AntiHackRepository _repository;
protected AntiHack(JavaPlugin plugin, Punish punish, Portal portal, PreferencesManager preferences, CoreClientManager clientManager)
private List<AntiHackGuardian> _guardians = new ArrayList<>();
private Predicate<Player> _filter = player -> true;
private Set<Player> _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<Detector>();
@ -95,11 +181,517 @@ public class AntiHack extends MiniPlugin
_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;
}
}, this._plugin, ServicePriority.Normal);
ServerCommandManager.getInstance().registerCommandType(MajorViolationCommand.class, violation ->
{
if (!violation.getOriginatingServer().equals(this._thisServer))
{
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(" 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)
)
);
for (Player player : Bukkit.getOnlinePlayers())
{
if (Managers.get(PreferencesManager.class).Get(player).ShowMacReports && _clientManager.Get(player).GetRank().has(Rank.HELPER))
{
((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<Player> 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)
public void registerFilter(Predicate<Player> filter)
{
Instance = new AntiHack(plugin, punish, portal, preferences, clientManager);
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 (!IS_PHASE_TWO)
return;
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<Double, Double> 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<BukkitTask> 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(() ->
{
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);
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)
{
if (IS_PHASE_TWO)
{
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<AntiHack>(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<AntiHack>(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<AntiHack>(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
@ -254,16 +846,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
@ -275,7 +859,7 @@ public class AntiHack extends MiniPlugin
if (event.getType() != UpdateType.SEC)
return;
for (Iterator<Entry<Player, HashMap<String, ArrayList<Long>>>> playerIterator = _offense.entrySet().iterator(); playerIterator.hasNext();)
for (Iterator<Entry<Player, HashMap<String, ArrayList<Long>>>> playerIterator = _offense.entrySet().iterator(); playerIterator.hasNext(); )
{
Entry<Player, HashMap<String, ArrayList<Long>>> entry = playerIterator.next();
Player player = entry.getKey();
@ -325,6 +909,44 @@ public class AntiHack extends MiniPlugin
}
}
@EventHandler
public void onHack(PlayerViolationEvent event)
{
for (Player player : Bukkit.getOnlinePlayers())
{
CoreClient client = _clientManager.Get(player);
if (event.shouldTellStaff())
{
if (client.GetRank().has(Rank.HELPER))
{
UtilPlayer.message(player, C.cAqua + C.Scramble + "A" + ChatColor.RESET + C.cRed + C.Bold + " GWEN > " + ChatColor.RESET + C.cGold + event.getPlayer().getName() + C.cYellow + " failed " + event.getHackType() + " VL" + event.getViolations() + ": " + event.getMessage() + ". Please investigate");
}
}
}
if (event.shouldTellStaff())
{
String key = event.getPlayer().getName() + "." + event.getHackType();
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"))
@ -401,7 +1023,7 @@ public class AntiHack extends MiniPlugin
if (event.getType() != UpdateType.SLOW)
return;
for (Iterator<Entry<Player, Long>> playerIterator = _ignore.entrySet().iterator(); playerIterator.hasNext();)
for (Iterator<Entry<Player, Long>> playerIterator = _ignore.entrySet().iterator(); playerIterator.hasNext(); )
{
Player player = playerIterator.next().getKey();
@ -423,7 +1045,7 @@ public class AntiHack extends MiniPlugin
}
for (Iterator<Player> playerIterator = _hubAttempted.iterator(); playerIterator.hasNext();)
for (Iterator<Player> playerIterator = _hubAttempted.iterator(); playerIterator.hasNext(); )
{
Player player = playerIterator.next();
@ -465,4 +1087,16 @@ public class AntiHack extends MiniPlugin
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");
}
}

View File

@ -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<Double, Double> 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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,52 @@
package mineplex.core.antihack.actions;
import com.mineplex.anticheat.api.PlayerViolationEvent;
import com.mineplex.anticheat.checks.combat.KillauraTypeA;
import com.mineplex.anticheat.checks.combat.KillauraTypeB;
import com.mineplex.anticheat.checks.combat.KillauraTypeD;
import com.mineplex.anticheat.checks.player.BadPackets;
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<Class<?>, 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(60));
ACTIONS.put(KillauraTypeB.class, new BanwaveAction(NEXT_BAN_WAVE, 50));
ACTIONS.put(KillauraTypeD.class, new BanwaveAction(NEXT_BAN_WAVE, 550));
ACTIONS.put(BadPackets.class, new MixedAction(new BanwaveAction(NEXT_BAN_WAVE, 80), new ImmediateBanAction(120)));
}
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;
}
}

View File

@ -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()
);
}
}
}

View File

@ -0,0 +1,26 @@
package mineplex.core.antihack.actions;
import com.mineplex.anticheat.api.PlayerViolationEvent;
import mineplex.core.Managers;
import mineplex.core.antihack.AntiHack;
import mineplex.core.punish.Category;
import mineplex.core.punish.Punish;
import java.util.concurrent.TimeUnit;
class ImmediateBanAction extends AntiHackAction
{
ImmediateBanAction(int vl)
{
super(vl);
}
@Override
public void handle(PlayerViolationEvent event)
{
if (event.getViolations() >= this.getMinVl())
{
Managers.get(AntiHack.class).doBan(event.getPlayer(), event.getMessage());
}
}
}

View File

@ -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<AntiHackAction> _actions = new ArrayList<>();
private Map<UUID, Set<AntiHackAction>> _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();
}
}

View File

@ -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)
{
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,80 @@
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)
{
if (!AntiHack.IS_PHASE_TWO)
{
return;
}
runAsync(() ->
{
CoreClient client = require(CoreClientManager.class).Get(event.getPlayer());
List<BanWaveInfo> 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();
}
});
}
}

View File

@ -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<BanWaveInfo> getBanWaveInfo(int accountId)
{
List<BanWaveInfo> 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()));
}
}

View File

@ -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));
}
}
}

View File

@ -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 +
'}';
}
}

View File

@ -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);
}
}

View File

@ -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<BenefitData>
}
@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

View File

@ -987,7 +987,7 @@ public class BonusManager extends MiniClientPlugin<BonusClientData> 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<BonusClientData> 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<BonusClientData> 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

View File

@ -10,6 +10,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.thank.ThankManager;
import org.bukkit.*;
@ -58,6 +59,11 @@ 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();

View File

@ -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();

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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());
}

View File

@ -245,13 +245,13 @@ public class GadgetPage extends ShopPageBase<CosmeticManager, CosmeticShop>
itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + gadget.getCost(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).getBalance(GlobalCurrency.TREASURE_SHARD) >= gadget.getCost(GlobalCurrency.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(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).getBalance(GlobalCurrency.TREASURE_SHARD) >= gadget.getCost(GlobalCurrency.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");
@ -335,7 +335,7 @@ public class GadgetPage extends ShopPageBase<CosmeticManager, CosmeticShop>
itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + gadget.getCost(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
if (gadget.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).getBalance(GlobalCurrency.TREASURE_SHARD) >= gadget.getCost(GlobalCurrency.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");

View File

@ -2,10 +2,25 @@ package mineplex.core.cosmetic.ui.page;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.*;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilText;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.cosmetic.ui.CosmeticShop;
import mineplex.core.cosmetic.ui.button.open.*;
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;
@ -23,6 +38,7 @@ 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<CosmeticManager, CosmeticShop>
{
@ -96,7 +112,7 @@ public class Menu extends ShopPageBase<CosmeticManager, CosmeticShop>
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++;
}
@ -108,7 +124,7 @@ public class Menu extends ShopPageBase<CosmeticManager, CosmeticShop>
int petMax = 0;
for (Pet pet : getPlugin().getPetManager().getFactory().GetPets())
{
NautHashMap<EntityType, String> pets = getPlugin().getPetManager().Get(getPlayer()).getPets();
Map<EntityType, String> pets = getPlugin().getPetManager().Get(getPlayer()).getPets();
if (pets != null && pets.containsKey(pet.getPetType()))
{
petOwned++;

View File

@ -59,7 +59,7 @@ public class MountPage extends ShopPageBase<CosmeticManager, CosmeticShop>
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(GlobalCurrency.TREASURE_SHARD) == -1)
{
@ -119,7 +119,7 @@ public class MountPage extends ShopPageBase<CosmeticManager, CosmeticShop>
}
}
if (getDonationManager().Get(getPlayer().getName()).OwnsUnknownPackage(mount.getName()))
if (getDonationManager().Get(getPlayer()).OwnsUnknownPackage(mount.getName()))
{
if (mount.getActive().containsKey(getPlayer()))
{
@ -144,7 +144,7 @@ public class MountPage extends ShopPageBase<CosmeticManager, CosmeticShop>
itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + mount.getCost(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
if (mount.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).getBalance(GlobalCurrency.TREASURE_SHARD) >= mount.getCost(GlobalCurrency.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");

View File

@ -144,7 +144,7 @@ public class PetPage extends ShopPageBase<CosmeticManager, CosmeticShop>
itemLore.add(C.cWhiteB + "Cost: " + C.cAqua + pet.getCost(GlobalCurrency.TREASURE_SHARD) + " Treasure Shards");
}
if (pet.getCost(GlobalCurrency.TREASURE_SHARD) > 0 && getDonationManager().Get(getPlayer().getName()).getBalance(GlobalCurrency.TREASURE_SHARD) >= pet.getCost(GlobalCurrency.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");

View File

@ -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 extends Entity> T SpawnEntity(Location location, Class<T> entityType)
{
_spawnForce = true;
T entity = location.getWorld().spawn(location, entityType);
_spawnForce = false;
return entity;
}
@EventHandler(priority = EventPriority.HIGHEST)
public void eggThrow(PlayerEggThrowEvent event)
{

View File

@ -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<PlayerCustomData>
}
@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<PlayerCustomData>
}
@Override
protected PlayerCustomData addPlayer(String player)
protected PlayerCustomData addPlayer(UUID uuid)
{
return new PlayerCustomData(_repository);
}
@ -56,7 +57,7 @@ public class CustomDataManager extends MiniDbClientPlugin<PlayerCustomData>
if (accountId == -1)
return;
runAsync(() -> _repository.saveData(name, accountId));
runAsync(() -> _repository.saveData(name, player.getUniqueId(), accountId));
}
public CorePlayer getCorePlayer(Player player)

View File

@ -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<CustomData, Integer> entry : data.getDataMap().entrySet())
{

View File

@ -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<DelayedTaskClient>
{
public static DelayedTask Instance;
@ -58,9 +60,9 @@ public class DelayedTask extends MiniClientPlugin<DelayedTaskClient>
}
@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)

View File

@ -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:

View File

@ -1,34 +0,0 @@
package mineplex.core.disguise;
import mineplex.serverdata.data.Data;
public class DisguisePlayerBean implements Data
{
private int _accountID;
private String _disguisedPlayer;
private String _playerName;
public DisguisePlayerBean(int playerAccountID, String playerName, String disguiseAs)
{
this._accountID = playerAccountID;
this._disguisedPlayer = disguiseAs;
this._playerName = playerName;
}
public int getAccountID()
{
return _accountID;
}
public String getDisguisedPlayer()
{
return _disguisedPlayer;
}
public String getPlayerName()
{
return _playerName;
}
@Override
public String getDataId()
{
return _accountID+_playerName;
}
}

View File

@ -1,71 +0,0 @@
package mineplex.core.disguise;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClient;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.serverdata.Region;
import mineplex.serverdata.redis.RedisDataRepository;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
public class PlayerDisguiseManager extends MiniPlugin
{
private CoreClientManager _clients;
private RedisDataRepository<DisguisePlayerBean> _redis;
public PlayerDisguiseManager(JavaPlugin plugin, CoreClientManager clients)
{
super("Player Disguise Manager", plugin);
this._clients = clients;
_redis = new RedisDataRepository<DisguisePlayerBean>(Region.ALL, DisguisePlayerBean.class, "disguisedPlayer");
}
@EventHandler
public void onDisguisedPlayerQuit(PlayerQuitEvent event)
{
CoreClient client = _clients.Get(event.getPlayer());
if(client.isDisguised())
{
_redis.addElement(new DisguisePlayerBean(client.getAccountId(), client.GetPlayerName(), client.getDisguisedAs()), 60*60*12); // 12 hours
}
}
@EventHandler
public void onDisguisedPlayerJoin(PlayerJoinEvent event)
{
new BukkitRunnable()
{
@Override
public void run()
{
CoreClient client = _clients.Get(event.getPlayer());
if(!client.GetRank().has(Rank.JNR_DEV) && client.GetRank() != Rank.YOUTUBE_SMALL && client.GetRank() != Rank.TWITCH && client.GetRank() != Rank.YOUTUBE)
return;
if(_redis.elementExists(client.getAccountId()+client.GetPlayerName()))
{
DisguisePlayerBean bean = _redis.getElement(client.getAccountId()+client.GetPlayerName());
Bukkit.getPluginManager().callEvent(new PlayerCommandPreprocessEvent(event.getPlayer(), "/Disguise " + bean.getDisguisedPlayer()));
event.setJoinMessage("");
}
}
}.runTaskLater(getPlugin(), 7);
}
@EventHandler
public void onPlayerUndisguise(PlayerUndisguiseEvent event)
{
CoreClient client = _clients.Get(event.getPlayer());
_redis.removeElement(client.getAccountId()+client.GetPlayerName());
}
}

View File

@ -1,9 +1,11 @@
package mineplex.core.disguise.disguises;
import org.bukkit.entity.EntityType;
public abstract class DisguiseAmbient extends DisguiseInsentient
{
public DisguiseAmbient(org.bukkit.entity.Entity entity)
public DisguiseAmbient(EntityType entityType, org.bukkit.entity.Entity entity)
{
super(entity);
super(entityType, entity);
}
}

View File

@ -1,5 +1,6 @@
package mineplex.core.disguise.disguises;
import org.bukkit.entity.EntityType;
import org.bukkit.util.Vector;
import net.minecraft.server.v1_8_R3.EntityArmorStand;
@ -12,7 +13,7 @@ public class DisguiseArmorStand extends DisguiseInsentient
{
public DisguiseArmorStand(org.bukkit.entity.Entity entity)
{
super(entity);
super(EntityType.ARMOR_STAND, entity);
DataWatcher.a(10, (byte) 0, EntityArmorStand.META_ARMOR_OPTION, (byte) 0);
@ -47,7 +48,7 @@ public class DisguiseArmorStand extends DisguiseInsentient
}
@Override
public Packet GetSpawnPacket()
public Packet getSpawnPacket()
{
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving();
packet.a = Entity.getId();

View File

@ -1,12 +1,5 @@
package mineplex.core.disguise.disguises;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Player;
import mineplex.core.common.DummyEntity;
import mineplex.core.common.util.UtilPlayer;
import net.minecraft.server.v1_8_R3.DataWatcher;
@ -14,9 +7,19 @@ import net.minecraft.server.v1_8_R3.Entity;
import net.minecraft.server.v1_8_R3.EntityPlayer;
import net.minecraft.server.v1_8_R3.EntityTrackerEntry;
import net.minecraft.server.v1_8_R3.IntHashMap;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo;
import net.minecraft.server.v1_8_R3.WorldServer;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public abstract class DisguiseBase
{
@ -25,23 +28,37 @@ public abstract class DisguiseBase
private DisguiseBase _soundDisguise;
public boolean Global = true;
private EntityType _disguiseType;
public DisguiseBase(org.bukkit.entity.Entity entity)
/**
* Whether the disguised entity should be entirely hidden from a player if that player does not receive the disguise
*/
private boolean _hideIfNotDisguised = false;
public DisguiseBase(EntityType entityType, org.bukkit.entity.Entity entity)
{
if (entity != null)
if (entity == null)
{
setEntity(entity);
throw new NullPointerException("Entity cannot be null (did you mean to pass in an unspawned entity?)");
}
this._disguiseType = entityType;
setEntity(entity);
DataWatcher = new DataWatcher(new DummyEntity(null));
DataWatcher.a(0, Byte.valueOf((byte) 0), Entity.META_ENTITYDATA, (byte) 0);
DataWatcher.a(1, Short.valueOf((short) 300), Entity.META_AIR, 300);
DataWatcher.a(0, (byte) 0, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0);
DataWatcher.a(1, (short) 300, net.minecraft.server.v1_8_R3.Entity.META_AIR, 300);
_soundDisguise = this;
}
public void attemptToSpawn()
{
this.Entity.world.addEntity(this.Entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
}
public void setEntity(org.bukkit.entity.Entity entity)
{
Entity = ((CraftEntity) entity).getHandle();
@ -49,13 +66,13 @@ public abstract class DisguiseBase
public void UpdateDataWatcher()
{
DataWatcher.watch(0, Entity.getDataWatcher().getByte(0), Entity.META_ENTITYDATA, Entity.getDataWatcher().getByte(0));
DataWatcher.watch(1, Entity.getDataWatcher().getShort(1), Entity.META_AIR, (int) Entity.getDataWatcher().getShort(1));
DataWatcher.watch(0, Entity.getDataWatcher().getByte(0), net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, Entity.getDataWatcher().getByte(0));
DataWatcher.watch(1, Entity.getDataWatcher().getShort(1), net.minecraft.server.v1_8_R3.Entity.META_AIR, (int) Entity.getDataWatcher().getShort(1));
}
public abstract Packet GetSpawnPacket();
public abstract Packet getSpawnPacket();
public Packet GetMetaDataPacket()
public Packet getMetadataPacket()
{
UpdateDataWatcher();
return new PacketPlayOutEntityMetadata(Entity.getId(), DataWatcher, true);
@ -71,7 +88,7 @@ public abstract class DisguiseBase
if (tracker.get(Entity.getId()) == null)
return;
Packet packet = GetMetaDataPacket();
Packet packet = getMetadataPacket();
for (EntityPlayer player : tracker.get(Entity.getId()).trackedPlayers)
{
@ -92,17 +109,12 @@ public abstract class DisguiseBase
Entity.world.makeSound(Entity, _soundDisguise.getHurtSound(), _soundDisguise.getVolume(), _soundDisguise.getPitch());
}
public void playHurtSound(Location location)
{
Entity.world.makeSound(location.getX(), location.getY(), location.getZ(), _soundDisguise.getHurtSound(), _soundDisguise.getVolume(), _soundDisguise.getPitch());
}
public Entity GetEntity()
public Entity getEntity()
{
return Entity;
}
public int GetEntityId()
public int getEntityId()
{
return Entity.getId();
}
@ -117,7 +129,12 @@ public abstract class DisguiseBase
{
List<Player> players = new ArrayList<>();
IntHashMap<EntityTrackerEntry> tracker = ((WorldServer) Entity.world).tracker.trackedEntities;
for(EntityPlayer ep : tracker.get(Entity.getId()).trackedPlayers)
if (tracker.get(Entity.getId()) == null)
{
System.out.println("Tracker did not contain " + Entity.getId() + " " + Entity.getCustomName() + " " + Entity.dead + " " + Entity.locX + " " + Entity.locY + " " + Entity.locZ);
return Collections.emptyList();
}
for (EntityPlayer ep : tracker.get(Entity.getId()).trackedPlayers)
{
players.add(ep.getBukkitEntity());
}
@ -126,9 +143,55 @@ public abstract class DisguiseBase
public void sendPacket(Packet... packet)
{
for(Player p : getTrackedPlayers()) {
UtilPlayer.sendPacket(p, packet);
List<Player> trackedPlayers = getTrackedPlayers();
for (Packet p : packet)
{
if (p instanceof PacketPlayOutPlayerInfo)
{
MinecraftServer.getServer().getPlayerList().sendAll(p);
}
else
{
for (Player player : trackedPlayers)
{
UtilPlayer.sendPacket(player, p);
}
}
}
}
public void onDisguise(boolean isActive)
{
}
public void onUndisguise(boolean wasActive)
{
}
public void onTransfer(DisguiseBase other)
{
}
public void onReturn(DisguiseBase other)
{
}
public void setHideIfNotDisguised(boolean hideIfNotDisguised)
{
this._hideIfNotDisguised = hideIfNotDisguised;
}
public boolean isHideIfNotDisguised()
{
return this._hideIfNotDisguised;
}
public EntityType getDisguiseType()
{
return this._disguiseType;
}
}

View File

@ -5,6 +5,7 @@ import java.util.Random;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import org.bukkit.entity.EntityType;
public class DisguiseBlock extends DisguiseBase
{
@ -15,7 +16,7 @@ public class DisguiseBlock extends DisguiseBase
public DisguiseBlock(org.bukkit.entity.Entity entity, int blockId, int blockData)
{
super(entity);
super(EntityType.FALLING_BLOCK, entity);
_blockId = blockId;
_blockData = blockData;
@ -32,7 +33,7 @@ public class DisguiseBlock extends DisguiseBase
}
@Override
public Packet GetSpawnPacket()
public Packet getSpawnPacket()
{
PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity();
packet.a = Entity.getId();

View File

@ -35,5 +35,4 @@ public class DisguiseCaveSpider extends DisguiseMonster
{
return "mob.spider.say";
}
}

View File

@ -7,22 +7,13 @@ import org.bukkit.entity.*;
public abstract class DisguiseCreature extends DisguiseInsentient
{
private final EntityType _disguiseType;
public DisguiseCreature(EntityType disguiseType, org.bukkit.entity.Entity entity)
{
super(entity);
_disguiseType = disguiseType;
}
public EntityType getDisguiseType()
{
return _disguiseType;
super(disguiseType, entity);
}
@SuppressWarnings("deprecation")
public Packet GetSpawnPacket()
public Packet getSpawnPacket()
{
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving();
packet.a = Entity.getId();

View File

@ -1,12 +1,13 @@
package mineplex.core.disguise.disguises;
import net.minecraft.server.v1_8_R3.EntityHuman;
import org.bukkit.entity.EntityType;
public abstract class DisguiseHuman extends DisguiseLiving
{
public DisguiseHuman(org.bukkit.entity.Entity entity)
public DisguiseHuman(EntityType disguiseType, org.bukkit.entity.Entity entity)
{
super(entity);
super(disguiseType, entity);
byte skin = 0;
skin |= (1 << 0); //Enable Cape

View File

@ -4,14 +4,15 @@ import mineplex.core.common.*;
import net.minecraft.server.v1_8_R3.EntityInsentient;
import org.bukkit.*;
import org.bukkit.entity.EntityType;
public abstract class DisguiseInsentient extends DisguiseLiving
{
private boolean _showArmor;
public DisguiseInsentient(org.bukkit.entity.Entity entity)
public DisguiseInsentient(EntityType disguiseType, org.bukkit.entity.Entity entity)
{
super(entity);
super(disguiseType, entity);
DataWatcher.a(3, Byte.valueOf((byte) 0), EntityInsentient.META_CUSTOMNAME_VISIBLE, false);
DataWatcher.a(2, "", EntityInsentient.META_CUSTOMNAME, "");

View File

@ -5,6 +5,7 @@ import java.util.Random;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import net.minecraft.server.v1_8_R3.EntityLiving;
@ -17,9 +18,9 @@ public abstract class DisguiseLiving extends DisguiseBase
private boolean _invisible;
private ItemStack[] _equipment = new ItemStack[5];
public DisguiseLiving(org.bukkit.entity.Entity entity)
public DisguiseLiving(EntityType disguiseType, org.bukkit.entity.Entity entity)
{
super(entity);
super(disguiseType, entity);
DataWatcher.a(6, Float.valueOf(1.0F), EntityLiving.META_HEALTH, 1F);
DataWatcher.a(7, Integer.valueOf(0), EntityLiving.META_POTION_COLOR, 0);
@ -88,7 +89,7 @@ public abstract class DisguiseLiving extends DisguiseBase
{
PacketPlayOutEntityEquipment packet = new PacketPlayOutEntityEquipment();
packet.a = GetEntityId();
packet.a = getEntityId();
packet.b = nmsSlot;
packet.c = CraftItemStack.asNMSCopy(itemstack);

View File

@ -4,12 +4,13 @@ import net.minecraft.server.v1_8_R3.EntitySlime;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
import org.bukkit.entity.EntityType;
public class DisguiseMagmaCube extends DisguiseInsentient
{
public DisguiseMagmaCube(org.bukkit.entity.Entity entity)
{
super(entity);
super(EntityType.MAGMA_CUBE, entity);
DataWatcher.a(16, new Byte((byte) 1), EntitySlime.META_SIZE, 1);
}
@ -24,7 +25,7 @@ public class DisguiseMagmaCube extends DisguiseInsentient
return DataWatcher.getByte(16);
}
public Packet GetSpawnPacket()
public Packet getSpawnPacket()
{
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving();
packet.a = Entity.getId();

View File

@ -1,80 +1,180 @@
package mineplex.core.disguise.disguises;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.properties.PropertyMap;
import mineplex.core.common.skin.SkinData;
import mineplex.core.common.util.UtilPlayer;
import net.minecraft.server.v1_8_R3.EntityPlayer;
import net.minecraft.server.v1_8_R3.EntityTrackerEntry;
import net.minecraft.server.v1_8_R3.IntHashMap;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.disguise.playerdisguise.PlayerDisguiseManager;
import mineplex.core.thread.ThreadPool;
import mineplex.core.utils.UtilGameProfile;
import net.minecraft.server.v1_8_R3.AttributeInstance;
import net.minecraft.server.v1_8_R3.AttributeMapServer;
import net.minecraft.server.v1_8_R3.EntityHuman;
import net.minecraft.server.v1_8_R3.EntityPlayer;
import net.minecraft.server.v1_8_R3.IInventory;
import net.minecraft.server.v1_8_R3.ITileEntityContainer;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MobEffect;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutAbilities;
import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEffect;
import net.minecraft.server.v1_8_R3.PacketPlayOutExperience;
import net.minecraft.server.v1_8_R3.PacketPlayOutHeldItemSlot;
import net.minecraft.server.v1_8_R3.PacketPlayOutNamedEntitySpawn;
import net.minecraft.server.v1_8_R3.PacketPlayOutOpenWindow;
import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo;
import net.minecraft.server.v1_8_R3.WorldServer;
import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo.EnumPlayerInfoAction;
import net.minecraft.server.v1_8_R3.PacketPlayOutPosition;
import net.minecraft.server.v1_8_R3.PacketPlayOutRespawn;
import net.minecraft.server.v1_8_R3.PacketPlayOutUpdateAttributes;
import net.minecraft.server.v1_8_R3.PacketPlayOutUpdateHealth;
import net.minecraft.server.v1_8_R3.WorldSettings;
import org.bukkit.Bukkit;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftInventory;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Supplier;
public class DisguisePlayer extends DisguiseHuman
{
private Entity _entity;
private GameProfile _profile;
private boolean _sneaking;
private BlockFace _sleeping;
private boolean _sendSkinToSelf;
private String _requestedUsername;
public DisguisePlayer(org.bukkit.entity.Entity entity)
// If _requestedSkinData is not null, that will be used
private SkinData _requestedSkinData;
private String _requestedSkin;
private GameProfile _originalProfile;
private GameProfile _profile;
private BlockFace _sleeping;
private boolean _sendSkinToSelf = true;
private boolean _showInTabList = false;
private int _showInTabListDelay = 30;
private DisguisePlayer(Entity entity)
{
super(entity);
_entity = entity;
super(EntityType.PLAYER, entity);
this._originalProfile = entity instanceof Player ? UtilGameProfile.getGameProfile((Player) entity) : null;
}
public DisguisePlayer(org.bukkit.entity.Entity entity, GameProfile profile)
/**
* Using this constructor, this DisguisePlayer will be given the same GameProfile as provided
*/
public DisguisePlayer(Entity entity, GameProfile gameProfile)
{
this(entity);
setProfile(profile);
this._profile = UtilGameProfile.clone(gameProfile);
}
public void setProfile(GameProfile profile)
/**
* @param username The username to disguise this player as, AND the username of the player whose skin will be used
*/
public DisguisePlayer(Entity entity, String username)
{
GameProfile newProfile = new GameProfile(UUID.randomUUID(), profile.getName());
newProfile.getProperties().putAll(profile.getProperties());
_profile = newProfile;
this(entity, username, username);
}
public GameProfile getProfile()
{
return _profile;
}
/**
* @param username The username to disguise this entity as
* @param skin The username of the player whose skin will be used
*/
public DisguisePlayer(Entity entity, String username, String skin)
{
this(entity);
public void setSkinData(SkinData skin)
{
_profile.getProperties().put("textures", skin.getProperty());
}
this._requestedUsername = username;
this._requestedSkin = skin;
}
/**
* Currently not working.
*/
public void setSendSkinDataToSelf(boolean sendToSelf)
{
_sendSkinToSelf = sendToSelf;
}
public DisguisePlayer(Entity entity, String username, SkinData skinData)
{
this(entity);
public boolean getSendSkinDataToSelf()
{
return _sendSkinToSelf;
}
this._requestedUsername = username;
this._requestedSkinData = skinData;
}
/**
* If this DisguisePlayer has been initialized with a requested username and requested skin, it must be initialized
*
* @param onComplete The Runnable which will be run once initialized. Can be null. It will be run on a separate thread if initialization took place, and the current thread if not
*
* @returns A Future which, upon completion, implies the task is done
*/
public Future<Object> initialize(Runnable onComplete)
{
if (this._profile != null && this._profile.isComplete())
{
onComplete.run();
return CompletableFuture.completedFuture(null);
}
return ThreadPool.ASYNC.submit(() ->
{
try
{
GameProfile profileOfUsername = UtilGameProfile.getProfileByName(_requestedUsername, true, null).get();
if (_requestedSkinData == null)
{
GameProfile profileOfSkin = UtilGameProfile.getProfileByName(_requestedSkin, true, null).get();
_requestedSkinData = SkinData.constructFromGameProfile(profileOfSkin, true, true);
}
this._profile = new GameProfile(profileOfUsername.getId(), profileOfUsername.getName());
this._profile.getProperties().put("textures", _requestedSkinData.getProperty());
}
catch (Exception e)
{
// fixme handle
e.printStackTrace();
}
finally
{
onComplete.run();
}
}, null);
}
public GameProfile getProfile()
{
return _profile;
}
public void setSendSkinDataToSelf(boolean sendToSelf)
{
_sendSkinToSelf = sendToSelf;
}
public boolean getSendSkinDataToSelf()
{
return _sendSkinToSelf;
}
public void showInTabList(boolean show, int delay)
{
this._showInTabList = show;
this._showInTabListDelay = delay;
}
public BlockFace getSleepingDirection()
{
@ -82,31 +182,44 @@ public class DisguisePlayer extends DisguiseHuman
}
/**
* Don't use this if the disguise is already on as it will not work the way you want it to. Contact libraryaddict if you need
* Don't use this if the disguise is already on as it will not work the way you want it to. Contact samczsun if you need
* that added.
* <p>
* BlockFace.NORTH = feet pointing north
* BlockFace.SOUTH = feet pointing south
* etc etc
*/
public void setSleeping(BlockFace sleeping)
{
_sleeping = sleeping;
}
public void setSneaking(boolean sneaking)
public PacketPlayOutPlayerInfo getDisguiseInfoPackets(boolean add)
{
_sneaking = sneaking;
}
if (!add && _originalProfile == null)
return null;
public boolean getSneaking()
{
return _sneaking;
}
public Packet getNewInfoPacket(boolean add)
{
PacketPlayOutPlayerInfo newDisguiseInfo = new PacketPlayOutPlayerInfo();
newDisguiseInfo.a = add ? EnumPlayerInfoAction.ADD_PLAYER : EnumPlayerInfoAction.REMOVE_PLAYER;
PacketPlayOutPlayerInfo.PlayerInfoData info = newDisguiseInfo.new PlayerInfoData(_profile, 90,
WorldSettings.EnumGamemode.SURVIVAL, null);
PacketPlayOutPlayerInfo.PlayerInfoData info = newDisguiseInfo.new PlayerInfoData(add ? _profile : _originalProfile, UtilMath.r(120),
getAppropriateGamemode(), null);
newDisguiseInfo.b.add(info);
return newDisguiseInfo;
}
public Packet getUndisguiseInfoPackets(boolean remove)
{
if (!remove && _originalProfile == null)
return null;
PacketPlayOutPlayerInfo newDisguiseInfo = new PacketPlayOutPlayerInfo();
newDisguiseInfo.a = remove ? EnumPlayerInfoAction.REMOVE_PLAYER : EnumPlayerInfoAction.ADD_PLAYER;
PacketPlayOutPlayerInfo.PlayerInfoData info = newDisguiseInfo.new PlayerInfoData(remove ? _profile : _originalProfile, UtilMath.r(120),
getAppropriateGamemode(), null);
newDisguiseInfo.b.add(info);
@ -120,32 +233,26 @@ public class DisguisePlayer extends DisguiseHuman
byte b0 = DataWatcher.getByte(0);
if (_sneaking)
if (Entity.isSneaking())
{
DataWatcher.watch(0, Byte.valueOf((byte) (b0 | 1 << 1)), EntityHuman.META_ENTITYDATA, (byte) (b0 | 1 << 1));
}
else
{
DataWatcher.watch(0, Byte.valueOf((byte) (b0 & ~(1 << 1))), EntityHuman.META_ENTITYDATA, (byte) (b0 & ~(1 << 1)));
}
}
public PacketPlayOutNamedEntitySpawn spawnBeforePlayer(Location spawnLocation)
{
Location loc = spawnLocation.add(spawnLocation.getDirection().normalize().multiply(30));
loc.setY(Math.max(loc.getY(), 0));
if (Entity instanceof EntityPlayer)
{
EntityPlayer entityPlayer = (EntityPlayer) Entity;
PacketPlayOutNamedEntitySpawn packet = new PacketPlayOutNamedEntitySpawn();
packet.a = Entity.getId();
packet.b = _profile.getId();
packet.c = MathHelper.floor(loc.getX() * 32.0D);
packet.d = MathHelper.floor(loc.getY() * 32.0D);
packet.e = MathHelper.floor(loc.getZ() * 32.0D);
packet.f = (byte) ((int) (loc.getYaw() * 256.0F / 360.0F));
packet.g = (byte) ((int) (loc.getPitch() * 256.0F / 360.0F));
packet.i = DataWatcher;
return packet;
DataWatcher.watch(10, entityPlayer.getDataWatcher().getByte(10), EntityPlayer.META_SKIN, entityPlayer.getDataWatcher().getByte(10));
DataWatcher.watch(16, (byte) 0, EntityPlayer.META_CAPE, (byte) 1);
}
}
@Override
public PacketPlayOutNamedEntitySpawn GetSpawnPacket()
public PacketPlayOutNamedEntitySpawn getSpawnPacket()
{
PacketPlayOutNamedEntitySpawn packet = new PacketPlayOutNamedEntitySpawn();
packet.a = Entity.getId();
@ -153,8 +260,8 @@ public class DisguisePlayer extends DisguiseHuman
packet.c = MathHelper.floor(Entity.locX * 32.0D);
packet.d = MathHelper.floor(Entity.locY * 32.0D);
packet.e = MathHelper.floor(Entity.locZ * 32.0D);
packet.f = (byte) ((int) (Entity.yaw * 256.0F / 360.0F));
packet.g = (byte) ((int) (Entity.pitch * 256.0F / 360.0F));
packet.f = (byte) ((int) ((Entity.isFakeHead() ? Entity.fakePitch : Entity.pitch) * 256.0F / 360.0F));
packet.g = (byte) ((int) ((Entity.isFakeHead() ? Entity.fakePitch : Entity.pitch) * 256.0F / 360.0F));
packet.i = DataWatcher;
return packet;
@ -165,17 +272,212 @@ public class DisguisePlayer extends DisguiseHuman
return _profile.getName();
}
public void sendHit()
{
PacketPlayOutAnimation packet = new PacketPlayOutAnimation();
packet.a = GetEntityId();
public void sendHit()
{
PacketPlayOutAnimation packet = new PacketPlayOutAnimation();
packet.a = getEntityId();
packet.b = 0;
sendPacket(packet);
}
}
public org.bukkit.entity.Entity getEntity()
@Override
public void onDisguise(boolean isActive)
{
return _entity;
if (this.Entity instanceof EntityPlayer)
{
if (_sendSkinToSelf)
{
EntityPlayer entityPlayer = ((EntityPlayer) this.Entity);
// First construct the packet which will remove the previous disguise from the tab list
PacketPlayOutPlayerInfo playerInfoPacketRemove = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER);
PacketPlayOutPlayerInfo.PlayerInfoData dataRemove = playerInfoPacketRemove.new PlayerInfoData(_originalProfile, entityPlayer.ping, getAppropriateGamemode(), null);
playerInfoPacketRemove.b.add(dataRemove);
// This packet will add the new disguised name into the tab list
// We have to create a new profile with the original ID because when we respawn the caller, their UUID stays the same
PacketPlayOutPlayerInfo playerInfoPacket = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER);
PacketPlayOutPlayerInfo.PlayerInfoData data = playerInfoPacket.new PlayerInfoData(getSelfProfile(), entityPlayer.ping, getAppropriateGamemode(), null);
playerInfoPacket.b.add(data);
// This packet does the magic. It forces a new player to be created client-side which causes the skin to reload
PacketPlayOutRespawn respawnPacket = new PacketPlayOutRespawn(entityPlayer.world.getWorld().getEnvironment().getId(), entityPlayer.getWorld().getDifficulty(), entityPlayer.getWorld().worldData.getType(), getAppropriateGamemode());
entityPlayer.playerConnection.networkManager.handle(playerInfoPacketRemove);
entityPlayer.playerConnection.networkManager.handle(playerInfoPacket);
entityPlayer.playerConnection.networkManager.handle(respawnPacket);
update(entityPlayer);
}
}
}
@Override
public void onUndisguise(boolean wasActive)
{
if (this.Entity instanceof EntityPlayer)
{
if (_sendSkinToSelf)
{
EntityPlayer entityPlayer = ((EntityPlayer) this.Entity);
// First construct the packet which will remove the previous disguise from the tab list
PacketPlayOutPlayerInfo playerInfoPacketRemove = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER);
PacketPlayOutPlayerInfo.PlayerInfoData dataRemove = playerInfoPacketRemove.new PlayerInfoData(getSelfProfile(), entityPlayer.ping, getAppropriateGamemode(), null);
playerInfoPacketRemove.b.add(dataRemove);
// This packet will add the new disguised name into the tab list
// We have to create a new profile with the original ID because when we respawn the caller, their UUID stays the same
PacketPlayOutPlayerInfo playerInfoPacket = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER);
PacketPlayOutPlayerInfo.PlayerInfoData data = playerInfoPacket.new PlayerInfoData(_originalProfile, entityPlayer.ping, entityPlayer.playerInteractManager.getGameMode(), null);
playerInfoPacket.b.add(data);
// This packet does the magic. It forces a new player to be created client-side which causes the skin to reload
PacketPlayOutRespawn respawnPacket = new PacketPlayOutRespawn(entityPlayer.world.getWorld().getEnvironment().getId(), entityPlayer.getWorld().getDifficulty(), entityPlayer.getWorld().worldData.getType(), getAppropriateGamemode());
entityPlayer.playerConnection.networkManager.handle(playerInfoPacketRemove);
entityPlayer.playerConnection.networkManager.handle(playerInfoPacket);
entityPlayer.playerConnection.networkManager.handle(respawnPacket);
update(entityPlayer);
}
}
}
@Override
public void onTransfer(DisguiseBase disguise)
{
if (disguise instanceof DisguisePlayer)
{
if (((DisguisePlayer) disguise).getSendSkinDataToSelf() && _sendSkinToSelf && this.Entity instanceof EntityPlayer)
{
EntityPlayer entityPlayer = ((EntityPlayer) this.Entity);
PacketPlayOutPlayerInfo playerInfoRemove = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER);
PacketPlayOutPlayerInfo.PlayerInfoData data = playerInfoRemove.new PlayerInfoData(getSelfProfile(), entityPlayer.ping, getAppropriateGamemode(), null);
playerInfoRemove.b.add(data);
entityPlayer.playerConnection.networkManager.handle(playerInfoRemove);
}
}
}
@EventHandler
public void onReturn(DisguiseBase disguise)
{
if (disguise instanceof DisguisePlayer)
{
if (((DisguisePlayer) disguise).getSendSkinDataToSelf() && _sendSkinToSelf && this.Entity instanceof EntityPlayer)
{
EntityPlayer entityPlayer = ((EntityPlayer) this.Entity);
PacketPlayOutPlayerInfo playerInfoPacket = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER);
PacketPlayOutPlayerInfo.PlayerInfoData data = playerInfoPacket.new PlayerInfoData(((DisguisePlayer) disguise)._originalProfile, entityPlayer.ping, entityPlayer.playerInteractManager.getGameMode(), null);
playerInfoPacket.b.add(data);
entityPlayer.playerConnection.networkManager.handle(playerInfoPacket);
PacketPlayOutPlayerInfo playerInfoAdd = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER);
PacketPlayOutPlayerInfo.PlayerInfoData dataRemove = playerInfoAdd.new PlayerInfoData(getSelfProfile(), entityPlayer.ping, entityPlayer.playerInteractManager.getGameMode(), null);
playerInfoAdd.b.add(dataRemove);
entityPlayer.playerConnection.networkManager.handle(playerInfoAdd);
}
}
}
public GameProfile getOriginalProfile()
{
return UtilGameProfile.clone(_originalProfile);
}
private void update(EntityPlayer entityPlayer)
{
// And then we teleport them back to where they were
PacketPlayOutPosition positionPacket = new PacketPlayOutPosition(entityPlayer.locX, entityPlayer.locY, entityPlayer.locZ, entityPlayer.yaw, entityPlayer.pitch, new HashSet<>());
// Allow them to fly again
PacketPlayOutAbilities packetPlayOutAbilities = new PacketPlayOutAbilities(entityPlayer.abilities);
// Give them their exp again
PacketPlayOutExperience exp = new PacketPlayOutExperience(entityPlayer.exp, entityPlayer.expTotal, entityPlayer.expLevel);
entityPlayer.playerConnection.networkManager.handle(positionPacket);
entityPlayer.playerConnection.networkManager.handle(packetPlayOutAbilities);
entityPlayer.playerConnection.networkManager.handle(exp);
if (entityPlayer.activeContainer != entityPlayer.defaultContainer)
{
IInventory inv = ((CraftInventory) entityPlayer.activeContainer.getBukkitView().getTopInventory()).getInventory();
String name;
if (inv instanceof ITileEntityContainer)
{
name = ((ITileEntityContainer) inv).getContainerName();
}
else
{
name = "minecraft:chest";
}
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(entityPlayer.activeContainer.windowId, name, inv.getScoreboardDisplayName(), inv.getSize()));
}
entityPlayer.updateInventory(entityPlayer.activeContainer);
entityPlayer.playerConnection.networkManager.handle(new PacketPlayOutHeldItemSlot(entityPlayer.inventory.itemInHandIndex));
AttributeMapServer attributemapserver = (AttributeMapServer) entityPlayer.getAttributeMap();
Set<AttributeInstance> set = attributemapserver.getAttributes();
entityPlayer.getBukkitEntity().injectScaledMaxHealth(set, true);
entityPlayer.playerConnection.sendPacket(new PacketPlayOutUpdateHealth(entityPlayer.getBukkitEntity().getScaledHealth(), entityPlayer.getFoodData().getFoodLevel(), entityPlayer.getFoodData().getSaturationLevel()));
entityPlayer.playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(entityPlayer.getId(), set));
for (MobEffect mobEffect : entityPlayer.getEffects())
{
if (entityPlayer.playerConnection.networkManager.getVersion() > 47 || mobEffect.getEffectId() != 25)
entityPlayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(entityPlayer.getId(), mobEffect));
}
}
public boolean showInTabList()
{
return this._showInTabList;
}
public int getShowInTabListDelay()
{
return this._showInTabListDelay;
}
private WorldSettings.EnumGamemode getAppropriateGamemode()
{
if (Entity instanceof EntityPlayer)
{
return ((EntityPlayer) Entity).playerInteractManager.getGameMode();
}
return WorldSettings.EnumGamemode.SURVIVAL;
}
private GameProfile getSelfProfile()
{
GameProfile selfProfile = new GameProfile(getOriginalUUID(), this._profile.getName());
selfProfile.getProperties().putAll(this._profile.getProperties());
return selfProfile;
}
private UUID getOriginalUUID()
{
if (this._originalProfile.getProperties().containsKey(PlayerDisguiseManager.ORIGINAL_UUID_KEY))
{
try
{
return UUID.fromString(this._originalProfile.getProperties().get(PlayerDisguiseManager.ORIGINAL_UUID_KEY).iterator().next().getValue());
}
catch (IllegalArgumentException ignored)
{
}
}
return this._originalProfile.getId();
}
}

View File

@ -18,7 +18,7 @@ public class DisguiseRabbit extends DisguiseAnimal
}
@Override
public Packet GetSpawnPacket()
public Packet getSpawnPacket()
{
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving();
packet.a = Entity.getId();
@ -75,5 +75,4 @@ public class DisguiseRabbit extends DisguiseAnimal
return packet;
}
}

View File

@ -4,12 +4,13 @@ import net.minecraft.server.v1_8_R3.EntitySlime;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
import org.bukkit.entity.EntityType;
public class DisguiseSlime extends DisguiseInsentient
{
public DisguiseSlime(org.bukkit.entity.Entity entity)
{
super(entity);
super(EntityType.SLIME, entity);
DataWatcher.a(16, new Byte((byte) 1), EntitySlime.META_SIZE, 1);
}
@ -24,7 +25,7 @@ public class DisguiseSlime extends DisguiseInsentient
return DataWatcher.getByte(16);
}
public Packet GetSpawnPacket()
public Packet getSpawnPacket()
{
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving();
packet.a = Entity.getId();

View File

@ -0,0 +1,33 @@
package mineplex.core.disguise.playerdisguise;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
public class DisguiseCommand extends CommandBase<PlayerDisguiseManager> implements Listener
{
DisguiseCommand(PlayerDisguiseManager plugin)
{
super(plugin, Rank.ADMIN, new Rank[]{Rank.YOUTUBE, Rank.TWITCH}, "disguise");
}
@Override
public void Execute(final Player caller, final String[] args)
{
if (args == null || args.length == 0)
{
Plugin.undisguise(caller);
return;
}
if (args.length > 2)
{
UtilPlayer.message(caller, F.help("/disguise <username> [username of skin]", "Disguise yourself as 'username' with optional skin belonging to 'username of skin'", Rank.ADMIN));
return;
}
Plugin.disguise(caller, args[0], args.length > 1 ? args[1] : args[0]);
}
}

View File

@ -0,0 +1,137 @@
package mineplex.core.disguise.playerdisguise;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.PropertyMap;
import com.mojang.util.UUIDTypeAdapter;
import mineplex.serverdata.data.Data;
import java.lang.reflect.Type;
import java.util.UUID;
public class DisguisePlayerBean implements Data
{
private static final Gson GSON;
static
{
GSON = new GsonBuilder()
.registerTypeAdapter(GameProfile.class, new GameProfileSerializer())
.registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer())
.registerTypeAdapter(UUID.class, new UUIDTypeAdapter())
.create();
}
private int _accountID;
private String _playerName;
private String _disguisedPlayer;
private String _disguisedSkin;
private String _serializedGameProfile;
public DisguisePlayerBean(int playerAccountID, String playerName, String disguiseAs, String disguiseSkin, GameProfile targetProfile)
{
this._accountID = playerAccountID;
this._playerName = playerName;
this._disguisedPlayer = disguiseAs;
this._disguisedSkin = disguiseSkin;
this._serializedGameProfile = serialize(targetProfile);
}
public int getAccountID()
{
return _accountID;
}
public String getDisguisedPlayer()
{
return _disguisedPlayer;
}
public String getDisguisedSkin()
{
return this._disguisedSkin;
}
public String getPlayerName()
{
return _playerName;
}
@Override
public String getDataId()
{
return _accountID + _playerName;
}
public GameProfile getGameProfile()
{
return deserialize(this._serializedGameProfile);
}
private String serialize(GameProfile gameProfile)
{
return GSON.toJson(gameProfile);
}
private GameProfile deserialize(String in)
{
return GSON.fromJson(in, GameProfile.class);
}
private static class GameProfileSerializer implements JsonSerializer<GameProfile>, JsonDeserializer<GameProfile>
{
private GameProfileSerializer()
{
}
public GameProfile deserialize(JsonElement var1, Type var2, JsonDeserializationContext var3) throws JsonParseException
{
JsonObject var4 = (JsonObject) var1;
UUID var5 = var4.has("id") ? (UUID) var3.deserialize(var4.get("id"), UUID.class) : null;
String var6 = var4.has("name") ? var4.getAsJsonPrimitive("name").getAsString() : null;
GameProfile gameProfile = new GameProfile(var5, var6);
if (var4.has("properties"))
{
PropertyMap propertyMap = var3.deserialize(var4.get("properties"), PropertyMap.class);
gameProfile.getProperties().putAll(propertyMap);
}
return gameProfile;
}
public JsonElement serialize(GameProfile var1, Type var2, JsonSerializationContext var3)
{
JsonObject var4 = new JsonObject();
if (var1.getId() != null)
{
var4.add("id", var3.serialize(var1.getId()));
}
if (var1.getName() != null)
{
var4.addProperty("name", var1.getName());
}
if (var1.getProperties() != null)
{
var4.add("properties", var3.serialize(var1.getProperties()));
}
return var4;
}
}
}

View File

@ -0,0 +1,631 @@
package mineplex.core.disguise.playerdisguise;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.account.CoreClient;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.core.common.skin.SkinData;
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.cosmetic.CosmeticManager;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.disguise.disguises.DisguisePlayer;
import mineplex.core.disguise.playerdisguise.events.PlayerDisguisedEvent;
import mineplex.core.disguise.playerdisguise.events.PlayerPreDisguiseEvent;
import mineplex.core.disguise.playerdisguise.events.PlayerPreUndisguiseEvent;
import mineplex.core.disguise.playerdisguise.events.PlayerUndisguisedEvent;
import mineplex.core.event.JoinMessageBroadcastEvent;
import mineplex.core.friend.FriendManager;
import mineplex.core.packethandler.IPacketHandler;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.packethandler.PacketInfo;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.punish.Punish;
import mineplex.core.punish.PunishClient;
import mineplex.core.scoreboard.ScoreboardManager;
import mineplex.core.utils.UtilGameProfile;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.PlayerStatus;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ServerManager;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import net.minecraft.server.v1_8_R3.PacketPlayOutNamedEntitySpawn;
import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo;
import net.minecraft.server.v1_8_R3.PlayerList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
@ReflectivelyCreateMiniPlugin
public class PlayerDisguiseManager extends MiniPlugin implements IPacketHandler
{
public static final String ORIGINAL_UUID_KEY = "originalUUID";
private CoreClientManager _clients = require(CoreClientManager.class);
private DisguiseManager _disguise = require(DisguiseManager.class);
private Punish _punish = require(Punish.class);
private CosmeticManager _cosmetics = require(CosmeticManager.class);
private PreferencesManager _prefs = require(PreferencesManager.class);
private RedisDataRepository<DisguisePlayerBean> _redis;
// The list of usernames which cannot join because someone else is joining
private Set<String> _cannotJoin = Collections.synchronizedSet(new HashSet<>());
private Set<String> _loggingIn = Collections.synchronizedSet(new HashSet<>());
private Set<UUID> _pendingDisguise1 = new HashSet<>();
private PlayerDisguiseManager()
{
super("Player Disguise Manager");
_serverName = _plugin.getConfig().getString("serverstatus.name");
require(PacketHandler.class).addPacketHandler(this, PacketHandler.ListenerPriority.LOW, PacketPlayOutPlayerInfo.class, PacketPlayOutNamedEntitySpawn.class);
_redis = new RedisDataRepository<>(Region.ALL, DisguisePlayerBean.class, "disguisedPlayer");
}
@Override
public void addCommands()
{
this.addCommand(new DisguiseCommand(this));
}
@EventHandler(priority = EventPriority.MONITOR)
public void cleanup(PlayerQuitEvent event)
{
_cannotJoin.remove(event.getPlayer().getName().toLowerCase());
_loggingIn.remove(event.getPlayer().getName().toLowerCase());
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onDisguiserJoin(PlayerLoginEvent event)
{
for (DisguisePlayer disguisePlayer : _disguises.values())
{
if (disguisePlayer.getProfile().getName().equalsIgnoreCase(event.getPlayer().getName()))
{
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
event.setKickMessage("Failed to login: The authentication servers are currently down for maintainence");
return;
}
}
if (_cannotJoin.contains(event.getPlayer().getName().toLowerCase()))
{
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
event.setKickMessage("Failed to login: The authentication servers are currently down for maintainence");
return;
}
CoreClient client = _clients.Get(event.getPlayer().getUniqueId());
DisguisePlayerBean bean = _redis.getElement(client.getAccountId() + client.getName());
if (bean != null)
{
Player player = Bukkit.getPlayerExact(bean.getDisguisedPlayer());
if (player != null)
{
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
event.setKickMessage("You cannot join this server because you are disguised and the user is online!");
return;
}
if (_loggingIn.contains(bean.getDisguisedPlayer()))
{
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
event.setKickMessage("You cannot join this server because you are disguised and the user is currently logging in!");
return;
}
_cannotJoin.add(bean.getDisguisedPlayer().toLowerCase());
runSyncLater(() ->
{
_cannotJoin.remove(bean.getDisguisedPlayer().toLowerCase());
}, 800L);
}
else
{
_loggingIn.add(event.getPlayer().getName().toLowerCase());
runSyncLater(() -> _loggingIn.remove(event.getPlayer().getName().toLowerCase()), 800L);
}
}
@EventHandler(priority = EventPriority.LOW)
public void onDisguisedPlayerJoin(PlayerJoinEvent event)
{
CoreClient client = _clients.Get(event.getPlayer());
if (_redis.elementExists(client.getAccountId() + client.getName()))
{
DisguisePlayerBean bean = _redis.getElement(client.getAccountId() + client.getName());
if (bean.getGameProfile() != null)
{
_pendingDisguise1.add(event.getPlayer().getUniqueId());
runSyncLater(() ->
{
UtilPlayer.message(event.getPlayer(), F.main(getName(), "Attempting to disguise you as " + bean.getGameProfile().getName()));
disguise(event.getPlayer(), bean.getGameProfile());
}, 1);
}
}
}
@EventHandler
public void onJoinMessage(JoinMessageBroadcastEvent event)
{
if (_pendingDisguise1.contains(event.getPlayer().getUniqueId()))
{
CoreClient client = _clients.Get(event.getPlayer());
DisguisePlayerBean bean = _redis.getElement(client.getAccountId() + client.getName());
event.setUsername(bean.getDisguisedPlayer());
}
}
public void storeDisguiseData(Player player, String disguisedName, GameProfile gameProfile)
{
CoreClient client = _clients.Get(player);
_redis.addElement(new DisguisePlayerBean(client.getAccountId(), client.getName(), disguisedName, null, gameProfile), 60 * 60 * 12); // 12 hours
System.out.println("+=+=+=+=+=+=+");
System.out.println("ADDING DISGUISE INFO FOR " + player.getName());
System.out.println("+=+=+=+=+=+=+");
}
public void removeDisguiseData(Player player)
{
CoreClient client = _clients.Get(player);
_redis.removeElement(client.getAccountId() + client.getName());
System.out.println("+=+=+=+=+=+=+");
System.out.println("REMOVING DISGUISE INFO FOR " + player.getName());
System.out.println("+=+=+=+=+=+=+");
}
/*
* Maps players (their UUID) with their disguises
*/
private final Map<UUID, DisguisePlayer> _disguises = new HashMap<>();
/*
* Mapping of old username to disguised username
*/
private final Map<String, String> _mapping = new HashMap<>();
/*
* A set of usernames which are currently being disguised
* This is to prevent two people from running /disguise at the same time
*/
private Set<String> _pendingDisguise = Collections.synchronizedSet(new HashSet<>());
private final String _serverName;
private RedisDataRepository<PlayerStatus> _repository = new RedisDataRepository<>(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(),
Region.currentRegion(), PlayerStatus.class, "playerStatus");
@EventHandler
public void onQuit(PlayerQuitEvent event)
{
_pendingDisguise1.remove(event.getPlayer().getUniqueId());
_disguises.remove(event.getPlayer().getUniqueId());
_mapping.remove(event.getPlayer().getName().toLowerCase());
}
private boolean isDisguised(Player player)
{
return _disguises.containsKey(player.getUniqueId());
}
public void allow(Player player)
{
_pendingDisguise1.remove(player.getUniqueId());
}
public DisguiseManager getDisguiseManager()
{
return this._disguise;
}
public CoreClientManager getClientManager()
{
return this._clients;
}
public Punish getPunishManager()
{
return this._punish;
}
public CosmeticManager getCostmeticManager()
{
return this._cosmetics;
}
public PreferencesManager getPreferencesManager()
{
return this._prefs;
}
// DisguiseManager is too slow, we need to cancel it here first
@Override
public void handle(PacketInfo packetInfo)
{
if (packetInfo.getPacket() instanceof PacketPlayOutPlayerInfo)
{
PacketPlayOutPlayerInfo packet = (PacketPlayOutPlayerInfo) packetInfo.getPacket();
Iterator<PacketPlayOutPlayerInfo.PlayerInfoData> iterator = packet.b.iterator();
while (iterator.hasNext())
{
PacketPlayOutPlayerInfo.PlayerInfoData data = iterator.next();
if (_pendingDisguise1.contains(data.a().getId()))
{
iterator.remove();
}
}
if (packet.b.isEmpty())
{
packetInfo.setCancelled(true);
}
else
{
if (packet.a != PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER && packet.a != PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER)
{
for (PacketPlayOutPlayerInfo.PlayerInfoData data : packet.b)
{
Player player = Bukkit.getPlayerExact(data.a().getName());
if (player != null)
{
if (isDisguised(player))
{
PacketPlayOutPlayerInfo custom = new PacketPlayOutPlayerInfo();
custom.a = packet.a;
GameProfile originalProfile = _disguises.get(player.getUniqueId()).getOriginalProfile();
custom.b.add(custom.new PlayerInfoData(originalProfile, data.b, data.c, data.d()));
((CraftPlayer) player).getHandle().playerConnection.networkManager.handle(custom);
}
}
else
{
System.out.println("Null player while sending PlayerInfoData: " + data.a().getName());
}
}
}
}
}
else if (packetInfo.getPacket() instanceof PacketPlayOutNamedEntitySpawn)
{
PacketPlayOutNamedEntitySpawn spawn = (PacketPlayOutNamedEntitySpawn) packetInfo.getPacket();
if (_pendingDisguise1.contains(spawn.b))
{
packetInfo.setCancelled(true);
}
}
}
public void undisguise(Player caller)
{
if (!isDisguised(caller))
{
if (getDisguiseManager().isDisguised(caller))
{
UtilPlayer.message(caller, F.main("Disguise", "You have been disguised by something else. Perhaps you are morphed?"));
}
else
{
UtilPlayer.message(caller, F.main("Disguise", "You are not disguised. You can disguise with /disguise <username> [username of skin]"));
}
return;
}
if (getDisguiseManager().getActiveDisguise(caller) != _disguises.get(caller.getUniqueId()))
{
UtilPlayer.message(caller, F.main("Disguise", "Could not undisguise as it is not your active disguise. Perhaps you are morphed?"));
return;
}
PlayerPreUndisguiseEvent playerPreUndisguiseEvent = new PlayerPreUndisguiseEvent(caller);
UtilServer.CallEvent(playerPreUndisguiseEvent);
if (playerPreUndisguiseEvent.isCancelled())
{
return;
}
DisguisePlayer disguise = _disguises.remove(caller.getUniqueId());
GameProfile originalProfile = disguise.getOriginalProfile();
GameProfile currentProfile = ((CraftPlayer) caller).getProfile();
require(ScoreboardManager.class).handlePlayerQuit(disguise.getName());
try
{
UtilGameProfile.changeName(currentProfile, originalProfile.getName());
UtilGameProfile.changeId(currentProfile, originalProfile.getId());
currentProfile.getProperties().clear();
currentProfile.getProperties().putAll(originalProfile.getProperties());
Field playersByName = PlayerList.class.getDeclaredField("playersByName");
playersByName.setAccessible(true);
Map map = (Map) playersByName.get(MinecraftServer.getServer().getPlayerList());
map.remove(disguise.getProfile().getName());
map.put(disguise.getOriginalProfile().getName(), disguise.getEntity());
}
catch (Exception ex)
{
UtilPlayer.message(caller, F.main("Disguise", "Could not undisguise because something went terribly wrong :("));
ex.printStackTrace();
return;
}
getDisguiseManager().undisguise(caller);
GameProfile disguisedProfile = disguise.getProfile();
CoreClient client = getClientManager().Get(caller);
client.undisguise();
require(FriendManager.class).updatePlayerStatus(disguisedProfile.getName(), null);
require(FriendManager.class).updatePlayerStatus(originalProfile.getName(), new PlayerStatus(originalProfile.getName(), _serverName));
getPreferencesManager().handlePlayerJoin(caller, true);
require(ScoreboardManager.class).handlePlayerJoin(disguise.getOriginalProfile().getName());
_mapping.remove(disguise.getName().toLowerCase());
UtilPlayer.message(caller, F.main("Disguise", "You are no longer disguised!"));
getPluginManager().callEvent(new PlayerUndisguisedEvent(caller));
removeDisguiseData(caller);
}
public void disguise(Player caller, GameProfile requestedProfile)
{
if (getDisguiseManager().isDisguised(caller))
{
if (isDisguised(caller))
{
UtilPlayer.message(caller, F.main("Disguise", "You are already disguised. Please undisguise by using /disguise"));
}
else
{
UtilPlayer.message(caller, F.main("Disguise", "You are already disguised. Perhaps you are morphed?"));
}
return;
}
if (isDisguised(caller))
{
UtilPlayer.message(caller, F.main("Disguise", "You are already disguised. Please undisguise by using /disguise"));
return;
}
String requestedUsername = requestedProfile.getName();
if (!requestedUsername.equalsIgnoreCase(caller.getName()))
{
_cannotJoin.add(requestedUsername.toLowerCase());
for (Player other : UtilServer.getPlayersCollection())
{
if (other.getName().equalsIgnoreCase(requestedUsername))
{
UtilPlayer.message(caller, C.cRed + F.main("Disguise", "This name is already in use!"));
return;
}
}
}
if (!_pendingDisguise.add(requestedUsername.toLowerCase()))
{
UtilPlayer.message(caller, F.main("Disguise", "Someone is already disguising as that user"));
return;
}
PlayerPreDisguiseEvent playerPreDisguiseEvent = new PlayerPreDisguiseEvent(caller, requestedUsername);
UtilServer.CallEvent(playerPreDisguiseEvent);
if (playerPreDisguiseEvent.isCancelled())
{
UtilPlayer.message(caller, F.main(getName(), "Your disguise was cancelled by something"));
_pendingDisguise.remove(requestedUsername.toLowerCase());
return;
}
CoreClient callerClient = getClientManager().Get(caller);
if (!requestedUsername.equalsIgnoreCase(caller.getName()))
{
Rank otherRank = Rank.ALL;
CoreClient other = new CoreClient(requestedUsername, requestedProfile.getId());
try
{
getClientManager().LoadClient(other, requestedProfile.getId(), caller.getAddress().getAddress().getHostAddress());
otherRank = other.GetRank();
}
catch (NullPointerException exception)
{
other = null;
}
if (otherRank.has(Rank.TWITCH))
{
UtilPlayer.message(caller, F.main("Disguise", "You can't disguise as staff, YouTubers or Twitchers!"));
return;
}
if (other != null)
{
PunishClient pclient = getPunishManager().GetClient(requestedUsername);
if (pclient != null && (pclient.IsBanned() || pclient.IsMuted()))
{
UtilPlayer.message(caller, F.main("Disguise", "You can't disguise as players who are banned/muted!"));
return;
}
}
callerClient.disguise(requestedUsername, requestedProfile.getId(), otherRank);
_mapping.put(callerClient.getDisguisedAs().toLowerCase(), callerClient.getName());
System.out.println("=================");
System.out.println("Disguising " + caller.getName() + " as:");
System.out.println(requestedProfile.getName() + " id " + requestedProfile.getId());
System.out.println("Properties:");
for (Map.Entry<String, Property> p : requestedProfile.getProperties().entries())
{
System.out.println("\t" + p.getKey() + " " + p.getValue().getName());
System.out.println("\t" + p.getValue().getValue());
System.out.println("\t" + p.getValue().getSignature());
}
System.out.println("=================");
DisguisePlayer disguisePlayer = new DisguisePlayer(caller, requestedProfile);
disguisePlayer.showInTabList(true, 0);
allow(caller);
getDisguiseManager().disguise(disguisePlayer, () ->
{
GameProfile callerProfile = ((CraftPlayer) caller).getProfile();
require(ScoreboardManager.class).handlePlayerQuit(disguisePlayer.getOriginalProfile().getName());
try
{
UtilGameProfile.changeName(callerProfile, disguisePlayer.getProfile().getName());
UtilGameProfile.changeId(callerProfile, disguisePlayer.getProfile().getId());
Field playersByName = PlayerList.class.getDeclaredField("playersByName");
playersByName.setAccessible(true);
Map map = (Map) playersByName.get(MinecraftServer.getServer().getPlayerList());
map.remove(disguisePlayer.getOriginalProfile().getName());
map.put(disguisePlayer.getProfile().getName(), disguisePlayer.getEntity());
}
catch (Throwable t)
{
t.printStackTrace();
}
require(ScoreboardManager.class).handlePlayerJoin(disguisePlayer.getName());
callerProfile.getProperties().clear();
callerProfile.getProperties().putAll(disguisePlayer.getProfile().getProperties());
callerProfile.getProperties().removeAll(ORIGINAL_UUID_KEY);
callerProfile.getProperties().put(ORIGINAL_UUID_KEY, new Property(ORIGINAL_UUID_KEY, caller.getUniqueId().toString()));
require(FriendManager.class).updatePlayerStatus(disguisePlayer.getOriginalProfile().getName(), null);
require(FriendManager.class).updatePlayerStatus(requestedUsername, new PlayerStatus(requestedUsername, _serverName));
getPreferencesManager().handlePlayerJoin(caller, true);
_disguises.put(caller.getUniqueId(), disguisePlayer);
UtilPlayer.message(caller, F.main("Disguise", "Disguise Active: " + ChatColor.RESET + requestedUsername));
UtilServer.CallEvent(new PlayerDisguisedEvent(caller));
storeDisguiseData(caller, requestedUsername, requestedProfile);
_pendingDisguise.remove(requestedUsername.toLowerCase());
_cannotJoin.remove(requestedUsername.toLowerCase());
});
}
else
{
DisguisePlayer disguisePlayer = new DisguisePlayer(caller, requestedProfile);
disguisePlayer.showInTabList(true, 0);
allow(caller);
getDisguiseManager().disguise(disguisePlayer, () ->
{
((CraftPlayer) caller).getProfile().getProperties().clear();
((CraftPlayer) caller).getProfile().getProperties().putAll(disguisePlayer.getProfile().getProperties());
storeDisguiseData(caller, caller.getName(), requestedProfile);
getPreferencesManager().handlePlayerJoin(caller, true);
_disguises.put(caller.getUniqueId(), disguisePlayer);
_pendingDisguise.remove(requestedUsername.toLowerCase());
});
}
}
public void disguise(Player caller, String requestedUsername, String requestedSkin)
{
if (!validateUsername(caller, requestedUsername)) return;
if (!validateUsername(caller, requestedSkin)) return;
UtilGameProfile.getProfileByName(requestedUsername, true, requestedProfile ->
{
Consumer<GameProfile> skinConsumer = requestedProfileSkin ->
{
SkinData skinData = SkinData.constructFromGameProfile(requestedProfileSkin, true, true);
requestedProfile.getProperties().clear();
requestedProfile.getProperties().put("textures", skinData.getProperty());
disguise(caller, requestedProfile);
};
if (!requestedUsername.equalsIgnoreCase(requestedSkin))
{
UtilGameProfile.getProfileByName(requestedSkin, true, skinConsumer);
}
else
{
skinConsumer.accept(UtilGameProfile.clone(requestedProfile));
}
});
}
private boolean validateUsername(Player caller, String username)
{
String replaced = UtilGameProfile.legalize(username);
if (!replaced.equals(username))
{
UtilPlayer.message(caller, F.main(getName(), "The chosen username of '" + username + "' is not valid"));
return false;
}
if (username.length() > 16)
{
UtilPlayer.message(caller, F.main("Disguise", "The chosen username of '" + username + "' is " + F.count(String.valueOf(username.length() - 16)) + " characters too long!"));
return false;
}
if (username.length() <= 0)
{
UtilPlayer.message(caller, F.main("Disguise", "The chosen username of '" + username + "' must be longer than 0 characters"));
return false;
}
return true;
}
}

View File

@ -0,0 +1,32 @@
package mineplex.core.disguise.playerdisguise.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PlayerDisguisedEvent extends Event
{
private static final HandlerList HANDLERS = new HandlerList();
private Player _player;
public PlayerDisguisedEvent(Player disguisee)
{
this._player = disguisee;
}
public Player getPlayer()
{
return _player;
}
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
}

View File

@ -0,0 +1,54 @@
package mineplex.core.disguise.playerdisguise.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PlayerPreDisguiseEvent extends Event implements Cancellable
{
private static final HandlerList HANDLERS = new HandlerList();
private Player _player;
private String _requestedUsername;
private boolean _cancelled;
public PlayerPreDisguiseEvent(Player disguisee, String requestedUsername)
{
this._player = disguisee;
this._requestedUsername = requestedUsername;
}
public Player getPlayer()
{
return _player;
}
public String getRequestedUsername()
{
return this._requestedUsername;
}
@Override
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
@Override
public boolean isCancelled()
{
return _cancelled;
}
@Override
public void setCancelled(boolean b)
{
this._cancelled = b;
}
}

View File

@ -0,0 +1,47 @@
package mineplex.core.disguise.playerdisguise.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PlayerPreUndisguiseEvent extends Event implements Cancellable
{
private static final HandlerList HANDLERS = new HandlerList();
private Player _player;
private boolean _cancelled;
public PlayerPreUndisguiseEvent(Player disguisee)
{
this._player = disguisee;
}
public Player getPlayer()
{
return _player;
}
@Override
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
@Override
public boolean isCancelled()
{
return _cancelled;
}
@Override
public void setCancelled(boolean b)
{
this._cancelled = b;
}
}

View File

@ -1,14 +1,14 @@
package mineplex.core.disguise;
package mineplex.core.disguise.playerdisguise.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PlayerUndisguiseEvent extends Event
public class PlayerUndisguisedEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Player _player;
public PlayerUndisguiseEvent(Player disguisee)
public PlayerUndisguisedEvent(Player disguisee)
{
this._player = disguisee;
}

View File

@ -69,7 +69,7 @@ public class DonationManager extends MiniClientPlugin<Donor>
private void LoadDonor(DonorTokenWrapper token, UUID uuid)
{
Get(token.Name).loadToken(token.DonorToken);
Get(uuid).loadToken(token.DonorToken);
//_repository.updateGemsAndCoins(uuid, Get(token.Name).GetGems(), Get(token.Name).getCoins());
}
@ -80,7 +80,7 @@ public class DonationManager extends MiniClientPlugin<Donor>
public void PurchaseUnknownSalesPackage(final Callback<TransactionResponse> callback, final String name, final int accountId, final String packageName, final GlobalCurrency currencyType, final int cost, boolean oneTimePurchase)
{
final Donor donor = Bukkit.getPlayerExact(name) != null ? Get(name) : null;
final Donor donor = Bukkit.getPlayerExact(name) != null ? Get(Bukkit.getPlayerExact(name)) : null;
if (donor != null)
{
@ -120,7 +120,7 @@ public class DonationManager extends MiniClientPlugin<Donor>
{
if (response == TransactionResponse.Success)
{
Donor donor = Get(name);
Donor donor = Get(uuid);
if (donor != null)
{
@ -149,7 +149,7 @@ public class DonationManager extends MiniClientPlugin<Donor>
{
if (updateTotal)
{
Donor donor = Get(name);
Donor donor = Get(uuid);
if (donor != null)
{
@ -177,7 +177,7 @@ public class DonationManager extends MiniClientPlugin<Donor>
_gemQueue.get(player).put(caller, totalAmount);
//Do Temp Change
Donor donor = Get(player.getName());
Donor donor = Get(player.getUniqueId());
if (donor != null)
donor.addBalance(GlobalCurrency.GEM, amount);
@ -264,7 +264,7 @@ public class DonationManager extends MiniClientPlugin<Donor>
_coinQueue.get(player).put(caller, totalAmount);
//Do Temp Change
Donor donor = Get(player.getName());
Donor donor = Get(player.getUniqueId());
if (donor != null)
donor.addBalance(GlobalCurrency.TREASURE_SHARD, amount);
@ -333,7 +333,7 @@ public class DonationManager extends MiniClientPlugin<Donor>
{
if (success)
{
Donor donor = Get(data.getPlayerName());
Donor donor = Get(data.getUuid());
if (donor != null)
{
@ -373,7 +373,7 @@ public class DonationManager extends MiniClientPlugin<Donor>
}
@Override
protected Donor addPlayer(String player)
protected Donor addPlayer(UUID uuid)
{
return new Donor();
}

View File

@ -36,18 +36,13 @@ public class ShardCommand extends CommandBase<DonationManager>
}
else if (target == null)
{
Plugin.getClientManager().loadClientByName(targetName, new Runnable()
Plugin.getClientManager().loadClientByName(targetName, client ->
{
public void run()
if (client != null)
rewardCoins(caller, null, targetName, client.getAccountId(), coinsString);
else
{
CoreClient client = Plugin.getClientManager().Get(targetName);
if (client != null)
rewardCoins(caller, null, targetName, client.getAccountId(), coinsString);
else
{
UtilPlayer.message(caller, F.main("Shards", "Could not find player " + F.name(targetName)));
}
UtilPlayer.message(caller, F.main("Shards", "Could not find player " + F.name(targetName)));
}
});
}

View File

@ -2,6 +2,7 @@ package mineplex.core.elo;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
import mineplex.core.MiniDbClientPlugin;
import mineplex.core.account.CoreClientManager;
@ -114,15 +115,15 @@ public class EloManager extends MiniDbClientPlugin<EloClientData>
}
@Override
protected EloClientData addPlayer(String player)
protected EloClientData addPlayer(UUID uuid)
{
return new EloClientData();
}
@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.loadClientInformation(resultSet));
Set(uuid, _repository.loadClientInformation(resultSet));
}
@Override

View File

@ -16,6 +16,8 @@ import mineplex.core.common.util.UtilServer;
import mineplex.core.energy.event.EnergyEvent;
import mineplex.core.energy.event.EnergyEvent.EnergyChangeReason;
import java.util.UUID;
public class Energy extends MiniClientPlugin<ClientEnergy>
{
private double _baseEnergy = 180;
@ -137,7 +139,7 @@ public class Energy extends MiniClientPlugin<ClientEnergy>
}
@Override
protected ClientEnergy addPlayer(String player)
protected ClientEnergy addPlayer(UUID uuid)
{
return new ClientEnergy();
}

View File

@ -0,0 +1,47 @@
package mineplex.core.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/*
* This event is called when the join message is about to be sent
*/
public class JoinMessageBroadcastEvent extends Event
{
private static final HandlerList HANDLERS = new HandlerList();
private Player _player;
private String _username;
public JoinMessageBroadcastEvent(Player player)
{
this._player = player;
this._username = player.getName();
}
public Player getPlayer()
{
return this._player;
}
public String getUsername()
{
return this._username;
}
public void setUsername(String username)
{
this._username = username;
}
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
}

View File

@ -17,6 +17,7 @@ import mineplex.core.common.util.UtilPlayer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;

View File

@ -2,6 +2,7 @@ package mineplex.core.facebook;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
@ -106,16 +107,16 @@ public class FacebookManager extends MiniDbClientPlugin<FacebookClient>
}
@Override
protected FacebookClient addPlayer(String player)
protected FacebookClient addPlayer(UUID uuid)
{
return new FacebookClient(false);
}
@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
{
boolean hasRow = resultSet.next();
Set(playerName, new FacebookClient(hasRow));
Set(uuid, new FacebookClient(hasRow));
}
@Override

View File

@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import mineplex.core.MiniDbClientPlugin;
import mineplex.core.account.CoreClientManager;
@ -28,6 +29,7 @@ import mineplex.core.preferences.PreferencesManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.serverdata.data.PlayerStatus;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
@ -70,7 +72,7 @@ public class FriendManager extends MiniDbClientPlugin<FriendData>
}
@Override
protected FriendData addPlayer(String player)
protected FriendData addPlayer(UUID uuid)
{
return new FriendData();
}
@ -399,10 +401,21 @@ public class FriendManager extends MiniDbClientPlugin<FriendData>
return false;
}
@Override
public void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException
public void updatePlayerStatus(String playerName, PlayerStatus status)
{
Set(playerName, _repository.loadClientInformation(resultSet));
_repository.updatePlayerStatus(playerName, status);
}
public PlayerStatus getStatus(String playerName)
{
return _repository.getStatus(playerName);
}
@Override
public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
{
Set(uuid, _repository.loadClientInformation(resultSet));
}
@Override

View File

@ -14,7 +14,6 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.util.NautHashMap;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnVarChar;
import mineplex.core.friend.FriendStatusType;
@ -183,7 +182,7 @@ public class FriendRepository extends MinecraftRepository
/**
* @param playerName - the name of the player whose current server status is being fetched
* @return the {@link MinecraftServer} name that the player matching {@code playerName}
* @return the name that the player matching {@code playerName}
* is currently online on, if they are online, null otherwise.
*/
public String fetchPlayerServer(String playerName)
@ -192,4 +191,21 @@ public class FriendRepository extends MinecraftRepository
return (status == null) ? null : status.getServer();
}
public void updatePlayerStatus(String playerName, PlayerStatus status)
{
if (status != null)
{
_repository.addElement(status, 60 * 60 * 8);
}
else
{
_repository.removeElement(playerName.toLowerCase());
}
}
public PlayerStatus getStatus(String playerName)
{
return _repository.getElement(playerName.toLowerCase());
}
}

View File

@ -54,21 +54,15 @@ public class AmmoCommand extends CommandBase<GadgetManager>
{
if (target == null)
{
_plugin.getClientManager().loadClientByName(targetName, new Runnable()
_plugin.getClientManager().loadClientByName(targetName, loadedProfile ->
{
@Override
public void run()
if (loadedProfile != null)
{
CoreClient client = _plugin.getClientManager().Get(targetName);
if (client != null)
{
addAmmo(caller, client.GetPlayer(), gadget, amount);
}
else
{
UtilPlayer.message(caller, F.main("Ammo", "Could not find player " + F.name(targetName)));
}
addAmmo(caller, loadedProfile.GetPlayer(), gadget, amount);
}
else
{
UtilPlayer.message(caller, F.main("Ammo", "Could not find player " + F.name(targetName)));
}
});
}

View File

@ -89,7 +89,7 @@ public class LockCosmeticsCommand extends CommandBase<GadgetManager>
Item clientItem = _plugin.getInventoryManager().getItem(gadget.getName());
if (clientItem == null)
continue;
_plugin.getInventoryManager().Get(caller.getName()).removeItem(new ClientItem(clientItem, 1));
_plugin.getInventoryManager().Get(caller).removeItem(new ClientItem(clientItem, 1));
removed++;
}
}
@ -108,7 +108,7 @@ public class LockCosmeticsCommand extends CommandBase<GadgetManager>
Item clientItem = _plugin.getInventoryManager().getItem(mount.getName());
if (clientItem == null)
continue;
_plugin.getInventoryManager().Get(caller.getName()).removeItem(new ClientItem(clientItem, 1));
_plugin.getInventoryManager().Get(caller).removeItem(new ClientItem(clientItem, 1));
removed++;
}
}

View File

@ -36,4 +36,12 @@ public class SongData
return false;
}
/**
* Forces this song's jukebox to revert to air
*/
public void disable()
{
Block.setType(Material.AIR);
}
}

View File

@ -45,7 +45,7 @@ public class ArrowTrailTitan extends ArrowEffectGadget
{
if (Manager.getClientManager().Get(event.getPlayer()).GetRank().has(Rank.TITAN))
{
Manager.getDonationManager().Get(event.getPlayer().getName()).AddUnknownSalesPackagesOwned(getName());
Manager.getDonationManager().Get(event.getPlayer()).AddUnknownSalesPackagesOwned(getName());
}
}
}

View File

@ -34,7 +34,7 @@ public class DeathTitan extends DeathEffectGadget
{
if (Manager.getClientManager().Get(event.getPlayer()).GetRank().has(Rank.TITAN))
{
Manager.getDonationManager().Get(event.getPlayer().getName()).AddUnknownSalesPackagesOwned(getName());
Manager.getDonationManager().Get(event.getPlayer()).AddUnknownSalesPackagesOwned(getName());
}
}

View File

@ -39,7 +39,7 @@ public class DoubleJumpTitan extends DoubleJumpEffectGadget
{
if (Manager.getClientManager().Get(event.getPlayer()).GetRank().has(Rank.TITAN))
{
Manager.getDonationManager().Get(event.getPlayer().getName()).AddUnknownSalesPackagesOwned(getName());
Manager.getDonationManager().Get(event.getPlayer()).AddUnknownSalesPackagesOwned(getName());
}
}
}

View File

@ -59,7 +59,7 @@ public class MorphBat extends MorphGadget implements IThrown
this.ApplyArmor(player, message);
DisguiseBat disguise = new DisguiseBat(player);
disguise.setName(player.getName(), Manager.getClientManager().Get(player).GetRank());
disguise.setName(player.getName(), Manager.getClientManager().Get(player).getRealOrDisguisedRank());
disguise.setCustomNameVisible(true);
Manager.getDisguiseManager().disguise(disguise);
}

View File

@ -42,7 +42,7 @@ public class MorphBlaze extends MorphGadget
this.ApplyArmor(player, message);
DisguiseBlaze disguise = new DisguiseBlaze(player);
disguise.setName(player.getName(), Manager.getClientManager().Get(player).GetRank());
disguise.setName(player.getName(), Manager.getClientManager().Get(player).getRealOrDisguisedRank());
disguise.setCustomNameVisible(true);
Manager.getDisguiseManager().disguise(disguise);
}
@ -84,7 +84,7 @@ public class MorphBlaze extends MorphGadget
{
if (Manager.getClientManager().Get(event.getPlayer()).GetRank().has(Rank.HERO))
{
Manager.getDonationManager().Get(event.getPlayer().getName()).AddUnknownSalesPackagesOwned(getName());
Manager.getDonationManager().Get(event.getPlayer()).AddUnknownSalesPackagesOwned(getName());
}
}
}

View File

@ -55,7 +55,7 @@ public class MorphBunny extends MorphGadget
this.ApplyArmor(player, message);
DisguiseRabbit disguise = new DisguiseRabbit(player);
disguise.setName(player.getName(), Manager.getClientManager().Get(player).GetRank());
disguise.setName(player.getName(), Manager.getClientManager().Get(player).getRealOrDisguisedRank());
disguise.setCustomNameVisible(true);
Manager.getDisguiseManager().disguise(disguise);
@ -136,7 +136,7 @@ public class MorphBunny extends MorphGadget
if (!UtilEvent.isAction(event, ActionType.L))
return;
if (Manager.getDonationManager().Get(player.getName()).getBalance(GlobalCurrency.TREASURE_SHARD) < 500)
if (Manager.getDonationManager().Get(player).getBalance(GlobalCurrency.TREASURE_SHARD) < 500)
{
UtilPlayer.message(player, F.main("Gadget", "You do not have enough Shards."));
return;

View File

@ -48,7 +48,7 @@ public class MorphChicken extends MorphGadget
this.ApplyArmor(player, message);
DisguiseChicken disguise = new DisguiseChicken(player);
disguise.setName(player.getName(), Manager.getClientManager().Get(player).GetRank());
disguise.setName(player.getName(), Manager.getClientManager().Get(player).getRealOrDisguisedRank());
disguise.setCustomNameVisible(true);
Manager.getDisguiseManager().disguise(disguise);
}

View File

@ -36,7 +36,7 @@ public class MorphCow extends MorphGadget
this.ApplyArmor(player, message);
DisguiseCow disguise = new DisguiseCow(player);
disguise.setName(player.getName(), Manager.getClientManager().Get(player).GetRank());
disguise.setName(player.getName(), Manager.getClientManager().Get(player).getRealOrDisguisedRank());
disguise.setCustomNameVisible(true);
Manager.getDisguiseManager().disguise(disguise);
}

View File

@ -50,7 +50,7 @@ public class MorphCreeper extends MorphGadget
this.ApplyArmor(player, message);
DisguiseCreeper disguise = new DisguiseCreeper(player);
disguise.setName(player.getName(), Manager.getClientManager().Get(player).GetRank());
disguise.setName(player.getName(), Manager.getClientManager().Get(player).getRealOrDisguisedRank());
disguise.setCustomNameVisible(true);
Manager.getDisguiseManager().disguise(disguise);
}
@ -171,7 +171,7 @@ public class MorphCreeper extends MorphGadget
{
if (Manager.getClientManager().Get(event.getPlayer()).GetRank().has(Rank.HERO))
{
Manager.getDonationManager().Get(event.getPlayer().getName()).AddUnknownSalesPackagesOwned(getName());
Manager.getDonationManager().Get(event.getPlayer()).AddUnknownSalesPackagesOwned(getName());
}
}

Some files were not shown because too many files have changed in this diff Show More