Merge remote-tracking branch 'refs/remotes/origin/develop' into feature/leveling

This commit is contained in:
Sam 2017-06-30 14:23:28 +01:00
commit 85342801a4
546 changed files with 41914 additions and 3000 deletions

View File

@ -0,0 +1,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-parent</artifactId>
<version>dev-SNAPSHOT</version>
</parent>
<artifactId>mineplex-core-common-base</artifactId>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -6,7 +6,7 @@ import org.bukkit.entity.Player;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilPlayerBase;
public enum Rank
{
@ -20,10 +20,12 @@ public enum Rank
CMOD("C.Mod", "cmod", ChatColor.GOLD, "Clans Moderators are members of the Clans Management Senior Mod team. \nTheir duties include moderation and support within the Clans servers. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 32, DyeColor.ORANGE),
EVENT_MODERATOR("Sr.Mod", "srmod_event", ChatColor.GOLD, "Senior Moderators are members of a special \nSenior Moderator team where they have to fulfill specific tasks. \nJust like Moderators, you can always ask them for help. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 44, DyeColor.ORANGE),
SNR_MODERATOR("Sr.Mod", "srmod", ChatColor.GOLD, "Senior Moderators are members of a special \nSenior Moderator team where they have to fulfill specific tasks. \nJust like Moderators, you can always ask them for help. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 44, DyeColor.ORANGE),
CMA("Mod", "mod_cma", ChatColor.GOLD, "Moderators enforce rules and provide help to \nanyone with questions or concerns. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 32, DyeColor.ORANGE),
MODERATOR("Mod", "mod", ChatColor.GOLD, "Moderators enforce rules and provide help to \nanyone with questions or concerns. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 32, DyeColor.ORANGE),
HELPER("Trainee", "train", ChatColor.GOLD, "Trainees are moderators-in-training. \nTheir duties include enforcing the rules and \nproviding help to anyone with questions or concerns. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 24, DyeColor.ORANGE),
MAPLEAD("MapLead", "mapl", ChatColor.BLUE, "Map Leaders are leaders of the Mineplex Build Team. \nThey oversee the creation of new maps and manage Builders.", 25, DyeColor.BLUE),
MAPDEV("Builder", "mapd", ChatColor.BLUE, "Builders are members of the Mineplex Build Team. \nThey create many of the maps used across Mineplex.", 26, DyeColor.BLUE),
MAPPER("Mapper", "mapp", ChatColor.BLUE, "These senior staff members work closely with \nthe development and design teams to build new \nmaps for new and old content!", 100, DyeColor.BLUE),
MAPDEV("Builder", "mapd", ChatColor.BLUE, "These creative staff members help \nbuild maps for your favorite games!", 26, DyeColor.BLUE),
MEDIA("Media", "media", ChatColor.BLUE, "The Media rank is given to talented artists who are\n endorsed to create content for Mineplex.", -1, DyeColor.BLUE),
EVENT("Event", "evnt", ChatColor.WHITE, "A member of the official Mineplex Events team!", -1, DyeColor.WHITE),
@ -120,7 +122,7 @@ public enum Rank
if (inform)
{
UtilPlayer.message(player, C.mHead + "Permissions> " +
UtilPlayerBase.message(player, C.mHead + "Permissions> " +
C.mBody + "This requires Permission Rank [" +
C.mHead + rank.Name.toUpperCase() +
C.mBody + "].");

View File

@ -0,0 +1,54 @@
package mineplex.core.common;
import java.util.Objects;
/**
* Represents an operation that accepts two input arguments and returns no
* result. This is the three-arity specialization of {@link Consumer}.
* Unlike most other functional interfaces, {@code TriConsumer} is expected
* to operate via side-effects.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #accept(Object, Object, Object)}.
*
* @param <T> the type of the first argument to the operation
* @param <U> the type of the second argument to the operation
* @param <V> the type of the third argument to the operation
*
* @see Consumer
*/
@FunctionalInterface
public interface TriConsumer<T, U, V>
{
/**
* Performs this operation on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
* @param v the third input argument
*/
void accept(T t, U u, V v);
/**
* Returns a composed {@code TriConsumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code TriConsumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default TriConsumer<T, U, V> andThen(TriConsumer<? super T, ? super U, ? super V> after)
{
Objects.requireNonNull(after);
return (f, s, t) -> {
accept(f, s, t);
after.accept(f, s, t);
};
}
}

View File

@ -4,7 +4,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map.Entry;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang.Validate;
import java.util.Set;

View File

@ -0,0 +1,38 @@
package mineplex.core.common.util;
import java.util.ArrayList;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
public class UtilBlockBase
{
public static ArrayList<Block> getSurrounding(Block block, boolean diagonals)
{
ArrayList<Block> blocks = new ArrayList<Block>();
if (diagonals)
{
for (int x = -1; x <= 1; x++)
for (int z = -1; z <= 1; z++)
for (int y = 1; y >= -1; y--)
{
if (x == 0 && y == 0 && z == 0) continue;
blocks.add(block.getRelative(x, y, z));
}
}
else
{
blocks.add(block.getRelative(BlockFace.UP));
blocks.add(block.getRelative(BlockFace.NORTH));
blocks.add(block.getRelative(BlockFace.SOUTH));
blocks.add(block.getRelative(BlockFace.EAST));
blocks.add(block.getRelative(BlockFace.WEST));
blocks.add(block.getRelative(BlockFace.DOWN));
}
return blocks;
}
}

View File

@ -54,6 +54,23 @@ public class UtilMath
return a.subtract(b).length();
}
public static double offset2dSquared(Entity a, Entity b)
{
return offset2dSquared(a.getLocation().toVector(), b.getLocation().toVector());
}
public static double offset2dSquared(Location a, Location b)
{
return offset2dSquared(a.toVector(), b.toVector());
}
public static double offset2dSquared(Vector a, Vector b)
{
a.setY(0);
b.setY(0);
return a.subtract(b).lengthSquared();
}
public static double offset(Entity a, Entity b)
{
return offset(a.getLocation().toVector(), b.getLocation().toVector());
@ -283,4 +300,36 @@ public class UtilMath
{
return n - ((int) ((int) n));
}
public static int getMax(int... ints)
{
if (ints.length < 1)
{
return -1;
}
int max = ints[0];
for (int i = 1; i < ints.length; i++)
{
max = Math.max(max, ints[i]);
}
return max;
}
public static int getMin(int... ints)
{
if (ints.length < 1)
{
return -1;
}
int min = ints[0];
for (int i = 1; i < ints.length; i++)
{
min = Math.min(min, ints[i]);
}
return min;
}
}

View File

@ -0,0 +1,97 @@
package mineplex.core.common.util;
import java.util.LinkedList;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import mineplex.core.common.events.PlayerMessageEvent;
import org.bukkit.Bukkit;
public class UtilPlayerBase
{
public static void message(Entity client, LinkedList<String> messageList)
{
message(client, messageList, false);
}
public static void message(Entity client, String message)
{
message(client, message, false);
}
public static void message(Entity client, LinkedList<String> messageList, boolean wiki)
{
for (String curMessage : messageList)
{
message(client, curMessage, wiki);
}
}
public static void message(Entity client, String message, boolean wiki)
{
if (client == null)
return;
if (!(client instanceof Player))
return;
/*
if (wiki)
message = UtilWiki.link(message);
*/
PlayerMessageEvent event = new PlayerMessageEvent((Player) client, message);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
return;
((Player) client).sendMessage(message);
}
public static Player searchOnline(Player caller, String player, boolean inform)
{
LinkedList<Player> matchList = new LinkedList<Player>();
for (Player cur : Bukkit.getOnlinePlayers())
{
if (cur.getName().equalsIgnoreCase(player))
return cur;
if (cur.getName().toLowerCase().contains(player.toLowerCase()))
matchList.add(cur);
}
// No / Non-Unique
if (matchList.size() != 1)
{
if (!inform)
return null;
// Inform
message(caller,
F.main("Online Player Search", "" + C.mCount + matchList.size() + C.mBody + " matches for [" + C.mElem
+ player + C.mBody + "]."));
if (matchList.size() > 0)
{
String matchString = "";
for (Player cur : matchList)
matchString += F.elem(cur.getName()) + ", ";
if (matchString.length() > 1)
matchString = matchString.substring(0, matchString.length() - 2);
message(caller,
F.main("Online Player Search", "" + C.mBody + "Matches [" + C.mElem + matchString + C.mBody + "]."));
}
return null;
}
return matchList.get(0);
}
}

View File

@ -6,8 +6,6 @@ import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import net.minecraft.server.v1_8_R3.MinecraftServer;
public class UtilTime
{
public static final ZoneId CENTRAL_ZONE = ZoneId.of("America/Chicago"); // This means "CST"
@ -54,15 +52,6 @@ public class UtilTime
}
}
/**
*
* @return Returns the current global server tick. Is reset on server restart. Starts out negative. Counts upwards.
*/
public static int getServerTick()
{
return MinecraftServer.currentTick;
}
/**
* Converts a {@link Timestamp} to a {@link LocalDateTime}.
* This method will only work for timestamp's stored using {@link #CENTRAL_ZONE}, if stored using

View File

@ -3,6 +3,7 @@ package mineplex.core.common.util;
import java.util.Collection;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
@ -10,19 +11,16 @@ import org.bukkit.World.Environment;
import org.bukkit.WorldBorder;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
public class UtilWorld
{
public static World getWorld(String world)
{
return UtilServer.getServer().getWorld(world);
return Bukkit.getServer().getWorld(world);
}
public static boolean areChunksEqual(Location first, Location second)
@ -100,7 +98,7 @@ public class UtilWorld
try
{
for (World cur : UtilServer.getServer().getWorlds())
for (World cur : Bukkit.getServer().getWorlds())
{
if (cur.getName().equalsIgnoreCase(parts[0]))
{
@ -154,7 +152,7 @@ public class UtilWorld
try
{
for (World cur : UtilServer.getServer().getWorlds())
for (World cur : Bukkit.getServer().getWorlds())
{
if (cur.getName().equalsIgnoreCase(tokens[0]))
{
@ -188,7 +186,7 @@ public class UtilWorld
public static World getWorldType(Environment env)
{
for (World cur : UtilServer.getServer().getWorlds())
for (World cur : Bukkit.getServer().getWorlds())
if (cur.getEnvironment() == env)
return cur;
@ -305,16 +303,4 @@ public class UtilWorld
return startX >= minX && startZ <= maxX && endX >= minZ && endZ <= maxZ;
}
public static double distanceSquared(Entity a, Entity b)
{
if (a.getWorld() != b.getWorld())
throw new IllegalArgumentException("Different worlds: " + a.getWorld().getName() + " and " + b.getWorld().getName());
net.minecraft.server.v1_8_R3.Entity entityA = ((CraftEntity) a).getHandle();
net.minecraft.server.v1_8_R3.Entity entityB = ((CraftEntity) b).getHandle();
double dx = entityA.locX - entityB.locX;
double dy = entityA.locY - entityB.locY;
double dz = entityA.locZ - entityB.locZ;
return (dx * dx) + (dy * dy) + (dz * dz);
}
}

View File

@ -20,6 +20,11 @@
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mineplex-core-common-base</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-serverdata</artifactId>

View File

@ -0,0 +1,79 @@
package mineplex.core.common.geom;
import javax.annotation.Nonnull;
import java.util.Comparator;
import org.bukkit.Location;
public class Point2D implements Comparable<Point2D>
{
private static final Comparator<Point2D> COMPARE_BY_Y_THEN_X =
Comparator.comparingDouble(Point2D::getY).thenComparingDouble(Point2D::getX);
private final double _x;
private final double _y;
private Point2D(double x, double y)
{
_x = x;
_y = y;
}
public static Point2D of(double x, double y)
{
return new Point2D(x, y);
}
public static Point2D of(Location location)
{
return new Point2D(location.getX(), location.getZ());
}
public double getX()
{
return _x;
}
public double getY()
{
return _y;
}
public Comparator<Point2D> polarOrder()
{
return (p2, p3) ->
{
double dx1 = p2._x - _x;
double dy1 = p2._y - _y;
double dx2 = p3._x - _x;
double dy2 = p3._y - _y;
if (dy1 >= 0 && dy2 < 0) return -1; // p2 above; p3 below
else if (dy2 >= 0 && dy1 < 0) return 1; // p2 below; p3 above
else if (dy1 == 0 && dy2 == 0) { // 3-collinear and horizontal
if (dx1 >= 0 && dx2 < 0) return -1; // p2 right; p3 left
else if (dx2 >= 0 && dx1 < 0) return 1; // p2 left ; p3 right
else return 0; // all the same point
}
else return -ccw(Point2D.this, p2, p3); // both above or below
};
}
public static int ccw(Point2D a, Point2D b, Point2D c) {
double area2 = (b._x-a._x)*(c._y-a._y) - (b._y-a._y)*(c._x-a._x);
if (area2 < 0) return -1;
else if (area2 > 0) return 1;
else return 0;
}
@Override
public int compareTo(@Nonnull Point2D that)
{
return COMPARE_BY_Y_THEN_X.compare(this, that);
}
@Override
public String toString()
{
return "Point2D{_x=" + _x + ",_y=" + _y + "}";
}
}

View File

@ -0,0 +1,68 @@
package mineplex.core.common.geom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
public class Polygon2D
{
private final List<Point2D> _points;
private Polygon2D(List<Point2D> points)
{
_points = points;
// Ensure points[points.size-1] = points[0]
if (!_points.get(0).equals(points.get(_points.size()-1)))
{
_points.add(points.get(0));
}
}
public boolean contains(Point2D point)
{
boolean result = false;
for (int i = 0, j = _points.size() - 1; i < _points.size(); j = i++)
{
if ((_points.get(i).getY() > point.getY()) != (_points.get(j).getY() > point.getY()) &&
(point.getX() < (_points.get(j).getX() - _points.get(i).getX()) * (point.getY() - _points.get(i).getY()) / (_points.get(j).getY() - _points.get(i).getY()) + _points.get(i).getX()))
{
result = !result;
}
}
return result;
}
public static Polygon2D fromUnorderedPoints(List<Point2D> points)
{
Stack<Point2D> hull = new Stack<>();
Collections.sort(points);
points.subList(1, points.size()).sort(points.get(0).polarOrder());
hull.push(points.get(0));
hull.push(points.get(1));
// find first extreme point (not collinear with first and second elements)
int extreme;
for (extreme = 2; extreme < points.size(); extreme++)
if (Point2D.ccw(points.get(0), points.get(1), points.get(extreme)) != 0) break;
for (int i = extreme; i < points.size(); i++)
{
Point2D top = hull.pop();
while (Point2D.ccw(hull.peek(), top, points.get(i)) <= 0) {
top = hull.pop();
}
hull.push(top);
hull.push(points.get(i));
}
return new Polygon2D(new ArrayList<>(hull));
}
public static Polygon2D fromPoints(List<Point2D> points)
{
return new Polygon2D(new ArrayList<>(points));
}
}

View File

@ -67,6 +67,17 @@ public class SkinData
public final static SkinData LEPRECHAUN = new SkinData("eyJ0aW1lc3RhbXAiOjE0ODc4NzI5Mjg1ODIsInByb2ZpbGVJZCI6IjlmY2FlZDhiMTRiNTRmN2ZhNjRjYjYwNDBlNzA1MjcyIiwicHJvZmlsZU5hbWUiOiJMQ2FzdHIxIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS80ZTBkZjZhZGNiNzkzMzM5ZjFhOGNkM2E0ZGQ2ZThjNGQ2ZWFjYmU5NWMzZDA5OTI4NDMyMWFiZGI5MTgwOSJ9fX0=", "cyIYHTdzvVBOyYoiJZTvNS8Et5pzqBNxuz6GQspE2lBkW2Bj82JNv5oczsf3oxYAG4zxdb96G8+7UKBmoJdvx0x6UD7Dk0dnKrwpXfOhe+jRxtwMGMsdYCb8URWaoIoeKpxdCmAtjgV6FI8zDy2Yzi+MF4O9e4VqH0tMBoD2/CZScQwNEzc4YXf2M2fglKn9uK2+xrgLV+XS+SNdIn7BRiNlQf96u6N2G0lO+eb09LbIfIgAgfnyLiARccWa+VNo6gwlCFyRMnwOlgqxL5XA5Um4kkx2ZReRRCDFQ4NV5eLBktLd5wpECyOuY7v7S3zLqwbhwG47gS8hnXqmtHG5RW0RUQZEryg638Cw7hwr2k09iStfok8WeZUIJ+fuUWgdArvbtN36a2pCXyFdqzp+E8xzSF4E9SQv0K+1lNj+w4L58dh8pddeKK8m5bpjINj4xZ6nf7reWYQAX/imVNYTXTW8JqYnF+++xViBwmfeeM3PmEg+wyTduh+M25nyhGcqn5l+UyQ9aMzzdNs2aEdx12fOm1sOFXjHrHWeo6ciEm7sY1SDjiJ99VVXuGHCJWBtxq/B+c+vC/Cj8itEYOetwe5NKrgI99pZjG+KiRr4L0n8/NA3Px7SbKUUpHse80pNMjGfFW4pAOyFXJaKHrObWT2iL2AnTe+yfdY4sf/JZT4=");
public final static SkinData BUGS_BUNNY = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTA0NzE5MDU2MTgsInByb2ZpbGVJZCI6IjlmY2FlZDhiMTRiNTRmN2ZhNjRjYjYwNDBlNzA1MjcyIiwicHJvZmlsZU5hbWUiOiJMQ2FzdHIxIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS84MmUyMjRkMGJkZGJmNjRiODIzMmUxNWRhNGRkN2NjN2NiYTYzM2NiODkyMTFhYjVjNDRhODU0ZjM1NDhlZWRiIn19fQ==", "QtM7YGNpqGcTnlUCTtQsQIEc8VGvL8cxWzAvN4LjYZrY4Fv15ysEVSPWPmRL/FJTRyUFCrJFO/0miVbuIEsGyUnsgHJAr9qkeyMvfD3+pZtKU1FkS58VNQkL/YaPDms7XPy1BPNo+ynQnVevdVCNDOvs2244Px3UljtuReBteKqL8QGMR1K6FFCQuKKvcvYsljdM8RV91r2yuT9UDxnzMRghWyRZuthvCeGL85g1LQxCnzJ0NUqIqCDrTWa8jeuncLnmRooKZYGsQjCAVOSFRk4KytD+fv8xgNK2igqBgVcqAINl5IjrFt7yyPQ2FVBbshETsjewusa6eZSBoy1Lc17G7bcndoOdwGMuztLjHPMzxFpIV1RkbZrngjcSTE/IQdSw79NlzMOEMKjE/34M7xcSnSZA1xwW33g+/xq+pNbqcXu85e7VXkziWDhHREp9ITT4YjrVdrss1yfYBzZgRmmLyaMpVmVsecKB9adpuZkhGzKIVrQHDGYEHoqoRnsRGJREdZQPxaSWp4+DSxpV/0oJXJWDz+XFztbcVbBcjBOD9kpFP0s+R5t1WA2B+jsf9J3LdsUUDbBiWikBwbAXKhHxTWWKv6OZLZovhgvGnW2lXQsHglEKuD7jE/mnFj4SF2qRO2N37AUjaG8AGQtTVhxW5JneIiBA0dbKIk06yoY=");
public final static SkinData SLENDERMAN = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTA0NzUyNzk4NTUsInByb2ZpbGVJZCI6IjlmY2FlZDhiMTRiNTRmN2ZhNjRjYjYwNDBlNzA1MjcyIiwicHJvZmlsZU5hbWUiOiJMQ2FzdHIxIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9hMWNkOTI5OTFmYTRjZGQ2MGVlZDNhZTM3ZmI5NWRmZjFkNWNkOGNiZmYwYWFjMzE4MmQ0ODU2NDU5NTIzYyJ9fX0=", "OVqWFLCekyZcdGli6kPBKNh8/VYPhKZGNqlAvSOKc3RLgh4pIkI6TDPr/Y+VQdhz1wZozARFYSeoDJJJ4nZTi7gi3rVPG2rL1ZnKo7so5hdT8caEzSTRmgwPKzo03ZhEEsW9AEJo9mpiUxGSJdBlgEb9UgodpYFW1IjRC09CcBUqzRWP8QGZTSFSN5x9emQ97DyiFmt0NFWubHCKHdb7CExhchPRtbahL3hOEzPY8/Y+Irl9OZjx7jONE7O/sYItCuZoXc3FaTgCV0riiXHCgH2eA54s5TQVWumtp3FU7VIcKR6pm/o61+GusvqhNgdFNk9XSHWMUyp+HNU0R8sConZQN/eaVx9laJmUUb4zNZ7hX/hLYV+r9LFU1NXOeIZWJPShD+bYfZgEorIpD+EAL4BHht/f5e6a1IZUDBWb001PFibby2t9WWjoDVKz4McbxZ2Xui7EHKFG1K3biPibhWx6fvnOeJ2xW6UDIZcD+TCXwlW/knkFt44Xpyv3oNHk3UNkyrQgghd6qkc3gZHxP8PQCNvKIyK1I+pHR6JMZvSStp7ZQRDpvsvIUyOJvq+7Bs7lFYs8hcJHMzEB+8PYlH2k7P7iLuA6ZYFUmvOW1LLq0+hvxK96ZdNEsJdmMkVVTZBRw7vsZ4GPbkdp2cMOFH2lHcQj80xKqVbd43IqFDA=");
public final static SkinData BOB_ROSS = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTU2NjEyOTc2NTcsInByb2ZpbGVJZCI6IjdkYTJhYjNhOTNjYTQ4ZWU4MzA0OGFmYzNiODBlNjhlIiwicHJvZmlsZU5hbWUiOiJHb2xkYXBmZWwiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzVhNzZhN2NlMzZlZGRiYmZhNWMzMmJhZmVhYmUyNmQ3ZWJlNWRlOTBkNzYyYzJmNWY3OTQ1ZTQ1ODUxOTU2ZDYifX19", "b7pUQSZ1UkMZJNSqdaBPGWfm+rfvFkEh58pBvYTG2RBPwVju1kKinb1LfsyYhFKlyPvL1jfqi30udmb0302QvE0SKg7p3txxULa3Hr94+eCJWFxrOxUNorRT9E+TurJxH6jimu6KW1p6goPn77/kgNaWb9xn3+E84+vH0z9ETjgc5G0aYLT+cSzThUorhvOQ7DRLfRgSWiFxfm3Er0g+waLfDEeNNAd6OJ5k3X+kgM/+V6QTIFofnZZ6NdZZInTARAVol2H0pRfQfAuVYfJyVyvA0uF+ZX+wlMuBTG1MeyWjZgI1iUKmGaQADXsAV796kT+Z+tAXpbRYYYZnxil5jx5P4druiHvaQfV2KK3lbKm2uH9M3SZr5d57C3V24BKRRWGS4C9INzgO8ORIIomes7kp0gECS4MnSMI6hcl0JsXVlaAy88BgmT/PKxM+3q4PCQE1N9fTCuhoil7vVYIU3uBXwFUE7NTAOUdBee+3TtMstIu2WP8rtEZBVpGH9CmomaLTCzPZSdXGY31goOFXSRYMNi8j4ykuBgP0qJqimipWH0rBF1bMdHqMu359h62tTLRKipHWXPxj4N8c/n1CVPYjuXH9X3f1HAU4DnET+v93Vb/uzbx8rXFrz6jLPwAjSlJ8Th3VE+4ey/ZBHWPB+SuHetN+e0r/LYxiqwwlnwI=");
public static final SkinData HATTORI = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjEyMTczMDgsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS83MjczMTBiMzlhMTIzOWI3ZTI4Y2JjNTkzMWY1MzlkNGVlNmQxOTc3ODhjNWI1YTY3YWY1NDJlYzk0MmZkMyJ9fX0=", "aHfFqPOZmcQkUqFPjVa27h27k5gyvkZMCOyIaIdIZfqVDg/69/hakkDQazvKg/U8KTlYaDSRyOp9ZD5qOUSCPvRtRDMhuX/Tn68KD9BdW5jYKsXo0puOa7IJDKAE47z7YQ8AvfOtxuOAg6S0ihjYEQqRA56UQ+gPbkd+pxpMxvXoLyAx7IEIKWmlkibG/rmaX8J7OEgq8Wi9s6BhtPVNMaLoznzdzOiiYkcza/zEG5zMXnj/hFHHUpWrYff0Oj7/SUB+krLsiMficASzzs/9HZq81V0ketqUhJYX66HL8F5fQniP8kYu9LbNNcVJmtlER03QaEqP/H8udemlVskFkOYLkTmhxfSetL46N+ZVf0Sxp2xYcFOH3djH/Q26IIXtzEqVyUW5Gun/ZJp8B8zYMOXbXSmaALAYPoX9cs91ZilNX/W7zn7b5Kb9kUBGt58eUpKoXjgK7rSvmH0X2JOZGFVji5QKzp/eOQAqMhkBOU8sEm9AT6mfZjjlyIDOZxSX6hjEJXRVVzFFlzTiRPTcAtaHWRnlRFywsDDSgVBGvQMPNMNa6CFeo0ajnhmfHWa4Ga77kpfQ75PzOoJ/j6Z/2sSIHfQFWE6INAGAyypX/x0Fd/AH6SmYfilnX6lhtd7OsDlxS01QGoRLPBh/ol+wY6rHSM1N6Qta0ulpQZLYIms=");
public static final SkinData ANATH = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0Njg4NjM4MTYsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS81NGI5NGQ4NzE5ZWFhYjc0YjVhMzhjN2Q5NDliM2FkMmIyYzA0ODIxZGY4OWM1ZDA0YjY5ZjNjZmExYmJhNjUifX19", "IKlnXzQ2k57XyTHge5V2ttnV1AqbRKrV0JktZS4+nLXx+ROM77/HRuf3/bYTqg48SB8npXy+c6nLYTCY1fTZOl3t2puS6BpZMBXuTV//A0OMQ1pJKzDb8vW6CwPYw2Nu6o0QX3J/FeUIaBj16GZAPxXOtSekkeOw9qsdh57GyqSmzODlEA/7CnJWqX2Ani5DACzo6j5rzfsz2qRgOzVlnbVlVzpXicRuYYLxKvT4nMS+B3HpQdsyFKAx8nTO/GmCHDzW97jck6w/VDlW9x+J39tPDEaKPLbDz1YV59yJt6hjNAcnwgbf3KvHSAbGZNLqRegq/Rk20ZI2J5GYT5ipiyf+p8rHfkRTxIsVCMyVecnSKaz59YQ7AleiWVGzYHDETU702UyigAZFHGHQ/0Kj9UyyZ4ew228FQuGo7iGY4dS/PKq40d1v3fq+czwBhcXR+Msi1Zqg/4dTh+QwwwWsIS3CKtOInpJgZ3U/tkn4STB3o+oKBbmBWvpJk8SrA6DVKKJMjHQig+67hXKSbdcRUWAoGc/iuRhRXgILkC99Ot4PHohEbwbEW8MsKxm49OFqzP4zptaUaiQpMK4YCxENhLrI7X+w51tt2XTjroIHu4oLYS4pG16ZnhUmd/RFg8Ar7mBVOv/2lUtOO5aMAv88CpyD+XXNcCQB4G5pv4c0F14=");
public static final SkinData DEVON = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0Njk0NDE1MDYsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS85N2FkNjY1MjFmNzNjOWFmYzE4MzliZGExYzE5ZDNkMjg3YjNmMjRmY2EwZTBlMTE1NzhiOTE0ZTNiNWIwZDIifX19", "BNIc7N3SGIXOEUKFe3hrQp4YmniPxkiL5aKAUNkTmYqbygAQlrCCrwJTuK6JrzkWmD5AzMSzMDKkmoMWOikgulhSmDyC88lQz/LQH3co7WldPHaPL6kk27ZirmIIZEm5WKcvWhQ7ChNWQd2KsZuFqxZSdLSQmsbujF9vpuVbhlU4hajsUwbdiOJRZ18fOAFoJYq/g3RlvqC9VtAA/IAAN7jIpXf9Pn5+vjLqN+AdKm27YknCpqMtBfkYaIhMrpTBe2gP+o50TmH0xm0IZPCS+ORYNGwFdCsg6DzEU7a0rtcUdcZgdInc09mS8tMY9eeMAISYYq5MpyliHQ/areGKk0RJEYg7muc9r/N6vBUpxZtZH8BioDj2dNj4JOoH/58cwU3+hv/Woykc9o5NUPyz0nndiOtTUp1SaDXleKyHryoYnIkPyaDPyuA7qTbIKZQHxyAdrRsnknb0PYku6T8RA4kWNK2jlOH+R9D4eiKFcbLRU2Zl6L57lJTZFFI6GUvzDsyD/vBb59gjvXYzRmvguX9CHUc1aLDeUKhV8NFXeaonoYM9VPIUBQRWNdMery9OlBiQvg4VXy1w2yKLvlHRhJZJpDm/IDdsfg27o8+BUOZ0xHF9iXPBDkOiLXXZ02X4IonLcopVNImCMRZJ1dKHwgu9qnFqVTEKH4mwXUz2Zq8=");
public static final SkinData DANA = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjkyMzgxMDAsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9hOWRhYTg5OGVkN2E0N2YyOGFkMjVmNjk5Y2Y4MzQyODFmMTVkZTY5OWM1MWVhMTRkOWRlYzVhM2VlNzY1MiJ9fX0=", "KUI3h0MDUNWQ3avjozkw0KnZf1UAMkRHzRKY9yGS/iUh9EMmDbfLcRfBhUvR5Dd6//75Yw2tElBrvPx+VqfJk0LqMACQc71n0lDY1NzqnXbpf6vNGyuhyumjhMSjJTG3BJ8Qtdd1yCsPK2x5ym+cGPS1FevJj4Vcu6rxg9HXZokgfjD11NXEwulFuPIiWHpJlnd8NlBw4a3txlrVwDnaHo7GqYSJeM1uOCrdICdpThSA2N2mOUEmOHvH9rHUhQvkKHipbsQMIxIX4oiXDWeK6P/GtT+Iv0DIeJfQdDkhDiIG5/zUyxmpC2mma1FQIsFsQOaJfgYZLfcOXGdhwlL/OcZ9ULBIKhgSx7Ozwzsc+JKonqlaBOuaietq5z/XvMClgFG9U2a1LXc5BIgaN/ClsO0uTksuoA8H0SDx9k3EmOjaPdrJOsQ/fgWQSkWN2XniLLFiEtSOEOI58vw6ORVXDgjbP+TqD0b6/d10z0jUzS2FD7AO51LHzTw+BjqoyVef4fszNNSqMi5QEgfBl++EAolZBAMHgN7hq6k52ry2LPlO5L8sm6NoZ4DrLyrx1oFNtXZZgYvNVy7rtEpIDdQczwAZkJFV0fuz8tRH3CkW/roA5HbfX3Fv19mQoteoemrSUrOwLlQsyVPxsFsn8uX94Cw88Q5KgBCGmGY2vpXHuiI=");
public static final SkinData BARDOLF = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjkxMTE4NjEsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS84MjUxNjZmNzc0ZjcyNmZmMDE3NTQ3OTk0NDc0MGYxNjRmMTZmYmI2M2I3NGI3NmNmNzk0NDMxZGZkNzUyIn19fQ==", "W8TO4M/IQ4rQ91627EaudboKwR8TuKTp5mAYOCyOJLCD0vyyEJmnZFy1Hv9HlXKiXsEm9iC36+cmQ8JfSE0JlIfU2vRH5qbXUL4HUHZi20SHVA5YKM2ztxI9uouc14ctv8pxlhT/huKxYNgB/eJR+ckT1gyc78RBoJj5YLwUTsptO87KE/vFg9hbHVo5lVSdk//jhfDsMRyf0RXp/wKZ1KGxaRA5hWQUc86mLJTiQU1EBVh3Lfb2zUq2w/gpLCoxdwiX8KnNuX1a1iC8pFCZm4VJ20yvNPaIgzFYDFfNQO6Vwv9fcLsdxVH819cEkjxg5do9MpZBj1OVmaWnTmQ4w4r3iKFzL6LMae4eOEyA/vJ8e7mbWUNrxM3+EPUPlxpG/NKr2VsR2ihIIF9GTduBZa2ayj7BJAkL9UK5PEGh/UxG6jf0YS7RjQ9ROaRgmTLMFsOVnQlFlp2UFRTe+heh/woD8/QSpd9MELdWFzeKRAlo7+hvo5AfWyjBI/3e9PIJfCXp+nF3Z92HKoR5V0m9QoYu2WGzbkhU49DJF7n+Bnd3ur0qefHFVl3USdVU2DJLcdcKU+Qn5G6E8NSy/3TVkjDg6u/o38b203b0tUBZNftAYYmCCpx/HVMEoNC03orIBPrwGYD6g//RC1TZ2ZxkLDU4QxeaM6neWq1xryXbvS4=");
public static final SkinData BARDOLF_WEREWOLF = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjkxODMxOTAsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9kNzc0ZGY3OWU1OGFiNDQ5OGQ2YzY3ZTdlMjY2NWFjZmE2OTViOWNjOWNkZTE1MmQ3ZTVlM2NjMTUyNzM5In19fQ==", "nqc7IdRVa2RF2SZXRli/HVhw7q5NfY7rnZFWbDyzjQ90Y/H6NWhb+9gwDDdnh7B1WolyptyUnukzTOQmrAcSecVO5vblhCTYY8PEOfcwUKznjpCmL/BgXdzBoYJHs43HFbtvzt3yhshcQ8Wvh7mtdmNu0MEYKbIX7lTqcfSoUbDk+A1PZDINuOF5RM8disGCrkq6WTdLij+k7pd3e7MJhtf8vJbtSoo5TjfzyzJyFvEvZqa+3lxobbPA9Z4cels0DVWVU8I/FEJhB29aSVXDVAZps3vWUr1sLMM9+PRaZdxHPZfNHx6q9R3oHXgjAlqzJwkljtJGExyOV+vOHEUuxrytdwMcW0XGjalukHVJ1A9DCgNMZqAXEbfYKk+BsN2BzOwT/+dtGfsOU+Rq7Kzp1/iit9saQy1QEG8Bynj6A2Vmg9XZsvbYsXZXsE+qNG6TOADEV0yrS9icEhLhOnO0re/+wE4Zsd5WDF51e87+ugvoH3iM4zrzvaWQb6McgxD/wlYlJyVHD+2f5VYCIw2yacNXp6LaZuXpfQyyDCqpHAosTYNLxWwjinl05C/TprQw+sZoLHFCGbVFQjTPEkDhQzG73PHecnO5Px3USBVleDoTb1kZfq6J2wJ1B1/7MTBW21Din3j2DmmuAVUNJYe6kifaNOhY1ghG2WVRNdIf1b4=");
public static final SkinData LARISSA = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjE0MTUxMzQsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jYThjNDRhOWVmZTY3NzExMDYzMjM5ODEwNDRmOTdjYmM1OWJmZmRlOGI1ODdlMGQzMWE4N2ViMDhhMmExZiJ9fX0=", "Lyac51CrnMK/CI2dWgGQLowAm/ZnQMpf0Ict/gqVrUgJVlGWDIVG77Rd1JyMQDEeESvTmoyivH+usiO0ePW95qjisqT3R43YEmLi85CqctGYqLKeSYpGYwYRz8Euw57LwJAALKOMLhVc2s4h2Or9nTecunG8KSmkCuZc4H1qh3frU+ltuV4HLqgdFUULbIHTggyvqiINov2tBqkkXeEjT7sOcTJCJNgNYU2O7//qg5kJmhso2CKHlRLpmy9LsaUK/Z+BzUmoRbwQgSwr3mz7dFAdlVWWKvKNcgX3nt1et0DIig3JKYmrnQX2Fprg+kWcr3nuizzLgjVwAlADC48P3DN0s/VBty2AYoWie16VNPIM+CV4BF2JRQ34GxZ8XceXbCKURrOjoCBgLGHvIhRW35eicoh26xp3/mwLvk5anPi5StJ/qEuzWJALeWcNbLsnt21m2MZp9h/MxaY6ftWOTzjTr5CYVd/teJyscMnGK4+lcV1dlt12lhbDMv6I+iz8iG9NIzuW5OvGkax90dA/Gq+Cd9FXVThPY4ufxWttHcTqgPB64GfMn6rywRm1B0eO1pJpYc/KlJZlW/PuaO8L1assyJs5KkOypBSy3zc6TO6pzgeOZv+VpQfA/UWpogv6ofmTpgdtwpjLFGSzIKTDXvF6FftALKVlYypG0fYbssA=");
public static final SkinData ROWENA = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0Njk1MTcxOTgsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jNDY1OGExODY4YzNhNjhhZWVhZmZkOTUxZDQyYmZkN2QxYTRjNGZjNDJjZDI2YTlmYzhkNTNmOTkxMTM1ZCJ9fX0=", "OqXMyH9SMmQ/Pwmb21In29YnCxbsN6yqUxfudN6KNgDwRUK6y072XhW6TIoTh9JQLAUKftpeVB53tk0LxHIxnsuBMrIHvETPDQFysIc/6xq3ABogs+zqFzcp5jk6S73HiD78JxLq5pzfUzhgDPMPuZP5Q/u2q1rYbe6B9lVEJ5sUcxBLUTossgucoR4qXYAlWVQdHRhq85Ol8a+OU7ruw3HackNGto6wt6u2MigCtiHVTt9XhJ/AJE4ScodQ3XwW4L6urpl/lV2OMCsr3mCjjjEz2EMhDbCWxrAorQ9aPpMbDkHBS+4TC1tbMGUlKhj5n+EZBYVaeLr4NGPACPSdT35p/2Zra49+DXn9Xn+681yNEB0ghTdsnsgwXg76+HVPHPqRHQMuTBQGQyGZaaTX/zE0tFjH+osMElLdb8dmz3dC7kQA4A13B2phj3YbMSF1FoU4GvnPKIQn6JIuEd6hd+pRLUW7Y+mgYIHHX1FT0ihrXAyVO6lQQ6rs92gSQr7sxC7tnhPSMFcmh7OcJYcbRpn97GMubthPLanOhVy7CKqjmwIkEVtYgP28idigKwNJ+sJuUONrOu7nMKl1UTD5EEapOacc/np6UhdSw8yW+LnWD/x9ueYz9ksnyRrJgcOa41izo/WCbjPK/j3JVezr9Q3x1yveWuFmdl7CGYdXngw=");
public static final SkinData BIFF = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjEzMDQzNjYsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9mOWMyMTE3ZDY0ZWE0ZmUxMWZiY2NhZmE2YzU5YzhlZjY3NDVkZjVkMTZjM2QwMmI4NmI2OTlmZWJjNTA0OGI1In19fQ==", "mJMpEvQ4A02z0S/chgLm5bKrrrd+zmp7A0012AB7b3KlyIHoLKEDDz+ZJgJtvN6skOqed3P+yNVqkxitugXaZZP8Af9J+/TseHn+vOy6CTK5tykRSY3Zb8Zmw1kn36v/SARAVtDIHD53yuPgJayYSAbVB7aknj1Q8XBQGUmZRMRxWWxeD7rQTOwgRYI4YJeKFf4UL9i6zxvOJuHsOAouJ7scu7VohG8vgR77Js/Z8rSu8/aSG+O9AQdzP6h9ixYNFkkQOHm7DseK/5tsWKHM4FYBgjIDKt3ApQokSbhThzGB55BA1qjXZkfCoOb13y1nOMC8WoIL6Ees1qzxG3VloGx2WAZLh+Q+/irwrFDMxk1zeU5fIRuj1c/UIM2HKdxxWgoRdrZ8ww/Jrll6maiOBx7geMn/0aOUbJ2U7gkTif6RG6YNS5YN9ZQDLh72l/akJMxF3SlmuAPmLs2kBghQ6eD2YQKuxWR/Hf1yS1YXtogFVNsGnzC1nda7F48EGL3zI+kCajbDlAGQ32aRt0btbEQ+Gj575kir3Aa53qiZ0YOIYQlhgZdOsTN2NE2s8uuy/15Rgc6K3ydgEmSZfdqyMyW0Dy7pE5TfVL8DumKRVRXdOceT5WfnW7MyqSmdorP5ab1fw2wLOnAVzhJmW8oXXNSs77WJ1/PURclxOWB4IF8=");
// Comments this out for now, so it doesn't load the player profile
// A better way to do this would check for the properties when getting the skull or the skin

View File

@ -378,7 +378,45 @@ public class UtilBlock
{
return fullSolid.contains(block);
}
/**
* Determines whether a block is a bottom slab.
*
* @param block The block object.
*
* @return <code>true</code> if block is a bottom slab.
*/
public static boolean bottomSlab(Block block)
{
return bottomSlab(block.getType().getId(), block.getData());
}
/**
* Determines whether a block is a bottom slab.
*
* @param block The block id
* @param data The block data
*
* @return <code>true</code> if block is a bottom slab.
*/
public static boolean bottomSlab(int block, byte data)
{
switch (block)
{
case 44:
if (data >= 0 && data <= 7) return true;
break;
case 182:
if (data == 0) return true;
break;
case 126:
if (data >= 0 && data <= 5) return true;
break;
}
return false;
}
public static boolean usable(Block block)
{
if (block == null) return false;
@ -577,30 +615,7 @@ public class UtilBlock
public static ArrayList<Block> getSurrounding(Block block, boolean diagonals)
{
ArrayList<Block> blocks = new ArrayList<Block>();
if (diagonals)
{
for (int x = -1; x <= 1; x++)
for (int z = -1; z <= 1; z++)
for (int y = 1; y >= -1; y--)
{
if (x == 0 && y == 0 && z == 0) continue;
blocks.add(block.getRelative(x, y, z));
}
}
else
{
blocks.add(block.getRelative(BlockFace.UP));
blocks.add(block.getRelative(BlockFace.NORTH));
blocks.add(block.getRelative(BlockFace.SOUTH));
blocks.add(block.getRelative(BlockFace.EAST));
blocks.add(block.getRelative(BlockFace.WEST));
blocks.add(block.getRelative(BlockFace.DOWN));
}
return blocks;
return UtilBlockBase.getSurrounding(block, diagonals);
}
public static boolean isVisible(Block block)

View File

@ -1032,7 +1032,12 @@ public class UtilEnt
return null;
}
return entity.getMetadata(key).get(0);
return entity.getMetadata(key).get(0).value();
}
public static void removeMetadata(Entity entity, String key)
{
entity.removeMetadata(key, UtilServer.getPlugin());
}
public static void SetItemInHand(LivingEntity entity, ItemStack item)

View File

@ -1158,6 +1158,16 @@ public class UtilItem
return i;
}
public static boolean isUnbreakable(ItemStack i)
{
if (i == null)
{
return false;
}
return i.getItemMeta().spigot().isUnbreakable();
}
/**
*

View File

@ -258,11 +258,9 @@ public class UtilParticle
}
}
PacketPlayOutWorldParticles packet = new PacketPlayOutWorldParticles(particleType.particle, displayFar,
return new PacketPlayOutWorldParticles(particleType.particle, displayFar,
(float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed,
count, details);
return packet;
}
public static void PlayParticle(ParticleType type, Location location, float offsetX, float offsetY,

View File

@ -348,42 +348,22 @@ public class UtilPlayer
public static void message(Entity client, LinkedList<String> messageList)
{
message(client, messageList, false);
UtilPlayerBase.message(client, messageList);
}
public static void message(Entity client, String message)
{
message(client, message, false);
UtilPlayerBase.message(client, message);
}
public static void message(Entity client, LinkedList<String> messageList, boolean wiki)
{
for (String curMessage : messageList)
{
message(client, curMessage, wiki);
}
UtilPlayerBase.message(client, messageList, wiki);
}
public static void message(Entity client, String message, boolean wiki)
{
if (client == null)
return;
if (!(client instanceof Player))
return;
/*
if (wiki)
message = UtilWiki.link(message);
*/
PlayerMessageEvent event = UtilServer.CallEvent(new PlayerMessageEvent((Player) client, message));
if (event.isCancelled())
return;
((Player) client).sendMessage(message);
UtilPlayerBase.message(client, message, wiki);
}
public static Player searchExact(String name)
@ -454,44 +434,7 @@ public class UtilPlayer
public static Player searchOnline(Player caller, String player, boolean inform)
{
LinkedList<Player> matchList = new LinkedList<Player>();
for (Player cur : UtilServer.getPlayers())
{
if (cur.getName().equalsIgnoreCase(player))
return cur;
if (cur.getName().toLowerCase().contains(player.toLowerCase()))
matchList.add(cur);
}
// No / Non-Unique
if (matchList.size() != 1)
{
if (!inform)
return null;
// Inform
message(caller,
F.main("Online Player Search", "" + C.mCount + matchList.size() + C.mBody + " matches for [" + C.mElem
+ player + C.mBody + "]."));
if (matchList.size() > 0)
{
String matchString = "";
for (Player cur : matchList)
matchString += F.elem(cur.getName()) + ", ";
if (matchString.length() > 1)
matchString = matchString.substring(0, matchString.length() - 2);
message(caller,
F.main("Online Player Search", "" + C.mBody + "Matches [" + C.mElem + matchString + C.mBody + "]."));
}
return null;
}
return matchList.get(0);
return UtilPlayerBase.searchOnline(caller, player, inform);
}
public static void searchOffline(List<String> matches, final Callback<String> callback, final Player caller,
@ -595,8 +538,13 @@ public class UtilPlayer
return nearbyMap;
}
public static Player getClosest(Location loc, Collection<Player> ignore)
{
return getClosest(loc, -1, ignore);
}
public static Player getClosest(Location loc, double maxDist, Collection<Player> ignore)
{
Player best = null;
double bestDist = 0;
@ -613,6 +561,11 @@ public class UtilPlayer
continue;
double dist = UtilMath.offset(cur.getLocation(), loc);
if (maxDist > 0 && dist > maxDist)
{
continue;
}
if (best == null || dist < bestDist)
{
@ -623,8 +576,13 @@ public class UtilPlayer
return best;
}
public static Player getClosest(Location loc, Entity... ignore)
{
return getClosest(loc, -1, ignore);
}
public static Player getClosest(Location loc, double maxDist, Entity... ignore)
{
Player best = null;
double bestDist = 0;
@ -655,6 +613,11 @@ public class UtilPlayer
}
double dist = UtilMath.offset(cur.getLocation(), loc);
if (maxDist > 0 && dist > maxDist)
{
continue;
}
if (best == null || dist < bestDist)
{

View File

@ -31,10 +31,16 @@ public class LineParticle
private double _maxRange;
private Set<Material> _ignoredTypes;
private boolean _ignoreAllBlocks;
private ParticleType _particleType;
private Player[] _toDisplay;
public LineParticle(Location start, Vector direction, double incrementedRange, double maxRange, ParticleType particleType, Player... toDisplay)
{
this(start, null, direction, incrementedRange, maxRange, null, particleType, toDisplay);
}
public LineParticle(Location start, Vector direction, double incrementedRange, double maxRange, Set<Material> ignoredTypes, ParticleType particleType, Player... toDisplay)
{
this(start, null, direction, incrementedRange, maxRange, ignoredTypes, particleType, toDisplay);
@ -73,7 +79,7 @@ public class LineParticle
Location newTarget = _start.clone().add(new Vector(0, 0.2, 0)).add(_direction.clone().multiply(_curRange));
_lastLocation = newTarget;
if (!(UtilBlock.airFoliage(newTarget.getBlock()) || UtilBlock.airFoliage(newTarget.getBlock().getRelative(BlockFace.UP))))
if (!_ignoreAllBlocks && (!(UtilBlock.airFoliage(newTarget.getBlock()) || UtilBlock.airFoliage(newTarget.getBlock().getRelative(BlockFace.UP)))))
{
if (_ignoredTypes == null || !_ignoredTypes.contains(newTarget.getBlock().getType()))
{
@ -87,7 +93,12 @@ public class LineParticle
return done;
}
public void setIgnoreAllBlocks(boolean b)
{
_ignoreAllBlocks = b;
}
public Location getLastLocation()
{
return _lastLocation;

View File

@ -32,6 +32,11 @@
<artifactId>mineplex-serverdata</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mineplex-questmanager</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>

View File

@ -1,104 +0,0 @@
package mineplex.core;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import sun.net.www.protocol.http.HttpURLConnection;
import javax.net.ssl.HttpsURLConnection;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
@ReflectivelyCreateMiniPlugin
public class TimingsFix extends MiniPlugin
{
private static final Gson GSON = new Gson();
private TimingsFix()
{
super("Timings Fix");
URL.setURLStreamHandlerFactory(protocol ->
{
if (protocol.equals("http"))
{
return new sun.net.www.protocol.http.Handler()
{
@Override
protected URLConnection openConnection(URL u) throws IOException
{
if (u.getHost().contains("paste.ubuntu.com"))
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);
return new HttpURLConnection(u, null, this)
{
@Override
public OutputStream getOutputStream()
{
return baos;
}
@Override
public InputStream getInputStream()
{
return bais;
}
@Override
public String getHeaderField(String name)
{
if (name.equals("Location"))
{
try
{
String request = new String(baos.toByteArray(), StandardCharsets.UTF_8);
request = request.substring("poster=Spigot&syntax=text&content=".length());
request = URLDecoder.decode(request, "UTF-8");
URL url = new URL("https://timings.spigotmc.org/paste");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setInstanceFollowRedirects(false);
connection.getOutputStream().write(request.getBytes(StandardCharsets.UTF_8));
connection.getOutputStream().close();
JsonObject object = GSON.fromJson(new InputStreamReader(connection.getInputStream()), JsonObject.class);
return "http://paste.ubuntu.com/" + object.get("key").getAsString() + "/";
}
catch (Throwable e)
{
e.printStackTrace();
return "http://paste.ubuntu.com/0/";
}
}
return null;
}
};
}
return super.openConnection(u);
}
@Override
protected URLConnection openConnection(URL u, Proxy p) throws IOException
{
return super.openConnection(u, p);
}
};
}
return null;
});
}
}

View File

@ -31,6 +31,7 @@ import com.google.common.collect.Sets;
import com.google.gson.Gson;
import mineplex.cache.player.PlayerCache;
import mineplex.cache.player.PlayerInfo;
import mineplex.core.MiniPlugin;
import mineplex.core.account.command.TestRank;
import mineplex.core.account.command.UpdateRank;
@ -175,7 +176,7 @@ public class CoreClientManager extends MiniPlugin
}
/**
* Get the databse account id for a player. Requires the player is online
* Get the database account id for a player. Requires the player is online
*
* @param player
* @return
@ -260,6 +261,53 @@ public class CoreClientManager extends MiniPlugin
loadClientByName(playerName, client -> runnable.run());
}
public void loadClientByUUID(UUID uuid, Consumer<CoreClient> loadedClient)
{
runAsync(() ->
{
AtomicReference<CoreClient> loaded = new AtomicReference<>();
try
{
Gson gson = new Gson();
String response = _repository.getClientByUUID(uuid);
ClientToken token = gson.fromJson(response, ClientToken.class);
if (token.Name == null || token.Rank == null)
{
loaded.set(null);
return;
}
CoreClient client = Add(token.Name, uuid);
client.SetRank(Rank.valueOf(token.Rank), false);
client.setAccountId(_repository.login(_loginProcessors, uuid, client.getName()));
Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
if (client.getAccountId() > 0)
{
PlayerInfo playerInfo = PlayerCache.getInstance().getPlayer(uuid);
if (playerInfo != null)
{
PlayerCache.getInstance().updateAccountId(uuid, client.getAccountId());
}
}
loaded.set(client);
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
UtilTasks.onMainThread(() -> loadedClient.accept(loaded.get())).run();
}
});
}
public void loadClientByName(String playerName, Consumer<CoreClient> loadedClient)
{
runAsync(() ->

View File

@ -64,7 +64,7 @@ public class TestRank extends CommandBase<CoreClientManager>
UtilPlayer.message(caller, F.main(Plugin.getName(), ChatColor.RED + "" + ChatColor.BOLD + "Invalid rank!"));
return;
}
if (Plugin.Get(caller).GetRank(true) == Rank.SNR_MODERATOR)
if (!Plugin.Get(caller).GetRank(true).has(Rank.JNR_DEV))
{
if (tempRank.has(Rank.TWITCH))
{

View File

@ -413,8 +413,8 @@ public enum Achievement
new String[]{"Earn Kill Streak Rewards"},
new int[][]{new int[]{0, 50, 500}, new int[]{0, 100, 750}, new int[]{0, 150, 1000}, new int[]{0, 200, 1500}, new int[]{0, 400, 2000}, new int[]{0, 500, 2500}, new int[]{0, 1000, 3000}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4000}, new int[]{0, 5000, 100000}},
new int[]{10, 20, 50, 100, 200, 250, 500, 750, 1000, 2000},
"Novice I",
new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
"Initiate",
new String[]{"Novice I", "Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
AchievementCategory.CASTLE_ASSAULT),
CASTLE_ASSAULT_FIRST_BLOOD("First Blood", 0,
@ -422,8 +422,8 @@ public enum Achievement
new String[]{"Obtain the first kill in a Match"},
new int[][]{new int[]{0, 100, 100}, new int[]{0, 150, 200}, new int[]{0, 200, 300}, new int[]{0, 250, 400}, new int[]{0, 500, 500}},
new int[]{2, 5, 10, 25, 50},
"Novice I",
new String[]{"Novice II", "Novice III", "Novice IV", "Novice V"},
"Initiate",
new String[]{"Novice I", "Novice II", "Novice III", "Novice IV", "Novice V"},
AchievementCategory.CASTLE_ASSAULT),
CASTLE_ASSAULT_FIGHTER_KIT("Fighter", 0,
@ -431,8 +431,8 @@ public enum Achievement
new String[]{"Kill opponents while wearing the Fighter Kit"},
new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}},
new int[]{50, 100, 250, 500, 1000, 1500, 3000, 5000, 10000, 20000},
"Novice I",
new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
"Initiate",
new String[]{"Novice I", "Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
AchievementCategory.CASTLE_ASSAULT),
CASTLE_ASSAULT_TANK_KIT("Tank", 0,
@ -440,8 +440,8 @@ public enum Achievement
new String[]{"Kill opponents while wearing the Tank Kit"},
new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}},
new int[]{50, 100, 250, 500, 1000, 1500, 3000, 5000, 10000, 20000},
"Novice I",
new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
"Initiate",
new String[]{"Novice I", "Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
AchievementCategory.CASTLE_ASSAULT),
CASTLE_ASSAULT_ARCHER_KIT("Archer", 0,
@ -449,8 +449,8 @@ public enum Achievement
new String[]{"Kill opponents while wearing the Archer Kit"},
new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}},
new int[]{50, 100, 250, 500, 1000, 1500, 3000, 5000, 10000, 20000},
"Novice I",
new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
"Initiate",
new String[]{"Novice I", "Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
AchievementCategory.CASTLE_ASSAULT),
CASTLE_ASSAULT_DEMOLITIONIST_KIT("Demolitionist", 0,
@ -458,8 +458,8 @@ public enum Achievement
new String[]{"Kill opponents while wearing the Demolitionist Kit"},
new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}},
new int[]{50, 100, 250, 500, 1000, 1500, 3000, 5000, 10000, 20000},
"Novice I",
new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
"Initiate",
new String[]{"Novice I", "Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
AchievementCategory.CASTLE_ASSAULT),
CASTLE_ASSAULT_WINNER("Assault", 0,
@ -467,8 +467,8 @@ public enum Achievement
new String[]{"Win games of Castle Assault"},
new int[][]{new int[]{0, 100, 500}, new int[]{0, 150, 750}, new int[]{0, 250, 1000}, new int[]{0, 500, 1500}, new int[]{0, 1000, 2500}, new int[]{0, 1500, 3500}, new int[]{0, 2000, 4500}, new int[]{0, 3000, 6000}, new int[]{0, 5000, 10000}, new int[]{0, 10000, 100000}},
new int[]{2, 5, 25, 50, 100, 150, 250, 500, 1000, 2000},
"Novice I",
new String[]{"Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
"Initiate",
new String[]{"Novice I", "Novice II", "Novice III", "Novice IV", "Novice V", "Master I", "Master II", "Master III", "Master IV", "GRANDMASTER"},
AchievementCategory.CASTLE_ASSAULT),
//Champions
@ -1202,7 +1202,31 @@ public enum Achievement
new String[]{"Skyfall.SupplyDropsOpened"},
new String[]{"Be the first to open 20 Supply Drops"},
new int[]{20},
AchievementCategory.SKYFALL);
AchievementCategory.SKYFALL),
GEM_HUNTERS_KILLS("Gem Killer", 5000,
new String[]{"Gem Hunters.Kills"},
new String[]{"+1 for each kill"},
new int[]{10,25,50,100,1000},
AchievementCategory.GEM_HUNTERS),
GEM_HUNTERS_GEMS_EARNED("Gem Millionaire", 5000,
new String[]{"Gem Hunters.GemsEarned"},
new String[]{"+1 for each Gem cashed out"},
new int[]{1000,2500,5000,10000,100000},
AchievementCategory.GEM_HUNTERS),
GEM_HUNTERS_QUESTS("Quest Complete", 5000,
new String[]{"Gem Hunters.QuestsCompleted"},
new String[]{"+1 for each quest completed"},
new int[]{10,25,50,100,1000},
AchievementCategory.GEM_HUNTERS),
GEM_HUNTERS_CHESTS_OPENED("Loot Get!", 5000,
new String[]{"Gem Hunters.ChestsOpened"},
new String[]{"+1 for each chest opened"},
new int[]{50,100,200,400,1000},
AchievementCategory.GEM_HUNTERS);
private String _name;
private String[] _desc;

View File

@ -213,7 +213,15 @@ public enum AchievementCategory
StatDisplay.fromGame("Wins", GameDisplay.SkyfallTeams, "Wins"), StatDisplay.fromGame("Games Played", GameDisplay.SkyfallTeams, "Wins", "Losses"),
StatDisplay.fromGame("Kills", GameDisplay.SkyfallTeams, "Kills"), StatDisplay.fromGame("Deaths", GameDisplay.SkyfallTeams, "Deaths"),
StatDisplay.fromGame("Gems Earned", GameDisplay.SkyfallTeams, "GemsEarned"), null, StatDisplay.fromGame("Booster Rings", GameDisplay.SkyfallTeams, "Rings")},
Material.DIAMOND_BOOTS, 0, GameCategory.SURVIVAL, null, false, GameDisplay.Skyfall.getGameId(), GameDisplay.SkyfallTeams.getGameId());
Material.DIAMOND_BOOTS, 0, GameCategory.SURVIVAL, null, false, GameDisplay.Skyfall.getGameId(), GameDisplay.SkyfallTeams.getGameId()),
GEM_HUNTERS("Gem Hunters", null,
new StatDisplay[] {StatDisplay.KILLS, StatDisplay.GEMS_EARNED, StatDisplay.fromGame("Quests Completed", GameDisplay.GemHunters, "QuestsCompleted"), StatDisplay.fromGame("Chests Opened", GameDisplay.GemHunters, "ChestsOpened")},
Material.EMERALD, 0, GameCategory.SURVIVAL, null, false, GameDisplay.GemHunters.getGameId()),
MOBA("Heroes of GWEN", null,
new StatDisplay[] {StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.GEMS_EARNED, null, StatDisplay.fromGame("Gold Earned", GameDisplay.MOBA, "GoldEarned")},
Material.PRISMARINE_SHARD, 0, GameCategory.CLASSICS, null, false, GameDisplay.MOBA.getGameId());
private String _name;
private String[] _statsToPull;

View File

@ -51,7 +51,7 @@ public class AchievementMainPage extends ShopPageBase<AchievementManager, Achiev
protected void buildPage()
{
ArrayList<Integer> pageLayout = new ItemLayout(
"XXOXOXOXO",
"OXOXOXOXO",
"OXOXOXOXO",
"OXOXOXOXO",
"OXOXOXOXO",

View File

@ -408,6 +408,11 @@ public class AntiHack extends MiniPlugin
@EventHandler
public void onHack(PlayerViolationEvent event)
{
if (event.getCheckClass() == Toggle.class)
{
return;
}
if (_ignoredChecks.contains(event.getCheckClass()))
return;

View File

@ -78,39 +78,39 @@ public class AntiHackGuardian implements Listener
{
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;
MAX_DISTANCE_X = maxX;
MIN_DISTANCE_X = minX;
MAX_DISTANCE_Y = maxY;
MIN_DISTANCE_Y = minY;
MAX_DISTANCE_Z = maxZ;
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);
CENTER_X = MIN_DISTANCE_X + ((MAX_DISTANCE_X - MIN_DISTANCE_X) / 2.0);
CENTER_Y = MIN_DISTANCE_Y + ((MAX_DISTANCE_Y - MIN_DISTANCE_Y) / 2.0);
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();
_center = center;
_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;
_armorStand = (ArmorStand) new EntityArmorStand(((CraftWorld) _center.getWorld()).getHandle(), _center.getX(), _center.getY(), _center.getZ()).getBukkitEntity();
_armorStand.setGravity(false);
_armorStand.setVisible(false);
_armorStand.setRemoveWhenFarAway(false);
_nmsEntity = ((CraftArmorStand) _armorStand).getHandle();
_nmsEntity.maxNoDamageTicks = 86400;
_nmsEntity.noDamageTicks = 86400;
this._entityUUID = this._armorStand.getUniqueId();
_entityUUID = _armorStand.getUniqueId();
this._disguise = new DisguiseGuardian(this._armorStand);
this._disguise.setHideIfNotDisguised(true);
_disguise = new DisguiseGuardian(_armorStand);
_disguise.setHideIfNotDisguised(true);
disguiseManager.disguise(this._disguise, player ->
disguiseManager.disguise(_disguise, player ->
{
if (!hideForStaff) return true;
@ -141,17 +141,17 @@ public class AntiHackGuardian implements Listener
@EventHandler
public void onLoad(ChunkAddEntityEvent event)
{
if (event.getEntity().getUniqueId().equals(this._entityUUID))
if (event.getEntity().getUniqueId().equals(_entityUUID))
{
this._armorStand = (ArmorStand) event.getEntity();
this._nmsEntity = ((CraftArmorStand) this._armorStand).getHandle();
_armorStand = (ArmorStand) event.getEntity();
_nmsEntity = ((CraftArmorStand) _armorStand).getHandle();
}
}
@EventHandler
public void onStack(StackerEvent event)
{
if (event.getEntity().getUniqueId().equals(this._entityUUID))
if (event.getEntity().getUniqueId().equals(_entityUUID))
{
event.setCancelled(true);
}
@ -159,27 +159,27 @@ public class AntiHackGuardian implements Listener
public void tick()
{
if (this._nmsEntity.dead || !this._nmsEntity.valid)
if (_nmsEntity.dead || !_nmsEntity.valid)
{
//debug("Skipping because " + this._armorStand.isDead() + " " + this._armorStand.isValid());
//debug("Skipping because " + _armorStand.isDead() + " " + _armorStand.isValid());
return;
}
if (this._target == null)
if (_target == null)
{
regularTick();
}
else
{
this._stalkTime++;
_stalkTime++;
targetTick();
}
//debug("Ticking " + this._armorStand + " " + this._armorStand.isDead() + " " + this._armorStand.getLocation() + " " + this._ticksUntilReset);
//debug("Ticking " + _armorStand + " " + _armorStand.isDead() + " " + _armorStand.getLocation() + " " + _ticksUntilReset);
}
private void regularTick()
{
if (this._ticksUntilReset <= 0)
if (_ticksUntilReset <= 0)
{
reset();
}
@ -187,8 +187,8 @@ public class AntiHackGuardian implements Listener
//debug("===== Begin Calculations =====");
//debug("Target: " + this._targetX + " " + this._targetY + " " + this._targetZ);
//debug("Start: " + this._armorStand.getLocation());
//debug("Target: " + _targetX + " " + _targetY + " " + _targetZ);
//debug("Start: " + _armorStand.getLocation());
double deltaX = _targetX - _nmsEntity.locX;
double deltaY = _targetY - _nmsEntity.locY;
double deltaZ = _targetZ - _nmsEntity.locZ;
@ -210,28 +210,28 @@ public class AntiHackGuardian implements Listener
_nmsEntity.locY += dy;
_nmsEntity.locZ += dz;
//debug("Dest: " + this._nmsEntity.locX + " " + this._nmsEntity.locY + " " + this._nmsEntity.locZ);
//debug("Dest: " + _nmsEntity.locX + " " + _nmsEntity.locY + " " + _nmsEntity.locZ);
//debug("===== End Calculations =====");
// Only send look update every second
if (this._nmsEntity.ticksLived % 20 == 0)
if (_nmsEntity.ticksLived % 20 == 0)
{
UtilEnt.CreatureLook(_armorStand, _nmsEntity.locX, _nmsEntity.locY, _nmsEntity.locZ, _targetX, _targetY, _targetZ);
}
this._ticksUntilReset--;
_ticksUntilReset--;
}
private void targetTick()
{
//debug("===== Stalking " + this._target.getName() + " =====");
EntityPlayer entityPlayer = ((CraftPlayer) this._target).getHandle();
//debug("===== Stalking " + _target.getName() + " =====");
EntityPlayer entityPlayer = ((CraftPlayer) _target).getHandle();
Vector direction = this._target.getLocation().getDirection().normalize().multiply(-6);
Vector direction = _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);
_nmsEntity.locX = entityPlayer.locX + direction.getX();
_nmsEntity.locZ = entityPlayer.locZ + direction.getZ();
_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);
}
@ -261,7 +261,7 @@ public class AntiHackGuardian implements Listener
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("Start: " + _armorStand.getLocation());
//debug("Changes: " + cx + " " + cy + " " + cz);
int ex = nextInt(8, 12);
@ -285,18 +285,18 @@ public class AntiHackGuardian implements Listener
//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);
_targetX = x + dx;
_targetY = y + dy;
_targetZ = z + dz;
//debug("End: " + _targetX + " " + _targetY + " " + _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;
_targetX = CENTER_X;
_targetY = CENTER_Y;
_targetZ = CENTER_Z;
dx = (int) (CENTER_X - x);
dy = (int) (CENTER_Y - y);
@ -305,46 +305,46 @@ public class AntiHackGuardian implements Listener
double maxDelta = Math.max(Math.max(Math.abs(dx), Math.abs(dy)), Math.abs(dz));
this._ticksUntilReset = (int) (maxDelta / DELTA_MOVE_PER_TICK);
_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("Ticks: " + _ticksUntilReset);
//debug("======= END RESET ======");
}
public void target(Player player)
{
this._target = player;
_target = player;
}
public boolean isTargeting()
{
return this._target != null;
return _target != null;
}
public int getTargetingTime()
{
return this._stalkTime;
return _stalkTime;
}
public void stopTargeting()
{
this._target = null;
this._stalkTime = 0;
_target = null;
_stalkTime = 0;
reset();
}
public void shoot(Player player)
{
this._disguise.setTarget(player == null ? 0 : player.getEntityId());
Managers.get(DisguiseManager.class).updateDisguise(this._disguise);
_disguise.setTarget(player == null ? 0 : player.getEntityId());
Managers.get(DisguiseManager.class).updateDisguise(_disguise);
}
public Player getTarget()
{
return this._target;
return _target;
}
private boolean locCheck()
@ -376,31 +376,31 @@ public class AntiHackGuardian implements Listener
public void remove()
{
this._target = null;
_target = null;
UtilServer.Unregister(this);
Managers.get(DisguiseManager.class).undisguise(this._disguise);
this._armorStand.remove();
this._nmsEntity = null;
this._armorStand = null;
this._center = null;
Managers.get(DisguiseManager.class).undisguise(_disguise);
_armorStand.remove();
_nmsEntity = null;
_armorStand = null;
_center = null;
}
public ArmorStand getEntity()
{
return this._armorStand;
return _armorStand;
}
public void moveDelta(double dx, double dy, double dz)
{
this._nmsEntity.locX += dx;
this._nmsEntity.locY += dy;
this._nmsEntity.locZ += dz;
_nmsEntity.locX += dx;
_nmsEntity.locY += dy;
_nmsEntity.locZ += dz;
}
public void move(double x, double y, double z)
{
this._nmsEntity.locX = x;
this._nmsEntity.locY = y;
this._nmsEntity.locZ = z;
_nmsEntity.locX = x;
_nmsEntity.locY = y;
_nmsEntity.locZ = z;
}
}

View File

@ -41,13 +41,13 @@ public class GuardianManager extends MiniPlugin
{
super("GuardianManager");
this._plugin.getServer().getScheduler().runTaskTimer(this._plugin, () ->
_plugin.getServer().getScheduler().runTaskTimer(_plugin, () ->
{
for (AntiHackGuardian guardian : this._guardians)
for (AntiHackGuardian guardian : _guardians)
{
if (guardian.getTarget() != null && !guardian.getTarget().isOnline())
{
this._stalking.remove(guardian.getTarget().getUniqueId());
_stalking.remove(guardian.getTarget().getUniqueId());
guardian.stopTargeting();
}
else if (guardian.getTargetingTime() > MIN_STALK_TIME)
@ -55,7 +55,7 @@ public class GuardianManager extends MiniPlugin
double threshold = STALK_END_PROBABILITY_EQUATION.apply(guardian.getTargetingTime() - MIN_STALK_TIME);
if (Math.random() <= threshold)
{
this._stalking.remove(guardian.getTarget().getUniqueId());
_stalking.remove(guardian.getTarget().getUniqueId());
_stalkingCooldown.put(guardian.getTarget().getUniqueId(), true);
guardian.stopTargeting();
}
@ -64,7 +64,7 @@ public class GuardianManager extends MiniPlugin
}
}, 0L, 1L);
this._plugin.getServer().getScheduler().runTaskTimer(this._plugin, () ->
_plugin.getServer().getScheduler().runTaskTimer(_plugin, () ->
{
if (_stalking.size() >= MAX_STALKED_PLAYERS)
{
@ -124,6 +124,6 @@ public class GuardianManager extends MiniPlugin
public void registerGuardian(AntiHackGuardian guardian)
{
this._guardians.add(guardian);
_guardians.add(guardian);
}
}

View File

@ -55,8 +55,8 @@ public class BetaWhitelist extends MiniPlugin
{
Player player = event.getPlayer();
Rank rank = _clientManager.Get(player).GetRank(true);
if ((rank != Rank.MAPDEV && rank != Rank.MAPLEAD && rank.has(Rank.ETERNAL) // If this player is Eternal+ (and not a builder),
|| _powerPlayClubRepository.getCachedData(player).isSubscribed()) // a PPC subscriber,
if (rank.has(Rank.ULTRA) // If this player is Ultra+
|| _powerPlayClubRepository.getCachedData(player).isSubscribed() // a PPC subscriber,
|| EXTRA_PLAYERS.contains(player.getUniqueId())) // or explicitly whitelisted,
{
return; // allow them in

View File

@ -941,12 +941,7 @@ public class BonusManager extends MiniClientPlugin<BonusClientData> implements I
if (!_enabled)
return;
Entity entity = event.getRightClicked();
if (entity.equals(_carlNpc.getEntity()))
{
updateDailyStreak(event.getPlayer());
new BonusGui(_plugin, event.getPlayer(), this, _rewardManager, _facebookManager, _youtubeManager, _thankManager, _playWireManager).openInventory();
}
attemptOpenCarlGUI(event.getPlayer(), event.getRightClicked());
}
@EventHandler
@ -957,12 +952,22 @@ public class BonusManager extends MiniClientPlugin<BonusClientData> implements I
if (event.getDamager() instanceof Player)
{
Player player = (Player) event.getDamager();
if (event.getEntity().equals(_carlNpc.getEntity()))
{
updateDailyStreak(player);
new BonusGui(_plugin, player, this, _rewardManager, _facebookManager, _youtubeManager, _thankManager, _playWireManager).openInventory();
}
attemptOpenCarlGUI((Player) event.getDamager(), event.getEntity());
}
}
private void attemptOpenCarlGUI(Player player, Entity entity)
{
if (_carlNpc == null || _carlNpc.getEntity() == null)
{
System.err.println("Carl is missing! (carlNpc=" + _carlNpc + ")");
return;
}
if (entity.equals(_carlNpc.getEntity()))
{
updateDailyStreak(player);
new BonusGui(_plugin, player, this, _rewardManager, _facebookManager, _youtubeManager, _thankManager, _playWireManager).openInventory();
}
}
@ -1261,4 +1266,9 @@ public class BonusManager extends MiniClientPlugin<BonusClientData> implements I
{
_carlLocation = carlLocation;
}
public Npc getCarl()
{
return _carlNpc;
}
}

View File

@ -127,7 +127,7 @@ public class PowerPlayClubButton implements GuiItem
itemName = C.cRedB + "Power Play Club";
lore.add(C.cYellow + YearMonth.now().getMonth().getDisplayName(TextStyle.FULL, Locale.US) + "'s Cosmetic");
lore.add(C.cWhite + " " + PowerPlayClubRewards.rewards().get(YearMonth.now()).getPrizeName());
lore.add(C.cWhite + " " + PowerPlayClubRewards.getReward(YearMonth.now()).getPrizeName());
lore.add(" ");
lore.addAll(buildOtherRewardsLore(1));
lore.add(C.cRed + "Get Power Play Club months at");

View File

@ -1,57 +0,0 @@
package mineplex.core.brawl.fountain;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
/**
* This class handled filling a vertical area with a specific block based off a percent
*
* @author Shaun Bennett
*/
public class BlockProgressBar
{
// Starting block for the block fill
private final Block _startBlock;
// Direction the blockfill takes place in
private final BlockFace _direction;
// Blocks in order from lowest to highes
private final Block[] _blocks;
// Material used to fill the blocks
private final Material _material;
public BlockProgressBar(Block startBlock, Material material, BlockFace direction)
{
_startBlock = startBlock;
_material = material;
_direction = direction;
// Add blocks to array
int i;
Block curr;
Block[] blocks = new Block[100]; // max of 100 to prevent blocking
for (i = 0, curr = startBlock; (curr.getType() == Material.AIR || curr.getType() == material) && i < blocks.length; i++)
{
blocks[i] = curr;
curr = curr.getRelative(direction);
}
_blocks = new Block[i];
System.arraycopy(blocks, 0, _blocks, 0, i);
}
// Update the blockfill based on fill percent
public void update(double percent)
{
double percentPerBlock = 1D / _blocks.length;
double check = 0;
for (int i = 0; i < _blocks.length; i++)
{
_blocks[i].setType(percent > check ? _material : Material.AIR);
check += percentPerBlock;
}
}
}

View File

@ -1,11 +0,0 @@
package mineplex.core.brawl.fountain;
import mineplex.core.shop.ShopBase;
/**
* @author Shaun Bennett
*/
public interface BrawlShopProvider
{
public ShopBase getBrawlShop();
}

View File

@ -1,258 +0,0 @@
package mineplex.core.brawl.fountain;
import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.gui.FountainShop;
import mineplex.core.common.SortedSchematicLoader;
import mineplex.core.common.block.schematic.UtilSchematic;
import mineplex.core.common.util.C;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilText;
import mineplex.core.donation.DonationManager;
import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
import mineplex.core.stats.StatsManager;
import mineplex.serverdata.Region;
import mineplex.serverdata.redis.counter.GoalCounter;
import mineplex.serverdata.redis.counter.GoalCounterListener;
import mineplex.serverdata.servers.ConnectionData;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.TimeZone;
/**
* Represents a fountain that players can add gems to, with a reward for reaching specific goals
* @author Shaun Bennett
*/
public class Fountain implements GoalCounterListener
{
// Manager Injections
private final HologramManager _hologramManager;
private final StatsManager _statsManager;
private boolean _brawlActive;
private final String _name;
private final String _dataKey;
private final Location _location;
private final Hologram _hologram;
private final GoalCounter _counter;
// private final BlockProgressBar _blockProgressBar;
private final SortedSchematicLoader<Double> _schematicLoader;
private final FountainShop _shop;
public Fountain(ConnectionData writeConnection, ConnectionData readConnection, Region region, Location location, Location pasteLocation, String name, String dataKey, long goal, FountainManager fountainManager,
CoreClientManager clientManager, DonationManager donationManager, HologramManager hologramManager,
StatsManager statsManager)
{
_hologramManager = hologramManager;
_statsManager = statsManager;
_name = name;
_dataKey = dataKey;
_location = location;
_hologram = new Hologram(hologramManager, new Location(location.getWorld(), -23, 75, 3), name).start();
_counter = new GoalCounter(writeConnection, readConnection, region, dataKey, goal);
_counter.addListener(this);
_brawlActive = false;
// _blockProgressBar = new BlockProgressBar(_lavaLocation.getBlock(), Material.LAVA, BlockFace.UP);
_schematicLoader = new SortedSchematicLoader<>(pasteLocation);
loadSchematics();
_shop = new FountainShop(this, fountainManager, clientManager, donationManager);
updateVisuals();
}
private void loadSchematics()
{
try
{
_schematicLoader.addSchematic(0.0, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain0.schematic")));
_schematicLoader.addSchematic(0.2, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain20.schematic")));
_schematicLoader.addSchematic(0.4, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain40.schematic")));
_schematicLoader.addSchematic(0.6, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain60.schematic")));
_schematicLoader.addSchematic(0.8, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain80.schematic")));
_schematicLoader.addSchematic(1.0, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain100.schematic")));
_schematicLoader.addSchematic(2.0, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain200.schematic")));
_schematicLoader.addSchematic(3.0, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain300.schematic")));
}
catch (IOException e)
{
System.err.println("Failed to load Gem Fountain Schematics");
e.printStackTrace();
}
}
protected void updateVisuals()
{
double fillPercent = getFillPercent();
if (isBrawlActive())
{
ArrayList<String> text = new ArrayList<>();
if (fillPercent >= 1)
{
text.add(C.cRed + C.Bold + "Weekend Brawl is Active!");
if (fillPercent >= 2)
{
text.add("Bonus Reward Unlocked:");
if (fillPercent >= 3)
{
text.add(C.cGreen + "3X Experience in Brawl");
}
else
{
text.add(C.cGreen + "2X Experience in Brawl");
}
}
text.add(" ");
text.add("Speak to the Fountain Keeper to Join!");
}
else
{
text.add(C.cRed + "Brawl goal was not met");
text.add("Come back next week");
}
_hologram.setText(text.toArray(new String[text.size()]));
//_schematicLoader.update(fillPercent);
}
else
{
double flatPercent = fillPercent - (int) fillPercent;
String fillColor;
String emptyColor;
String goalMessage;
if (fillPercent < 1)
{
fillColor = C.cGreen;
emptyColor = C.cRed;
goalMessage = "100% to Unlock Weekend Brawl";
} else if (fillPercent < 2)
{
fillColor = C.cYellow;
emptyColor = C.cGreen;
goalMessage = "200% to Unlock 2x XP for Weekend Brawl";
} else if (fillPercent < 3)
{
fillColor = C.cAqua;
emptyColor = C.cYellow;
goalMessage = "300% to Unlock 3x XP for Weekend Brawl";
} else
{
fillColor = C.cAqua;
emptyColor = C.cYellow;
goalMessage = "All Rewards Unlocked!";
flatPercent = 1;
}
int intPercent = (int) (fillPercent * 100);
String progressBar = UtilText.getProgress(null, flatPercent, null, false, 30, emptyColor, fillColor);
_hologram.setText(_name + C.Reset + " " + intPercent + "%", goalMessage, progressBar);
_schematicLoader.update(fillPercent);
}
}
public void increment(Player player, long amount, Callback<Long> callback)
{
_statsManager.incrementStat(player, getStatName(), amount);
_statsManager.runAsync(() -> {
long count = _counter.addAndGet(amount);
_statsManager.runSync(() -> {
updateVisuals();
if (callback != null) callback.run(count);
});
});
}
public long getAmountAdded(Player player)
{
return _statsManager.Get(player).getStat(getStatName());
}
private final String getStatName()
{
return "Global.Fountain." + getDataKey();
}
public String getName()
{
return _name;
}
public String getDataKey()
{
return _dataKey;
}
public void openShop(Player player)
{
_shop.attemptShopOpen(player);
}
public double getFillPercent()
{
return Math.min(3, _counter.getFillPercent());
}
public long getCount()
{
return _counter.getCount();
}
public void reset()
{
_counter.reset();
updateVisuals();
}
@Override
public void onMilestone(GoalCounter counter, int milestone)
{
switch (milestone)
{
case 1:
Bukkit.broadcastMessage(F.main("Fountain", "The Gem Fountain has reached 100%! Brawl Game unlocked this week"));
break;
case 2:
Bukkit.broadcastMessage(F.main("Fountain", "The Gem Fountain has reached 200%! 2x XP enabled for Brawl!"));
break;
case 3:
Bukkit.broadcastMessage(F.main("Fountain", "The Gem Fountain has reached 300%! 3x XP enabled for Brawl!"));
break;
}
}
public void updateBrawlActive()
{
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("PST"));
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek == Calendar.FRIDAY || dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY)
{
_brawlActive = true;
}
else
{
_brawlActive = false;
}
}
public void updateCounter()
{
_counter.updateCount();
}
public boolean isBrawlActive()
{
return _brawlActive;
}
}

View File

@ -1,123 +0,0 @@
package mineplex.core.brawl.fountain;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.command.FountainCommand;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.hologram.HologramManager;
import mineplex.core.locations.LocationConstants;
import mineplex.core.stats.StatsManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.serverdata.Region;
import mineplex.serverdata.servers.ConnectionData;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.plugin.java.JavaPlugin;
/**
* @author Shaun Bennett
*/
public class FountainManager extends MiniPlugin
{
private HologramManager _hologramManager;
private StatsManager _statsManager;
private DonationManager _donationManager;
// used so we can inject the brawl shop (only on hub) into fountain code
private BrawlShopProvider _brawlShopProvider;
private Fountain _gemFountain;
public FountainManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, HologramManager hologramManager, StatsManager statsManager, BrawlShopProvider shopProvider)
{
super("Counter", plugin);
_hologramManager = hologramManager;
_statsManager = statsManager;
_donationManager = donationManager;
_brawlShopProvider = shopProvider;
World world = Bukkit.getWorlds().get(0);//-43.5, 66, -38.5
int goal = 35000000;//!new File("eu.dat").exists() ? 200000000 : 20000000;
_gemFountain = new Fountain(new ConnectionData("10.3.203.80", 6379, ConnectionData.ConnectionType.MASTER, "USRedis"),
new ConnectionData("10.3.203.80", 6377, ConnectionData.ConnectionType.SLAVE, "USRedis"), Region.ALL,
LocationConstants.FOUNTAIN_LOCATION, LocationConstants.FOUNTAIN_SCHEMATIC,
C.cGreen + "Gem Fountain", "GemFountain_01", goal, this, clientManager, donationManager, _hologramManager, _statsManager);
}
@Override
public void addCommands()
{
addCommand(new FountainCommand(this));
}
@EventHandler
public void updateFountainCount(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
return;
_gemFountain.updateBrawlActive();
_gemFountain.updateVisuals();
}
@EventHandler
public void updateCounter(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC_05)
return;
runAsync(_gemFountain::updateCounter);
}
@EventHandler
public void onInteractAtEntity(PlayerInteractAtEntityEvent event)
{
Entity entity = event.getRightClicked();
if (entity.getCustomName() != null && entity.isCustomNameVisible())
{
if (entity.getCustomName().contains("Weekend Brawl") && getBrawlShopProvider() != null)
{
getBrawlShopProvider().getBrawlShop().attemptShopOpen(event.getPlayer());
}
}
}
@EventHandler
public void onDamage(EntityDamageByEntityEvent event)
{
if (!(event.getDamager() instanceof Player))
return;
Entity entity = event.getEntity();
if (entity.getCustomName() != null && entity.isCustomNameVisible())
{
if (entity.getCustomName().contains("Weekend Brawl") && getBrawlShopProvider() != null)
{
getBrawlShopProvider().getBrawlShop().attemptShopOpen(((Player) event.getDamager()));
}
}
}
public Fountain getGemFountain()
{
return _gemFountain;
}
public DonationManager getDonationManager()
{
return _donationManager;
}
public BrawlShopProvider getBrawlShopProvider()
{
return _brawlShopProvider;
}
}

View File

@ -1,20 +0,0 @@
package mineplex.core.brawl.fountain;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.shop.item.SalesPackageBase;
import org.bukkit.Material;
/**
* @author Shaun Bennett
*/
public class GemFountainSalesPackage extends SalesPackageBase
{
public GemFountainSalesPackage(int gems)
{
super("Add " + gems + " Gems", Material.EMERALD, (byte) 0, new String[] {}, gems, 1);
CurrencyCostMap.put(GlobalCurrency.GEM, gems);
KnownPackage = false;
OneTimePurchaseOnly = false;
}
}

View File

@ -1,69 +0,0 @@
package mineplex.core.brawl.fountain.command;
import java.util.function.Consumer;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.server.util.TransactionResponse;
import org.bukkit.entity.Player;
/**
* Command to add gems to the fountain
*
* @author Shaun Bennett
*/
public class AddCommand extends CommandBase<FountainManager>
{
public AddCommand(FountainManager plugin)
{
super(plugin, Rank.DEVELOPER, "add");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args == null || args.length != 1)
{
help(caller);
return;
}
try
{
int amount = Integer.parseInt(args[0]);
Plugin.getDonationManager().purchaseUnknownSalesPackage(caller, "GemFountain.Add", GlobalCurrency.GEM, amount, false,
result ->
{
if (result == TransactionResponse.Success)
{
Plugin.getGemFountain().increment(caller, amount, null);
UtilPlayer.message(caller, F.main("Fountain", "Added " + F.elem(amount) + " to the fountain!"));
}
else if (result == TransactionResponse.InsufficientFunds)
{
UtilPlayer.message(caller, F.main("Fountain", "You do not have enough gems!"));
}
else
{
UtilPlayer.message(caller, F.main("Fountain", "There was an error processing your request!"));
}
});
}
catch (NumberFormatException ex)
{
help(caller);
}
}
private void help(Player player)
{
UtilPlayer.message(player, F.help("/fountain add", "<amount>", Rank.DEVELOPER));
}
}

View File

@ -1,27 +0,0 @@
package mineplex.core.brawl.fountain.command;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.command.MultiCommandBase;
import mineplex.core.common.Rank;
import org.bukkit.entity.Player;
/**
* @author Shaun Bennett
*/
public class FountainCommand extends MultiCommandBase<FountainManager>
{
public FountainCommand(FountainManager plugin)
{
super(plugin, Rank.DEVELOPER, "fountain");
AddCommand(new AddCommand(plugin));
AddCommand(new GuiCommand(plugin));
AddCommand(new ResetCommand(plugin));
}
@Override
protected void Help(Player caller, String[] args)
{
}
}

View File

@ -1,26 +0,0 @@
package mineplex.core.brawl.fountain.command;
import mineplex.core.brawl.fountain.FountainManager;
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;
/**
* Command to open the fountain gui without speaking to the fountain keeper
* @author Shaun Bennett
*/
public class GuiCommand extends CommandBase<FountainManager>
{
public GuiCommand(FountainManager plugin)
{
super(plugin, Rank.DEVELOPER, "gui");
}
@Override
public void Execute(Player caller, String[] args)
{
Plugin.getGemFountain().openShop(caller);
}
}

View File

@ -1,26 +0,0 @@
package mineplex.core.brawl.fountain.command;
import mineplex.core.brawl.fountain.FountainManager;
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;
/**
* Command to reset the fountain
* @author Shaun Bennett
*/
public class ResetCommand extends CommandBase<FountainManager>
{
public ResetCommand(FountainManager plugin)
{
super(plugin, Rank.DEVELOPER, "reset");
}
@Override
public void Execute(Player caller, String[] args)
{
Plugin.getGemFountain().reset();
}
}

View File

@ -1,92 +0,0 @@
package mineplex.core.brawl.fountain.gui;
import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.Fountain;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.brawl.fountain.gui.button.FountainAddButton;
import mineplex.core.common.MaterialData;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.shop.item.ShopItem;
import mineplex.core.shop.page.ShopPageBase;
import org.bukkit.Material;
import org.bukkit.entity.Player;
/**
* @author Shaun Bennett
*/
public class FountainPage extends ShopPageBase<FountainManager, FountainShop>
{
private final MaterialData EMPTY_XP = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 7);
private final MaterialData XP = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 5);
private final MaterialData EMPTY_XP100 = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 5);
private final MaterialData XP100 = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 4);
private final MaterialData EMPTY_XP200 = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 4);
private final MaterialData XP200 = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 3);
private final int[] XP_SLOTS = { 2, 3, 4, 5, 6 };
private Fountain _fountain;
public FountainPage(FountainManager plugin, FountainShop shop, CoreClientManager clientManager, DonationManager donationManager, Fountain fountain, Player player)
{
super(plugin, shop, clientManager, donationManager, "Fountain Keeper", player, 27);
_fountain = fountain;
buildPage();
}
@Override
protected void buildPage()
{
// Experience Bar
long added = _fountain.getAmountAdded(getPlayer());
final double fillPercent = _fountain.getFillPercent();
String title = ((int)(fillPercent * 100)) + "% Complete";
boolean canAdd = fillPercent < 3;
String unlockMessage;
if (fillPercent < 1) unlockMessage = "Reach 100% to unlock Weekend Brawl Game";
else if (fillPercent < 2) unlockMessage = "Reach 200% to unlock 2x XP in Brawl";
else if (fillPercent < 3) unlockMessage = "Reach 300% to unlock 3x XP in Brawl";
else unlockMessage = "All rewards unlocked!";
String[] lore = new String[] {
" ",
C.cWhite + unlockMessage,
" ",
C.cWhite + "You have added " + C.cGreen + added + " Gems"};
final double percentForEach = 1D / XP_SLOTS.length;
double check = percentForEach;
double flatPercent = fillPercent == 3 ? 1 : fillPercent - ((int) fillPercent);
for (int i = 0; i < XP_SLOTS.length; i++)
{
MaterialData data;
if (fillPercent < 1) data = flatPercent >= check ? XP : EMPTY_XP;
else if (fillPercent < 2) data = flatPercent >= check ? XP100 : EMPTY_XP100;
else data = flatPercent >= check ? XP200 : EMPTY_XP200;
ShopItem shopItem = new ShopItem(data.getMaterial(), data.getData(), title,
lore, 1, false, false);
setItem(XP_SLOTS[i], shopItem);
check += percentForEach;
}
if (canAdd)
{
int playerGems = getDonationManager().Get(getPlayer()).getBalance(GlobalCurrency.GEM);
ShopItem add1 = new ShopItem(Material.EMERALD, "Add 100 Gems", new String[]{}, 1, playerGems < 100, false);
ShopItem add2 = new ShopItem(Material.EMERALD, "Add 1,000 Gems", new String[]{}, 64, playerGems < 1000, false);
ShopItem add3 = new ShopItem(Material.EMERALD_BLOCK, "Add 10,000 Gems", new String[]{}, 1, playerGems < 10000, false);
ShopItem add4 = new ShopItem(Material.EMERALD_BLOCK, "Add 100,000 Gems", new String[]{}, 64, playerGems < 100000, false);
// Buttons
addButton(19, add1, new FountainAddButton(this, 100));
addButton(21, add2, new FountainAddButton(this, 1000));
addButton(23, add3, new FountainAddButton(this, 10000));
addButton(25, add4, new FountainAddButton(this, 100000));
}
}
}

View File

@ -1,48 +0,0 @@
package mineplex.core.brawl.fountain.gui;
import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.Fountain;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
import org.bukkit.entity.Player;
/**
* @author Shaun Bennett
*/
public class FountainShop extends ShopBase<FountainManager>
{
private final Fountain _fountain;
public FountainShop(Fountain fountain, FountainManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super(plugin, clientManager, donationManager, "Fountain Keeper");
_fountain = fountain;
}
@Override
protected ShopPageBase<FountainManager, ? extends ShopBase<FountainManager>> buildPagesFor(Player player)
{
return new FountainPage(getPlugin(), this, getClientManager(), getDonationManager(), _fountain, player);
}
public Fountain getFountain()
{
return _fountain;
}
@Override
public boolean attemptShopOpen(Player player)
{
if (_fountain.isBrawlActive() && getPlugin().getBrawlShopProvider() != null)
{
return getPlugin().getBrawlShopProvider().getBrawlShop().attemptShopOpen(player);
}
else
{
return super.attemptShopOpen(player);
}
}
}

View File

@ -1,38 +0,0 @@
package mineplex.core.brawl.fountain.gui.button;
import mineplex.core.brawl.fountain.GemFountainSalesPackage;
import mineplex.core.brawl.fountain.gui.FountainPage;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.shop.confirmation.ConfirmationPage;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.SalesPackageBase;
import mineplex.core.shop.item.SalesPackageProcessor;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
/**
* @author Shaun Bennett
*/
public class FountainAddButton implements IButton
{
private final FountainPage _page;
private final int _gems;
private final SalesPackageBase _salesPackage;
public FountainAddButton(FountainPage page, int gems)
{
_page = page;
_gems = gems;
_salesPackage = new GemFountainSalesPackage(gems);
}
@Override
public void onClick(Player player, ClickType clickType)
{
_page.getShop().openPageForPlayer(player, new ConfirmationPage<>(player, _page, new SalesPackageProcessor(player, GlobalCurrency.GEM, _salesPackage, _page.getDonationManager(), () ->
{
_page.getPlugin().getGemFountain().increment(player, _gems, null);
_page.refresh();
}), _salesPackage.buildIcon()));
}
}

View File

@ -33,7 +33,7 @@ public class FallingBlocks extends MiniPlugin
if (vec.getY() < 0)
{
vec.setY(vec.getY() * -1);
vec.setY(-vec.getY());
}
Spawn(location, type, data, vec);
@ -46,7 +46,6 @@ public class FallingBlocks extends MiniPlugin
UtilAction.velocity(fall, velocity, 0.5 + 0.25 * Math.random(), false, 0, 0.4 + 0.20 * Math.random(), 10, false);
fall.setMetadata(METADATA, new FixedMetadataValue(_plugin, "x"));
UtilEnt.SetMetadata(fall, METADATA, "x");
}

View File

@ -10,6 +10,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import mineplex.core.gadget.gadgets.morph.MorphBobRoss;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@ -454,6 +455,7 @@ public class GadgetManager extends MiniPlugin
addGadget(new MorphLoveDoctor(this));
addGadget(new MorphGoldPot(this));
addGadget(new MorphAwkwardRabbit(this));
addGadget(new MorphBobRoss(this, _hologramManager));
// Particles
addGadget(new ParticleFoot(this));

View File

@ -10,10 +10,11 @@ import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilText;
import mineplex.core.common.util.UtilTime;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.types.ArrowEffectGadget;
import net.minecraft.server.v1_8_R3.MinecraftServer;
public class ArrowTrailCandyCane extends ArrowEffectGadget
{
@ -29,7 +30,7 @@ public class ArrowTrailCandyCane extends ArrowEffectGadget
public void doTrail(Arrow arrow)
{
int data = 15;
int tick = Math.abs(UtilTime.getServerTick()%3);
int tick = Math.abs(MinecraftServer.currentTick%3);
if(tick == 1) data = 1;
if(tick == 2) data = 2;
Location loc = arrow.getLocation();

View File

@ -0,0 +1,584 @@
package mineplex.core.gadget.gadgets.morph;
import java.time.Month;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilText;
import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.recharge.Recharge;
import mineplex.core.treasure.event.TreasureFinishEvent;
import mineplex.core.treasure.event.TreasureStartEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
import com.mojang.authlib.GameProfile;
import mineplex.core.common.skin.SkinData;
import mineplex.core.disguise.disguises.DisguisePlayer;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.morph.managers.UtilMorph;
import mineplex.core.gadget.types.MorphGadget;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.utils.UtilGameProfile;
/**
* Bob Ross morph for Power Play Club (June 2017)
*/
public class MorphBobRoss extends MorphGadget
{
/** Radius within which painting is not allowed near treasure chests */
private static final int TREASURE_RADIUS = 4;
/** The inventory slot in which the paint brush is placed */
private static final int PAINT_BRUSH_SLOT = 2;
/** The # of milliseconds for which paint blocks exist */
private static final long PAINT_MILLISECONDS = 30000;
/** Height above a player's location at which quotes are to be displayed */
private static final double QUOTE_HEIGHT = 2.25;
/** The number of seconds for which quotes are displayed */
private static final int QUOTE_PERSISTENCE = 10;
/** Cooldown key for changing paint colors */
private static final String COLOR_KEY = "Change Paint Color";
/** Cooldown time for changing paint colors (milliseconds) */
private static final long COLOR_COOLDOWN = 220;
/** Cooldown key for displaying a Bob Ross quote above head */
private static final String QUOTE_KEY = "Bob Ross Quote";
/** Cooldown time for displaying a Bob Ross quote (milliseconds) */
private static final long QUOTE_COOLDOWN = 10100;
/** Distance (in blocks) from which the quotes can be seen */
private static final int VIEW_DISTANCE = 14;
/** Quote attribution for bob */
private static final String ATTRIBUTION = C.cGray + "- " + C.cYellow + "Bob Ross";
/** Formatted name for the clean brush */
private static final String BRUSH_NAME = C.cYellow + "Clean Paintbrush";
/** Determines the order in which colors are selected */
private static final byte[] COLOR_ORDER = {
(byte) 1,
(byte) 14,
(byte) 11,
(byte) 10,
(byte) 2,
(byte) 6,
(byte) 12,
(byte) 4,
(byte) 5,
(byte) 13,
(byte) 9,
(byte) 15,
(byte) 7,
(byte) 8,
(byte) 0,
(byte) 3
};
/** Paint colors for displaying in players' hotbars */
private static final String[] PAINT_COLORS = {
C.cBlackB + "Midnight Black",
C.cRedB + "Alizarin Crimson",
C.cDGreenB + "Sap Green",
C.cGoldB + "Van Dyke Brown",
C.cDBlueB + "Prussian Blue",
C.cDPurpleB + "Studio Purple",
C.cDAquaB + "Phthalo Green",
C.cGrayB + "Dusty Gray",
C.cDGrayB + "Tundora Gray",
C.cPurpleB + "Soft Flower Pink",
C.cGreenB + "Lima Green",
C.cYellowB + "Cadmium Yellow",
C.cBlueB + "Danube Blue",
C.cPurpleB + "Soft Magenta",
C.cGoldB + "Yellow Ochre",
C.cWhiteB + "Titanium White"
};
/** Brush types for displaying in players' hotbars */
private static final String[] PAINT_BRUSHES = {
"Landscape Brush",
"Foliage Brush",
"Background Brush",
"Blender Brush",
"Oval Brush",
"Round Brush",
"Fan Brush",
"Painting Knife"
};
/** List of wholesome Bob Ross quotes. */
private static final String[][] QUOTES = {
{"We don't make mistakes,", "just happy little accidents."},
{"Anything that you're willing to practice,", "you can do."},
{"There's nothing wrong with having a tree as a friend."},
{"Let's get a little crazy here!"},
{"Express yourself to others through painting."},
{"All you need to paint is a few tools,", "a little instruction,", "and a vision in your mind."},
{"I can't think of anything more", "rewarding than being able to express", "yourself to others through painting."},
{"The secret to doing anything is", "believing that you can do it."},
{"Anything that you believe you can do strong enough,", "you can do."},
{"Wash the brush, just beat the devil out of it!"},
{"Beat the devil out of it!"},
{"I started painting as a hobby when I was little."},
{"Anybody can do what I do."},
{"I believe talent is just a pursued interest."},
{"Mix up a little more shadow color here,", "then we can put us a little shadow right in there."},
{"You have unlimited power on this canvas!"},
{"Believe that you can do it cause you can do it."},
{"There's nothing in the world", "that breeds success like success."},
{"Lets build a happy little cloud."},
{"Lets build some happy little trees."},
{"Everyday is a good day when you paint."},
{"The only thing worse than", "yellow snow is green snow."},
{"Look around.", "Look at what we have.", "Beauty is everywhere—", "you only have to look to see it."},
{"Just go out and talk to a tree.", "Make friends with it."},
{"How do you make a round circle with a square knife?", "Thats your challenge for the day."},
{"Water's like me. It's laaazy...", "Boy, it always looks for the easiest way to do things"},
{"Oooh, if you have never been to Alaska,", "go there while it is still wild."},
{"If I paint something,", "I don't want to have to explain what it is."},
{"We artists are a different breed of people.", "We're a happy bunch."},
{"Any way you want it to be, that's just right."},
{"As my son Steve says, just 'smoosh' it in there."},
{"Use odorless paint-thinner.", "If it's not odorless, you'll find yourself", "working alone very, very quickly."},
{"Let's just blend this little rascal here, ha!", "Happy as we can be."},
{"Clouds are very, very free."},
{"Maybe in our world there lives a", "happy little tree over there."},
{"Shwooop! Hehe.", "You have to make those little noises,", "or it just doesn't work."},
{"No pressure. Just relax and watch it happen."},
{"Find freedom on this canvas."},
{"Its so important to do something every", "day that will make you happy."},
{"Every day is a good day when you paint."},
{"Hi, I'm Bob Ross!"},
{"Everyone needs a friend."},
{"Dont forget to tell these special", "people in your life just how special", "they are to you."},
{"I taught my son to paint mountains like these!"},
{"You need the dark in order to show the light."},
{"In nature, dead trees are just", "as normal as live trees."},
{"This is happy place;", "little squirrels live here and play."},
{"Its life.", "Its interesting.", "Its fun."},
{"I really believe that", "if you practice enough you could paint the", "'Mona Lisa' with a two-inch brush."},
{"Don't be afraid to go out on a limb,", "because that's where the fruit is!"}
};
/** Map of items in players' inventories */
private final Map<UUID, ItemStack> _inventoryItems = new HashMap<>();
/** Colors that are being used by painting players */
private final Map<UUID, Byte> _paintColors = new HashMap<>();
/** Locations at which treasure is currently being opened */
private final Map<UUID, Location> _openingTreasure = new HashMap<>();
private final HologramManager _holograms;
public MorphBobRoss(GadgetManager manager, HologramManager holograms)
{
super(manager, "Bob Ross Morph", UtilText.splitLinesToArray(new String[] {
C.cGray + "Become the creator of your own world!",
C.cGray + "Leave a trail of paint behind you as you walk.",
"",
C.cGreen + "Hold " + C.cWhite + "your " + C.cYellow + "paintbrush" + C.cWhite + " (stick) to paint.",
"",
C.cGreen + "Left" + C.cWhite + " and " + C.cGreen + "right click" + C.cWhite + " on your",
C.cYellow + "paintbrush" + C.cWhite + " and " + C.cYellow + "paints" + C.cWhite + " (dyes)",
C.cWhite + "to change paint colors.",
"",
C.cGreen + "Crouch " + C.cWhite + "to say a Bob Ross quote."
}, LineFormat.LORE), -14, Material.PAINTING, (byte) 0, YearMonth.of(2017, Month.JUNE));
_holograms = holograms;
}
/**
* Sets the player's skin to Bob Ross, then gives the player a 'paintbrush' item.
*/
@Override
public void enableCustom(Player player, boolean message)
{
applyArmor(player, message);
GameProfile profile = UtilGameProfile.getGameProfile(player);
profile.getProperties().clear();
profile.getProperties().put("textures", SkinData.BOB_ROSS.getProperty());
DisguisePlayer disguisePlayer = new DisguisePlayer(player, profile);
disguisePlayer.showInTabList(true, 0);
UtilMorph.disguise(player, disguisePlayer, Manager);
givePaintbrush(player);
}
/**
* Restores the player's skin and takes their 'paintbrush' item away.
*/
@Override
public void disableCustom(Player player, boolean message)
{
removeArmor(player);
UtilMorph.undisguise(player, Manager.getDisguiseManager());
takePaintbrush(player);
}
/**
* Detect when a player clicks their paint brush item.
*/
@EventHandler
public void handlePlayerInteract(PlayerInteractEvent event)
{
if (!isActive(event.getPlayer()))
{
return;
}
if (!_inventoryItems.containsKey(event.getPlayer().getUniqueId()))
{
return;
}
if (!_inventoryItems.get(event.getPlayer().getUniqueId()).equals(event.getPlayer().getItemInHand()))
{
return;
}
if (UtilEvent.isAction(event, UtilEvent.ActionType.L))
{
if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{
changePaintColor(event.getPlayer(), true);
}
}
else if (UtilEvent.isAction(event, UtilEvent.ActionType.R))
{
if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{
changePaintColor(event.getPlayer(), false);
}
}
}
/**
* Display a Bob Ross quote above players' heads when they sneak.
* Destroy old paint after a certain amount of time has elapsed.
*/
@EventHandler
public void updateEvent(UpdateEvent event)
{
if (event.getType() == UpdateType.TICK) // do quote displaying
{
for (Player player : getActive())
{
if (player.isSneaking())
{
if (Recharge.Instance.use(player, QUOTE_KEY, QUOTE_COOLDOWN, false, false))
{
// select quote
String[] quote = QUOTES[ThreadLocalRandom.current().nextInt(0, QUOTES.length)];
final Collection<Hologram> holograms = new ArrayList<>();
// add attribution
holograms.add(new Hologram(_holograms, player.getLocation().add(0, QUOTE_HEIGHT, 0), ATTRIBUTION));
// display the quote
double offset = 0.3;
for (int i = quote.length - 1; i >= 0; --i)
{
holograms.add(new Hologram(_holograms, player.getLocation().add(0, QUOTE_HEIGHT + offset, 0),
C.cWhite + quote[i]));
offset += 0.25;
}
for (Hologram hologram : holograms)
{
hologram.setViewDistance(VIEW_DISTANCE);
hologram.setFollowEntity(player);
hologram.start();
}
// remove hologram a certain number of seconds later
Bukkit.getServer().getScheduler().runTaskLater(UtilServer.getPlugin(), () ->
holograms.forEach(Hologram::stop), QUOTE_PERSISTENCE * 20);
}
}
}
}
else if (event.getType() == UpdateType.FASTEST)
{
for (Player player : getActive())
{
if (_inventoryItems.containsKey(player.getUniqueId()))
{
ItemStack item = _inventoryItems.get(player.getUniqueId());
if (item.getType() == Material.STICK && player.getItemInHand().equals(item))
{
togglePainting(player);
}
else if (!player.getItemInHand().equals(item) && item.getType() != Material.STICK)
{
togglePainting(player);
}
}
}
}
}
/**
* When a player moves, paint the ground below them if they have it enabled.
*/
@EventHandler
public void paintGround(PlayerMoveEvent event)
{
Player player = event.getPlayer();
if (!isActive(player))
{
return;
}
for (Location location : _openingTreasure.values())
{
if (location.toVector().isInSphere(event.getPlayer().getLocation().toVector(), TREASURE_RADIUS))
{
return;
}
}
// check if the player has been issued a paintbrush
if (_inventoryItems.containsKey(player.getUniqueId()))
{
ItemStack item = _inventoryItems.get(player.getUniqueId());
if (item.getType() == Material.STICK)
{
return; // player is not painting, do nothing
}
Block block = player.getLocation().getBlock();
Block down = block.getRelative(BlockFace.DOWN);
boolean carpet = block.getType() == Material.CARPET;
// check that there is room to paint and that the block below is solid and not more paint.
if ((block.isEmpty() || carpet) && UtilBlock.fullSolid(down) && !UtilBlock.bottomSlab(down))
{
// if the block is a non-paint carpet
if (carpet && !Manager.getBlockRestore().contains(block))
{
return; // don't paint
}
// mark block as painted
Manager.getBlockRestore().add(block, Material.CARPET.getId(), (byte) (15 - item.getData().getData()),
block.getTypeId(), block.getData(), PAINT_MILLISECONDS);
}
}
}
/**
* Clean hash maps on player disconnect.
*/
@EventHandler
public void onPlayerDisconnect(PlayerQuitEvent event)
{
if (isActive(event.getPlayer()))
{
UUID uuid = event.getPlayer().getUniqueId();
_inventoryItems.remove(uuid);
_paintColors.remove(uuid);
}
}
/**
* Cycle the selected paint color for a player.
*
* @param reverse Whether to cycle backwards through colors.
*/
private void changePaintColor(Player player, boolean reverse)
{
ItemStack item = _inventoryItems.remove(player.getUniqueId());
byte data = selectPaintColor(player, reverse);
ItemStack newItem = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, data, 1,
PAINT_COLORS[data] + " " + PAINT_BRUSHES[ThreadLocalRandom.current().nextInt(0, PAINT_BRUSHES.length)]);
_inventoryItems.put(player.getUniqueId(), newItem);
player.getInventory().remove(item);
player.getInventory().setItem(PAINT_BRUSH_SLOT, newItem);
player.updateInventory();
}
/**
* Toggle whether a player is currently painting or not.
*/
private void togglePainting(Player player)
{
ItemStack item = _inventoryItems.remove(player.getUniqueId());
ItemStack newItem;
if (item.getType() == Material.STICK)
{
byte data;
if (!_paintColors.containsKey(player.getUniqueId()))
{
data = selectPaintColor(player, false);
}
else
{
data = COLOR_ORDER[_paintColors.get(player.getUniqueId())];
}
newItem = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, data, 1,
PAINT_COLORS[data] + " " + PAINT_BRUSHES[ThreadLocalRandom.current().nextInt(0, PAINT_BRUSHES.length)]);
}
else
{
newItem = ItemStackFactory.Instance.CreateStack(Material.STICK, (byte) 0, 1, BRUSH_NAME);
}
_inventoryItems.put(player.getUniqueId(), newItem);
player.getInventory().remove(item);
player.getInventory().setItem(PAINT_BRUSH_SLOT, newItem);
player.updateInventory();
}
/**
* Changes the paint color currently assigned to a player.
* If one is not assigned, a new one will be given.
*
* @param player The player to whom to assign the paint color.
* @param reverse Whether to reverse through paint colors when choosing a new one.
*
* @return the dye data value for the newly selected color.
*/
private byte selectPaintColor(Player player, boolean reverse)
{
UUID uuid = player.getUniqueId();
byte value;
if (!_paintColors.containsKey(uuid))
{
value = (byte) ThreadLocalRandom.current().nextInt(0, 16);
_paintColors.put(uuid, value);
}
else
{
value = _paintColors.get(uuid);
if (reverse)
{
if (--value < 0)
{
value = 15;
}
}
else
{
if (++value > 15)
{
value = 0;
}
}
_paintColors.put(uuid, value);
}
return COLOR_ORDER[value];
}
/**
* Give a paintbrush item to a player.
*/
private void givePaintbrush(Player player)
{
if (!_inventoryItems.containsKey(player.getUniqueId()))
{
ItemStack item = ItemStackFactory.Instance.CreateStack(Material.STICK, (byte) 0, 1, BRUSH_NAME);
player.getInventory().setItem(PAINT_BRUSH_SLOT, item);
_inventoryItems.put(player.getUniqueId(), item);
player.updateInventory();
}
}
/**
* Take the paintbrush item from the player
*/
private void takePaintbrush(Player player)
{
// check that paintbrush has been issued
if (_inventoryItems.containsKey(player.getUniqueId()))
{
ItemStack item = _inventoryItems.remove(player.getUniqueId());
// if player has paintbrush, take it
if (player.getInventory().contains(item))
{
player.getInventory().remove(item);
}
player.updateInventory();
}
}
/**
* Disable painting in the area around treasure being opened.
*/
@EventHandler(priority = EventPriority.LOW)
public void disableOnTreasureStart(TreasureStartEvent event)
{
_openingTreasure.put(event.getPlayer().getUniqueId(), event.getPlayer().getLocation());
Manager.getBlockRestore().restoreBlockAround(Material.CARPET, event.getPlayer().getLocation(), TREASURE_RADIUS);
}
/**
* Enable painting in the area around treasure no longer being opened.
*/
@EventHandler(priority = EventPriority.HIGH)
public void enableOnTreasureFinish(TreasureFinishEvent event)
{
if (_openingTreasure.containsKey(event.getPlayer().getUniqueId()))
{
_openingTreasure.remove(event.getPlayer().getUniqueId());
}
}
}

View File

@ -20,7 +20,7 @@ public class ParticleCoalFumes extends ParticleGadget
public ParticleCoalFumes(GadgetManager manager)
{
super(manager, "Coal Fumes",
UtilText.splitLineToArray(C.cGray + "Being on the Naughty List does have some perks... if you love coal, that is...", LineFormat.LORE),
UtilText.splitLineToArray(C.cGray + "Being on the Naughty List does have some hattori... if you love coal, that is...", LineFormat.LORE),
-1, Material.COAL, (byte) 0);
}

View File

@ -104,6 +104,11 @@ public enum GameDisplay
AlienInvasion("Alien Invasion", Material.ENDER_STONE, (byte) 0, GameCategory.EVENT, 69, false),
MOBA("Heroes of GWEN", Material.PRISMARINE, (byte)0, GameCategory.CLASSICS, 70, true),
MOBATraining("Heroes of GWEN Training", Material.PRISMARINE, (byte)0, GameCategory.CLASSICS, 70, false),
GemHunters("Gem Hunters", Material.EMERALD, (byte) 0, GameCategory.SURVIVAL, 71, false),
Event("Mineplex Event", Material.CAKE, (byte)0, GameCategory.EVENT, 999, false),
Brawl("Brawl", Material.DIAMOND, (byte) 0, GameCategory.EVENT, 998, false);

View File

@ -82,16 +82,23 @@ public class SimpleGui implements ItemRefresher, Listener
{
Validate.isTrue(i >= 0 && i < _size, "Tried to add a gui item outside of inventory range");
GuiItem oldItem = getItem(i);
if (oldItem != null) oldItem.close();
if (item != null)
try
{
_items[i] = item;
item.setup();
}
GuiItem oldItem = getItem(i);
if (oldItem != null) oldItem.close();
refreshItem(i);
if (item != null)
{
_items[i] = item;
item.setup();
}
refreshItem(i);
} catch (Exception ex)
{
System.err.println("Failed to add item " + item + " to GUI " + this + ": ");
ex.printStackTrace();
}
}
public GuiItem getItem(int i)

View File

@ -24,20 +24,21 @@ import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
/**
* Floating text object with interaction and entity follow capabilities.
*/
public class Hologram {
public enum HologramTarget {
BLACKLIST, WHITELIST;
}
private Packet _destroy1_8;
/**
* 1.7 packets uses both EntityIDs while 1.8 uses only the first.
*/
private ArrayList<Integer> _entityIds = new ArrayList<Integer>();
private ArrayList<Integer> _entityIds = new ArrayList<>();
private Entity _followEntity;
private HologramManager _hologramManager;
private String[] _hologramText = new String[0];
/**
* Keeps track of the holograms movements. This fixes offset that
* occasionally happens when moving a hologram around.
@ -49,7 +50,7 @@ public class Hologram {
private Packet[] _packets1_8;
private Packet[] _packets1_9;
private HashSet<UUID> _playersInList = new HashSet<>();
private ArrayList<Player> _playersTracking = new ArrayList<Player>();
private ArrayList<Player> _playersTracking = new ArrayList<>();
private boolean _removeEntityDeath;
private HologramTarget _target = HologramTarget.BLACKLIST;
private int _viewDistance = 70;
@ -60,15 +61,42 @@ public class Hologram {
private long _maxLifetime = -1;
private long _startTime;
public Hologram(HologramManager hologramManager, Location location, String... text) {
this(hologramManager, location, false, -1l, text);
/**
* Construct a standard hologram.
*
* @param hologramManager The hologram manager.
* @param location The location at which to display the hologram.
* @param text An array of text lines which the hologram should display.
*/
public Hologram(HologramManager hologramManager, Location location, String... text)
{
this(hologramManager, location, false, -1L, text);
}
public Hologram(HologramManager hologramManager, Location location, boolean hideBoundingBox, String... text) {
this(hologramManager, location, hideBoundingBox, -1l, text);
/**
* Construct a hologram with a specified bounding box.
*
* @param hologramManager The hologram manager.
* @param location The location at which to display the hologram.
* @param hideBoundingBox Whether to hide the bounding box of the hologram.
* @param text An array of text lines which the hologram should display.
*/
public Hologram(HologramManager hologramManager, Location location, boolean hideBoundingBox, String... text)
{
this(hologramManager, location, hideBoundingBox, -1L, text);
}
public Hologram(HologramManager hologramManager, Location location, boolean hideBoundingBox, long maxLifetime, String... text) {
/**
* Construct a hologram with a limited lifetime.
*
* @param hologramManager The hologram manager.
* @param location The location at which to display the hologram.
* @param hideBoundingBox Whether to hide the bounding box of the hologram.
* @param maxLifetime The max lifetime of the hologram, specified in milliseconds.
* @param text An array of text lines which the hologram should display.
*/
public Hologram(HologramManager hologramManager, Location location, boolean hideBoundingBox, long maxLifetime, String... text)
{
_hologramManager = hologramManager;
_location = location.clone();
_maxLifetime = maxLifetime;
@ -76,9 +104,16 @@ public class Hologram {
setText(text);
}
public Hologram setInteraction(HologramInteraction interact) {
/**
* Set the interaction handler for the hologram.
*
* @param interact The handler.
*
* @return the original hologram object.
*/
public Hologram setInteraction(HologramInteraction interact)
{
_interaction = interact;
return this;
}
@ -89,37 +124,50 @@ public class Hologram {
/**
* Adds the player to the Hologram to be effected by Whitelist or Blacklist
*/
public Hologram addPlayer(Player player) {
public Hologram addPlayer(Player player)
{
return addPlayer(player.getUniqueId());
}
/**
* Adds the player to the Hologram to be effected by Whitelist or Blacklist
*/
public Hologram addPlayer(UUID player) {
public Hologram addPlayer(UUID player)
{
_playersInList.add(player);
return this;
}
/**
* Warning! Bounding box if hidden will hide holograms for 1.8 to 1.8.2
* Hides the bounding box for the hologram. <br>
*
* <b>Warning! Bounding box if hidden will hide holograms for 1.8 to 1.8.2</b>
*
* @return
* @return the original hologram object.
*/
public Hologram setHideBoundingBox() {
public Hologram setHideBoundingBox()
{
_hideBoundingBox = true;
return this;
}
/**
* Is there a player entry in the hologram for Whitelist and Blacklist
* @return if there is a player entry in the holograms whitelist/blacklist.
*/
public boolean containsPlayer(Player player) {
public boolean containsPlayer(Player player)
{
return _playersInList.contains(player.getUniqueId());
}
protected Packet getDestroyPacket() {
if (_makeDestroyPackets) {
/**
* Generates a packet to destroy the hologram client-side.
*
* @return the packet.
*/
protected Packet getDestroyPacket()
{
if (_makeDestroyPackets)
{
makeDestroyPacket();
_makeDestroyPackets = false;
}
@ -127,32 +175,44 @@ public class Hologram {
return _destroy1_8;
}
public Entity getEntityFollowing() {
/**
* @return the entity that this hologram is currently following.
*/
public Entity getEntityFollowing()
{
return _followEntity;
}
/**
* Get who can see the hologram
*
* @Whitelist = Only people added can see the hologram
* @Blacklist = Anyone but people added can see the hologram
* @return The functionality that is currently being used for the object's internal
* player list.
* {@link HologramTarget#WHITELIST} = Only people added can see the hologram
* {@link HologramTarget#BLACKLIST} = Anyone but people added can see the hologram
*/
public HologramTarget getHologramTarget() {
public HologramTarget getHologramTarget()
{
return _target;
}
/**
* Get the hologram location
* @return the current location of the hologram.
*/
public Location getLocation() {
public Location getLocation()
{
return _location.clone();
}
protected ArrayList<Player> getNearbyPlayers() {
ArrayList<Player> nearbyPlayers = new ArrayList<Player>();
/**
* @return A list of players that can currently see the hologram.
*/
protected ArrayList<Player> getNearbyPlayers()
{
ArrayList<Player> nearbyPlayers = new ArrayList<>();
for (Player player : getLocation().getWorld().getPlayers()) {
if (isVisible(player)) {
for (Player player : getLocation().getWorld().getPlayers())
{
if (isVisible(player))
{
nearbyPlayers.add(player);
}
}
@ -160,26 +220,37 @@ public class Hologram {
return nearbyPlayers;
}
protected ArrayList<Player> getPlayersTracking() {
/**
* @return The list of players that are in the holograms whitelist or blacklist.
*/
protected ArrayList<Player> getPlayersTracking()
{
return _playersTracking;
}
protected void checkSpawnPackets() {
if (_makeSpawnPackets) {
/**
* Generates hologram spawn packets if they have not been created already.
*/
protected void checkSpawnPackets()
{
if (_makeSpawnPackets)
{
makeSpawnPackets();
_makeSpawnPackets = false;
}
}
/**
* Get the text in the hologram
* @return the current text being displayed by the hologram.
*/
public String[] getText() {
public String[] getText()
{
// We reverse it again as the hologram would otherwise display the text
// from the bottom row to the top row
String[] reversed = new String[_hologramText.length];
for (int i = 0; i < reversed.length; i++) {
for (int i = 0; i < reversed.length; i++)
{
reversed[i] = _hologramText[reversed.length - (i + 1)];
}
@ -187,27 +258,45 @@ public class Hologram {
}
/**
* Get the view distance the hologram is viewable from. Default is 70
* @return the view distance the hologram is viewable from. Default is 70
*/
public int getViewDistance() {
public int getViewDistance()
{
return _viewDistance;
}
/**
* Is the hologram holograming?
* @return Is the hologram holograming?
*/
public boolean isInUse() {
public boolean isInUse()
{
return _lastMovement != null;
}
public boolean isRemoveOnEntityDeath() {
/**
* @return whether to delete the hologram when the entity it is following dies.
*/
public boolean isRemoveOnEntityDeath()
{
return _removeEntityDeath;
}
public boolean isVisible(Player player) {
if (getLocation().getWorld() == player.getWorld()) {
if ((getHologramTarget() == HologramTarget.WHITELIST) == containsPlayer(player)) {
if (getLocation().distance(player.getLocation()) < getViewDistance()) {
/**
* Determines whether the hologram is visible to a player based on view distance, whitelist /
* blacklist, and current world.
*
* @param player The player to check.
*
* @return whether the hologram is visible to the player.
*/
public boolean isVisible(Player player)
{
if (getLocation().getWorld() == player.getWorld())
{
if ((getHologramTarget() == HologramTarget.WHITELIST) == containsPlayer(player))
{
if (getLocation().distance(player.getLocation()) < getViewDistance())
{
return true;
}
}
@ -216,34 +305,49 @@ public class Hologram {
return false;
}
private void makeDestroyPacket() {
/**
* Generates a packet to destroy the hologram client-side.
*/
private void makeDestroyPacket()
{
int[] entityIds1_8 = new int[_entityIds.size()];
for (int i = 0; i < _entityIds.size(); i++) {
for (int i = 0; i < _entityIds.size(); i++)
{
entityIds1_8[i] = _entityIds.get(i);
}
_destroy1_8 = new PacketPlayOutEntityDestroy(entityIds1_8);
}
private void makeSpawnPackets() {
/**
* Generates spawn packets for the hologram.
*/
private void makeSpawnPackets()
{
_packets1_8 = new Packet[_hologramText.length];
_packets1_9 = new Packet[_hologramText.length];
if (_entityIds.size() < _hologramText.length) {
if (_entityIds.size() < _hologramText.length)
{
_makeDestroyPackets = true;
for (int i = _entityIds.size(); i < _hologramText.length; i++) {
for (int i = _entityIds.size(); i < _hologramText.length; i++)
{
_entityIds.add(Integer.valueOf(UtilEnt.getNewEntityId()));
}
} else {
}
else
{
_makeDestroyPackets = true;
while (_entityIds.size() > _hologramText.length) {
while (_entityIds.size() > _hologramText.length)
{
_entityIds.remove(_hologramText.length);
}
}
for (int textRow = 0; textRow < _hologramText.length; textRow++) {
for (int textRow = 0; textRow < _hologramText.length; textRow++)
{
PacketPlayOutSpawnEntityLiving packet1_8 = makeSpawnPacket1_8(textRow, _entityIds.get(textRow), _hologramText[textRow]);
PacketPlayOutSpawnEntityLiving packet1_9 = makeSpawnPacket1_9(textRow, _entityIds.get(textRow), _hologramText[textRow]);
@ -253,7 +357,7 @@ public class Hologram {
}
/**
* Used for sending 1.9 clients holograms with no bounding boxes
* Used for sending 1.9 clients holograms with no bounding boxes.
*/
private PacketPlayOutSpawnEntityLiving makeSpawnPacket1_9(int textRow, int entityId, String lineOfText)
{
@ -269,7 +373,11 @@ public class Hologram {
return packet;
}
private PacketPlayOutSpawnEntityLiving makeSpawnPacket1_8(int textRow, int entityId, String lineOfText) {
/**
* Used for sending 1.8 clients holograms.
*/
private PacketPlayOutSpawnEntityLiving makeSpawnPacket1_8(int textRow, int entityId, String lineOfText)
{
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving();
DataWatcher watcher = new DataWatcher(null);
@ -290,86 +398,122 @@ public class Hologram {
}
/**
* Removes the player from the Hologram so they are no longer effected by
* Whitelist or Blacklist
* Removes a player from the Hologram so they are no longer effected by
* whitelist or blacklist.
*
* @param player The player to remove.
*
* @return the original hologram object.
*/
public Hologram removePlayer(Player player) {
public Hologram removePlayer(Player player)
{
return removePlayer(player.getUniqueId());
}
/**
* Removes the player from the Hologram so they are no longer effected by
* Whitelist or Blacklist
* whitelist or blacklist
*
* @param player The player to remove.
*
* @return the original hologram object.
*/
public Hologram removePlayer(UUID player) {
public Hologram removePlayer(UUID player)
{
_playersInList.remove(player);
return this;
}
/**
* If the entity moves, the hologram will update its position to appear
* relative to the movement.
*
* @Please note the hologram updates every tick.
* Sets an entity to which the hologram will remain relative to in position.
*
* @param entityToFollow the entity which to follow.
*
* @return the original hologram object.
*/
public Hologram setFollowEntity(Entity entityToFollow) {
public Hologram setFollowEntity(Entity entityToFollow)
{
_followEntity = entityToFollow;
relativeToEntity = entityToFollow == null ? null
: _location.clone().subtract(entityToFollow.getLocation()).toVector();
if (entityToFollow != null)
{
relativeToEntity = _location.clone().subtract(entityToFollow.getLocation()).toVector();
}
return this;
}
/**
* Set who can see the hologram
*
* @Whitelist = Only people added can see the hologram
* @Blacklist = Anyone but people added can see the hologram
* Set how the hologram's internal player list is used.
*
* @param newTarget The target which defines how the list is used.
* {@link HologramTarget#WHITELIST} = Only people added can see the hologram
* {@link HologramTarget#BLACKLIST} = Anyone but people added can see the hologram
*
* @retuen the original hologram object.
*/
public Hologram setHologramTarget(HologramTarget newTarget) {
public Hologram setHologramTarget(HologramTarget newTarget)
{
_target = newTarget;
return this;
}
/**
* Sets the hologram to appear at this location
* Change the location of the hologram.
*
* @param newLocation the location to which to teleport the hologram.
*
* @return the original hologram object.
*/
public Hologram setLocation(Location newLocation) {
public Hologram setLocation(Location newLocation)
{
_makeSpawnPackets = true;
Location oldLocation = getLocation();
_location = newLocation.clone();
if (getEntityFollowing() != null) {
if (getEntityFollowing() != null)
{
relativeToEntity = _location.clone().subtract(getEntityFollowing().getLocation()).toVector();
}
if (isInUse()) {
if (isInUse())
{
ArrayList<Player> canSee = getNearbyPlayers();
Iterator<Player> itel = _playersTracking.iterator();
while (itel.hasNext()) {
while (itel.hasNext())
{
Player player = itel.next();
if (!canSee.contains(player)) {
if (!canSee.contains(player))
{
itel.remove();
if (player.getWorld() == getLocation().getWorld()) {
if (player.getWorld() == getLocation().getWorld())
{
UtilPlayer.sendPacket(player, getDestroyPacket());
}
}
}
itel = canSee.iterator();
checkSpawnPackets();
while (itel.hasNext()) {
while (itel.hasNext())
{
Player player = itel.next();
if (!_playersTracking.contains(player)) {
if (!_playersTracking.contains(player))
{
_playersTracking.add(player);
itel.remove();
UtilPlayer.sendPacket(player, UtilPlayer.is1_9(player) ? _packets1_9 : _packets1_8);
}
}
if (!canSee.isEmpty()) {
if (!canSee.isEmpty())
{
_lastMovement.add(new Vector(newLocation.getX() - oldLocation.getX(),
newLocation.getY() - oldLocation.getY(), newLocation.getZ() - oldLocation.getZ()));
@ -378,12 +522,38 @@ public class Hologram {
int z = (int) Math.floor(32 * _lastMovement.getZ());
Packet[] packets1_8 = new Packet[_hologramText.length];
Packet[] packets1_9 = new Packet[_hologramText.length];
int i = 0;
if (x >= -128 && x <= 127 && y >= -128 && y <= 127 && z >= -128 && z <= 127) {
// Generate packets for 1.9 clients
x = (int) Math.floor(32 * newLocation.getX());
z = (int) Math.floor(32 * newLocation.getZ());
_lastMovement = new Vector(newLocation.getX() - (x / 32D), 0, newLocation.getZ() - (z / 32D));
for (Integer entityId : _entityIds)
{
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport();
teleportPacket.a = entityId;
teleportPacket.b = x;
teleportPacket.c = (int) Math.floor((oldLocation.getY() + (-2.1) + ((double) i * 0.285)) * 32);
teleportPacket.d = z;
packets1_9[i] = teleportPacket;
i++;
}
i = 0;
// Generate move packets for 1.8 clients if the move is small enough.
if (x >= -128 && x <= 127 && y >= -128 && y <= 127 && z >= -128 && z <= 127)
{
_lastMovement.subtract(new Vector(x / 32D, y / 32D, z / 32D));
for (Integer entityId : _entityIds) {
for (Integer entityId : _entityIds)
{
PacketPlayOutEntity.PacketPlayOutRelEntityMove relMove = new PacketPlayOutEntity.PacketPlayOutRelEntityMove();
relMove.a = entityId;
@ -394,80 +564,109 @@ public class Hologram {
packets1_8[i] = relMove;
i++;
}
} else {
x = (int) Math.floor(32 * newLocation.getX());
z = (int) Math.floor(32 * newLocation.getZ());
_lastMovement = new Vector(newLocation.getX() - (x / 32D), 0, newLocation.getZ() - (z / 32D));
for (Integer entityId : _entityIds) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport();
teleportPacket.a = entityId;
teleportPacket.b = x;
teleportPacket.c = (int) Math.floor((oldLocation.getY() + (-2.1) + ((double) i * 0.285)) * 32);
teleportPacket.d = z;
packets1_8[i] = teleportPacket;
i++;
}
}
else // Use teleport packets
{
packets1_8 = packets1_9;
}
for (Player player : canSee) {
for (Packet packet : packets1_8) {
UtilPlayer.sendPacket(player, packet);
for (Player player : canSee)
{
if (UtilPlayer.is1_9(player))
{
for (Packet packet : packets1_9)
{
UtilPlayer.sendPacket(player, packet);
}
}
else
{
for (Packet packet : packets1_8)
{
UtilPlayer.sendPacket(player, packet);
}
}
}
}
}
return this;
}
/**
* @return the time at which the hologram was last started.
*/
public long getStartTime()
{
return _startTime;
}
/**
* @return the max time after the hologram was started for which it will live.
*/
public long getMaxLifetime()
{
return _maxLifetime;
}
public Hologram setRemoveOnEntityDeath() {
/**
* Set the hologram to stop when the entity it is following dies.
*
* @return the original hologram object.
*/
public Hologram setRemoveOnEntityDeath()
{
_removeEntityDeath = true;
return this;
}
public boolean isEntityId(int entityId) {
/**
* @param entityId an entity id.
*
* @return whether the entity ID is represented by this hologram object.
*/
public boolean isEntityId(int entityId)
{
return _entityIds.contains(entityId);
}
/**
* Set the hologram text
*
* @param newLines array of text lines for the hologram to display.
*
* @return the original hologram object.
*/
public Hologram setText(String... newLines) {
public Hologram setText(String... newLines)
{
String[] newText = new String[newLines.length];
for (int i = 0; i < newText.length; i++) {
for (int i = 0; i < newText.length; i++)
{
newText[i] = newLines[newText.length - (i + 1)];
}
if (newText.equals(_hologramText))
{
return this;
}
if (isInUse()) {
if (isInUse())
{
int[] destroy1_8 = new int[0];
ArrayList<Packet> packets1_8 = new ArrayList<Packet>();
ArrayList<Packet> packets1_8 = new ArrayList<>();
ArrayList<Packet> packets1_9 = new ArrayList<>();
if (_hologramText.length != newText.length) {
if (_hologramText.length != newText.length)
{
_makeDestroyPackets = true;
}
for (int i = 0; i < Math.max(_hologramText.length, newText.length); i++) {
// If more lines than previously
if (i >= _hologramText.length) {
for (int i = 0; i < Math.max(_hologramText.length, newText.length); i++)
{
if (i >= _hologramText.length) // If more lines than previously
{
// Add entity id and send spawn packets
// You add a entity id because the new hologram needs
int entityId = UtilEnt.getNewEntityId();
@ -476,14 +675,16 @@ public class Hologram {
packets1_8.add(makeSpawnPacket1_8(i, entityId, newText[i]));
packets1_9.add(makeSpawnPacket1_9(i, entityId, newText[i]));
}
// If less lines than previously
else if (i >= newText.length) {
else if (i >= newText.length) // If less lines than previously
{
// Remove entity id and send destroy packets
Integer entityId = _entityIds.remove(newText.length);
destroy1_8 = Arrays.copyOf(destroy1_8, destroy1_8.length + 1);
destroy1_8[destroy1_8.length - 1] = entityId;
} else if (!newText[i].equals(_hologramText[i])) {
}
else if (!newText[i].equals(_hologramText[i]))
{
// Send update metadata packets
Integer entityId = _entityIds.get(i);
@ -495,10 +696,12 @@ public class Hologram {
watcher1_8.a(2, newText[i], EntityArmorStand.META_CUSTOMNAME, newText[i]);
watcher1_8.a(3, (byte) 1, EntityArmorStand.META_CUSTOMNAME_VISIBLE, true);
}
{
watcher1_9.a(0, (byte) 32, EntityArmorStand.META_ENTITYDATA, (byte) 32);
watcher1_9.a(2, newText[i], EntityArmorStand.META_CUSTOMNAME, newText[i]);
watcher1_9.a(3, (byte) 1, EntityArmorStand.META_CUSTOMNAME_VISIBLE, true);
if (_hideBoundingBox)
{
watcher1_9.a(10, (byte) 16, EntityArmorStand.META_ARMOR_OPTION, (byte) 16);
@ -510,13 +713,16 @@ public class Hologram {
}
}
if (destroy1_8.length > 0) {
if (destroy1_8.length > 0)
{
packets1_8.add(new PacketPlayOutEntityDestroy(destroy1_8));
packets1_9.add(new PacketPlayOutEntityDestroy(destroy1_8));
}
for (Player player : _playersTracking) {
for (Player player : _playersTracking)
{
List<Packet> packets = UtilPlayer.is1_9(player) ? packets1_9 : packets1_8;
for (Packet packet : packets)
{
UtilPlayer.sendPacket(player, packet);
@ -532,18 +738,26 @@ public class Hologram {
/**
* Set the distance the hologram is viewable from. Default is 70
*
* @param newDistance The distance in blocks.
*
* @return the original hologram object.
*/
public Hologram setViewDistance(int newDistance) {
public Hologram setViewDistance(int newDistance)
{
_viewDistance = newDistance;
return setLocation(getLocation());
}
/**
* Start the hologram
* Start the hologram, displaying it to players.
*
* @return the original hologram object.
*/
public Hologram start() {
if (!isInUse()) {
public Hologram start()
{
if (!isInUse())
{
_startTime = System.currentTimeMillis();
_hologramManager.addHologram(this);
@ -553,9 +767,13 @@ public class Hologram {
_lastMovement = new Vector();
}
return this;
}
/**
* Sends hologram spawn packets to players.
*/
private void sendPackets()
{
checkSpawnPackets();
@ -566,6 +784,13 @@ public class Hologram {
}
}
/**
* Generates spawn packets based on minecraft version.
*
* @param player The player for which to generate the packets.
*
* @return the list of packets generated.
*/
public Packet[] getSpawnPackets(Player player)
{
checkSpawnPackets();
@ -574,13 +799,19 @@ public class Hologram {
}
/**
* Stop the hologram
* Stop the hologram, effectively destroying it once
* garbage collection has occurred.
*
* @return the original hologram object.
*/
public Hologram stop() {
if (isInUse()) {
public Hologram stop()
{
if (isInUse())
{
_hologramManager.removeHologram(this);
for (Player player : _playersTracking) {
for (Player player : _playersTracking)
{
UtilPlayer.sendPacket(player, getDestroyPacket());
}
@ -591,4 +822,11 @@ public class Hologram {
return this;
}
/**
* Enum defining to whom the hologram is displayed.
*/
public enum HologramTarget
{
BLACKLIST, WHITELIST
}
}

View File

@ -81,6 +81,7 @@ public class HologramManager extends MiniPlugin implements IPacketHandler
hologram.stop();
continue;
}
if (!hologram.relativeToEntity.equals(following.getLocation().subtract(hologram.getLocation()).toVector()))
{
// And we do this so in the rare offchance it changes by a decimal. It doesn't start turning wonky.

View File

@ -1,13 +1,7 @@
package mineplex.core.itemstack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilInv;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Color;
@ -21,10 +15,18 @@ import org.bukkit.inventory.meta.BannerMeta;
import org.bukkit.inventory.meta.FireworkEffectMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.potion.PotionEffect;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilInv;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ItemBuilder
{
@ -53,14 +55,15 @@ public class ItemBuilder
private Color _color;
private short _data;
private short _durability;
private final HashMap<Enchantment, Integer> _enchants = new HashMap<Enchantment, Integer>();
private final List<String> _lore = new ArrayList<String>();
private final Map<Enchantment, Integer> _enchants = new HashMap<>();
private final List<String> _lore = new ArrayList<>();
private Material _mat;
private String _title = null;
private boolean _unbreakable;
private boolean _glow;
private String _playerHeadName = null;
private HashSet<ItemFlag> _itemFlags = new HashSet<ItemFlag>();
private Set<ItemFlag> _itemFlags = new HashSet<>();
private List<PotionEffect> _potionEffects = new ArrayList<>();
public ItemBuilder(ItemStack item)
{
@ -86,6 +89,13 @@ public class ItemBuilder
{
setColor(((LeatherArmorMeta) meta).getColor());
}
else if (meta instanceof PotionMeta)
{
for (PotionEffect effect : ((PotionMeta) meta).getCustomEffects())
{
addPotionEffect(effect);
}
}
_itemFlags.addAll(meta.getItemFlags());
@ -124,7 +134,7 @@ public class ItemBuilder
return this;
}
public HashSet<ItemFlag> getItemFlags()
public Set<ItemFlag> getItemFlags()
{
return _itemFlags;
}
@ -279,6 +289,22 @@ public class ItemBuilder
{
((BannerMeta) meta).setBaseColor(DyeColor.getByColor(_color));
}
else if (meta instanceof PotionMeta)
{
PotionMeta potionMeta = (PotionMeta) meta;
for (PotionEffect effect : _potionEffects)
{
potionMeta.addCustomEffect(effect, true);
}
if (!_potionEffects.isEmpty())
{
potionMeta.setMainEffect(_potionEffects.get(0).getType());
}
meta = potionMeta;
}
meta.addItemFlags(getItemFlags().toArray(new ItemFlag[0]));
meta.spigot().setUnbreakable(isUnbreakable());
@ -307,7 +333,7 @@ public class ItemBuilder
}
newBuilder.setColor(_color);
// newBuilder.potion = potion;
newBuilder.setDurability(_durability);
newBuilder.setData(_data);
@ -321,11 +347,16 @@ public class ItemBuilder
newBuilder.setItemFlags(_itemFlags);
newBuilder.setPlayerHead(_playerHeadName);
for (PotionEffect potionEffect : _potionEffects)
{
newBuilder.addPotionEffect(potionEffect);
}
return newBuilder;
}
public HashMap<Enchantment, Integer> getAllEnchantments()
public Map<Enchantment, Integer> getAllEnchantments()
{
return _enchants;
}
@ -452,4 +483,9 @@ public class ItemBuilder
return this;
}
public ItemBuilder addPotionEffect(PotionEffect effect)
{
_potionEffects.add(effect);
return this;
}
}

View File

@ -1000,10 +1000,10 @@ public class ItemStackFactory extends MiniPlugin
ItemMeta meta = stack.getItemMeta();
if (meta == null)
return 0;
return empty;
if (meta.getLore() == null)
return 0;
return empty;
for (String cur : meta.getLore())
if (cur.contains(var))
@ -1021,7 +1021,7 @@ public class ItemStackFactory extends MiniPlugin
}
return 0;
return empty;
}
public void SetLoreVar(ItemStack stack, String var, String value)

View File

@ -2,6 +2,15 @@ package mineplex.core.monitor;
import java.util.HashSet;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
@ -10,17 +19,6 @@ import mineplex.core.common.util.F;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
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.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import net.minecraft.server.v1_8_R3.MinecraftServer;
public class LagMeter extends MiniPlugin
{
private CoreClientManager _clientManager;
@ -31,12 +29,6 @@ public class LagMeter extends MiniPlugin
private long _lastAverage;
private long _start;
private long _lastTick = 0;
private boolean _timingsRunning;
private boolean _timingsPasted;
private long _timingsStarted;
private HashSet<Player> _monitoring = new HashSet<Player>();
public LagMeter(JavaPlugin plugin, CoreClientManager clientManager)
@ -98,24 +90,6 @@ public class LagMeter extends MiniPlugin
_lastRun = now;
_count++;
if (System.currentTimeMillis() - _start > 30000)
{
if (_timingsRunning)
{
if (System.currentTimeMillis() - _timingsStarted > 30000)
{
getPlugin().getServer().dispatchCommand(Bukkit.getConsoleSender(), "timings paste");
_timingsRunning = false;
}
}
else if (_ticksPerSecond < 10)
{
_timingsRunning = true;
_timingsStarted = System.currentTimeMillis();
getPlugin().getServer().dispatchCommand(Bukkit.getConsoleSender(), "timings on");
}
}
}
public double getTicksPerSecond()

View File

@ -188,4 +188,10 @@ public class Npc
{
_location = location;
}
@Override
public String toString()
{
return "NPC[entity=" + _entity + "]";
}
}

View File

@ -104,8 +104,6 @@ public class PowerPlayClubRepository implements Listener {
PowerPlayData cached = getCachedData(player);
List<PowerPlayClubRewards.PowerPlayClubItem> list = PowerPlayClubRewards.rewardsForMonths(cached.getUsableCosmeticMonths());
PowerPlayClubRewards.rewardsForMonths(cached.getUsableCosmeticMonths()).forEach(item -> item.reward(player));
// Gives Metal Man for anyone subscribed

View File

@ -38,6 +38,7 @@ public class PowerPlayClubRewards
.put(YearMonth.of(2017, Month.MARCH), new UnknownSalesPackageItem("Gold Pot Morph"))
.put(YearMonth.of(2017, Month.APRIL), new UnknownSalesPackageItem("Bumblebee's Wings"))
.put(YearMonth.of(2017, Month.MAY), new UnknownSalesPackageItem("King"))
.put(YearMonth.of(2017, Month.JUNE), new UnknownSalesPackageItem("Bob Ross Morph"))
.build();
public interface PowerPlayClubItem
@ -48,6 +49,15 @@ public class PowerPlayClubRewards
void reward(Player player);
}
private static final PowerPlayClubItem MISSING = new PowerPlayClubItem()
{
@Override
public String getPrizeName() { return "Coming soon!"; }
@Override
public void reward(Player player) { }
};
private static class UnknownSalesPackageItem implements PowerPlayClubItem
{
private static final DonationManager _donationManager = Managers.require(DonationManager.class);
@ -103,7 +113,7 @@ public class PowerPlayClubRewards
public static List<PowerPlayClubItem> rewardsForMonths(Set<YearMonth> months)
{
return months.stream().sorted().map(rewards::get).collect(Collectors.toList());
return months.stream().sorted().map(PowerPlayClubRewards::getReward).collect(Collectors.toList());
}
public static Map<YearMonth, PowerPlayClubItem> rewards()
@ -111,6 +121,10 @@ public class PowerPlayClubRewards
return rewards;
}
public static PowerPlayClubItem getReward(YearMonth month)
{
return rewards.getOrDefault(month, MISSING);
}
public static void giveAllItems(Player player, InventoryManager inventoryManager, PowerPlayClubRepository repo)
{

View File

@ -1,12 +1,18 @@
package mineplex.core.powerplayclub;
import com.google.common.base.Objects;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import com.google.common.base.MoreObjects;
public class PowerPlayData
{
/* If this is set, the player's subscription is planned to recur.
@ -19,6 +25,9 @@ public class PowerPlayData
*/
private final Optional<LocalDate> _nextClaimDate;
// The source set of subscriptions from which this was built
private final List<Subscription> _subscriptions;
// The months where the player hasn't claimed chests/amplifiers
private final Set<YearMonth> _unclaimedMonths;
@ -29,11 +38,11 @@ public class PowerPlayData
*/
private final Set<YearMonth> _cosmeticMonths;
static PowerPlayData fromSubsAndClaims(List<Subscription> subscriptions, List<YearMonth> claimedMonths)
public static PowerPlayData fromSubsAndClaims(List<Subscription> subscriptions, List<YearMonth> claimedMonths)
{
if (subscriptions.isEmpty())
{
return new PowerPlayData(Optional.empty(), new HashSet<>(), new HashSet<>());
return new PowerPlayData(subscriptions, Optional.empty(), new HashSet<>(), new HashSet<>());
}
final LocalDate today = LocalDate.now();
@ -96,7 +105,7 @@ public class PowerPlayData
.map(YearMonth::from)
.collect(Collectors.toSet());
return new PowerPlayData(nextClaimDate, unclaimedMonths, cosmeticMonths);
return new PowerPlayData(subscriptions, nextClaimDate, unclaimedMonths, cosmeticMonths);
}
private static List<LocalDate> buildMonths(Subscription subscription)
@ -126,10 +135,10 @@ public class PowerPlayData
}
}
static class Subscription
public static class Subscription
{
private final LocalDate _startDate;
private final SubscriptionDuration _duration;
public final LocalDate _startDate;
public final SubscriptionDuration _duration;
Subscription(LocalDate startDate, SubscriptionDuration duration)
{
@ -143,13 +152,19 @@ public class PowerPlayData
MONTH, YEAR
}
private PowerPlayData(Optional<LocalDate> nextClaimDate, Set<YearMonth> unclaimedMonths, Set<YearMonth> cosmeticMonths)
private PowerPlayData(List<Subscription> subscriptions, Optional<LocalDate> nextClaimDate, Set<YearMonth> unclaimedMonths, Set<YearMonth> cosmeticMonths)
{
_subscriptions = subscriptions;
_nextClaimDate = nextClaimDate;
_unclaimedMonths = unclaimedMonths;
_cosmeticMonths = cosmeticMonths;
}
public List<Subscription> getSubscriptions()
{
return _subscriptions;
}
public Optional<LocalDate> getNextClaimDate()
{
return _nextClaimDate;
@ -173,7 +188,7 @@ public class PowerPlayData
@Override
public String toString()
{
return Objects.toStringHelper(this)
return MoreObjects.toStringHelper(this)
.add("_nextClaimDate", _nextClaimDate)
.add("_unclaimedMonths", _unclaimedMonths)
.add("_cosmeticMonths", _cosmeticMonths)

View File

@ -0,0 +1,240 @@
package mineplex.core.quests;
import org.bukkit.ChatColor;
import mineplex.core.game.GameCategory;
import mineplex.core.game.GameDisplay;
/**
* Quest
*
* @author xXVevzZXx
*/
public class Quest
{
private static final Object _progressLock = new Object();
private int _questID;
private String _questName;
private String _questTask;
private int _questCost;
private String _questReward;
private QuestRarity _rarity;
private String _type;
private GameDisplay _game;
private GameCategory _gameCategory;
private boolean _generalGame;
private boolean _overworld;
private TriggerType _trigger;
private String[] _item;
private int _statToComplete;
private long _lastCompleted;
private int _current;
private int _timesCompleted;
public Quest(int questID, String name, String task, int cost, String reward, QuestRarity rarity, String type, TriggerType trigger, String[] item, int statToComplete)
{
_questID = questID;
_questName = name;
_questTask = task;
_questCost = cost;
_questReward = reward;
_rarity = rarity;
_trigger = trigger;
_item = item;
_statToComplete = statToComplete;
_type = type;
if (GameDisplay.matchName(type) != null)
_game = GameDisplay.matchName(type);
try
{
_gameCategory = GameCategory.valueOf(type);
}
catch (IllegalArgumentException e) {}
_generalGame = _type.equalsIgnoreCase("General");
if (!_generalGame)
_overworld = (_game == null && _gameCategory == null);
}
public int getID()
{
return _questID;
}
public String getName()
{
return _questName;
}
public String getTask()
{
return _questTask;
}
public int getCost()
{
return _questCost;
}
public String getReward()
{
return _questReward;
}
public QuestRarity getRarity()
{
return _rarity;
}
public GameDisplay getGame()
{
return _game;
}
public GameCategory getGameCategory()
{
return _gameCategory;
}
public boolean isInOverworld()
{
return _overworld;
}
public TriggerType getTrigger()
{
return _trigger;
}
public String[] getItem()
{
return _item;
}
public int getStatToComplete()
{
return _statToComplete;
}
public int getProgress()
{
return _current;
}
public void setProgress(int progress)
{
_current = progress;
}
public void increment(int value)
{
synchronized (_progressLock)
{
_current += value;
}
}
public void increment()
{
synchronized (_progressLock)
{
_current++;
}
}
public void decrement(int value)
{
synchronized (_progressLock)
{
_current -= value;
}
}
public void decrement()
{
synchronized (_progressLock)
{
_current--;
}
}
public boolean isCompleted()
{
return _current >= _statToComplete;
}
public void setLastCompleted(long time)
{
_lastCompleted = time;
}
public long getLastCompleted()
{
return _lastCompleted;
}
public String getRewardName()
{
return _questReward.split(":")[0];
}
public int getRewardAmount()
{
return Integer.parseInt(_questReward.split(":")[1]);
}
public void setTimesCompleted(int amount)
{
_timesCompleted = amount;
}
public int getTimesCompleted()
{
return _timesCompleted;
}
public boolean isActive()
{
return _current != -1;
}
public String[] getQuestInfo()
{
String[] info = new String[]{
ChatColor.LIGHT_PURPLE + getTask(), "", ChatColor.GRAY + "Reward: " + ChatColor.AQUA + getRewardAmount() + " " + getRewardName(),
"",
ChatColor.GRAY + "Progress: "
+ (_current == -1 ? ChatColor.RED + "Not in your " + QuestManager.QUEST_NAME + " Inventory" :
(isCompleted() ? ChatColor.GREEN + "Completed!" :
ChatColor.YELLOW + "" + getProgress() + ChatColor.GRAY + "/" + ChatColor.YELLOW + getStatToComplete())),
"",
getRarity().getColor() + "" + ChatColor.BOLD + getRarity().toString(),
};
return info;
}
public boolean isGeneral()
{
return _generalGame;
}
@Override
public Quest clone()
{
return new Quest(_questID, _questName, _questTask, _questCost, _questReward, _rarity, _type, _trigger, _item, _statToComplete);
}
}

View File

@ -0,0 +1,94 @@
package mineplex.core.quests;
import java.util.ArrayList;
import mineplex.core.hologram.Hologram;
/**
* QuestClientData
*
* @author xXVevzZXx
*/
public class QuestClientData
{
private ArrayList<Quest> _quests = new ArrayList<>();
private Hologram _hologram;
public void addQuest(Quest quest)
{
_quests.add(quest);
}
public ArrayList<Quest> getQuests()
{
ArrayList<Quest> quests = new ArrayList<>();
for (Quest quest : _quests)
{
if (quest.getProgress() != -1)
quests.add(quest);
}
return quests;
}
public boolean hasQuest(Quest quest)
{
for (Quest other : getQuests())
{
if (other.getID() == quest.getID())
return true;
}
return false;
}
public Quest getQuest(int id)
{
for (Quest quest : getQuests())
{
if (quest.getID() == id)
return quest;
}
return null;
}
public Quest getQuestFromAll(int id)
{
for (Quest quest : _quests)
{
if (quest.getID() == id)
return quest;
}
return null;
}
public boolean hasQuestFromAll(Quest quest)
{
for (Quest other : _quests)
{
if (other.getID() == quest.getID())
return true;
}
return false;
}
public void removeQuest(int id)
{
Quest toRemove = getQuest(id);
toRemove.setProgress(-1);
}
public ArrayList<Quest> getAllQuests()
{
return _quests;
}
public Hologram getHologram()
{
return _hologram;
}
public void setHologram(Hologram hologram)
{
_hologram = hologram;
}
}

View File

@ -0,0 +1,416 @@
package mineplex.core.quests;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import net.md_5.bungee.api.ChatColor;
import org.apache.commons.lang3.tuple.Triple;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Slime;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import mineplex.core.MiniClientPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Pair;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.donation.DonationManager;
import mineplex.core.google.GoogleSheetsManager;
import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.npc.Npc;
import mineplex.core.npc.NpcManager;
import mineplex.core.quests.command.GetQuestCommand;
import mineplex.core.quests.command.IncrementQuestCommand;
import mineplex.core.quests.command.OpenGuiCommand;
import mineplex.core.quests.repository.QuestRepository;
import mineplex.core.quests.shop.QuestShop;
import mineplex.core.stats.StatsManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.quest.client.RedisQuestSupplier;
import mineplex.quest.common.QuestSupplier;
import mineplex.serverdata.redis.messaging.PubSubJedisClient;
import mineplex.serverdata.redis.messaging.PubSubRouter;
import mineplex.serverdata.servers.ServerManager;
/**
* QuestManager
*
* @author xXVevzZXx
*/
public class QuestManager extends MiniClientPlugin<QuestClientData>
{
public static final String QUEST_NAME = "Mineplex Mission";
private static final String GOOGLE_SHEET = "QUESTS_SHEET";
private static final String GOOGLE_TABLE = "Quests";
private QuestRepository _repository;
private GoogleSheetsManager _sheetsManager;
private CoreClientManager _clients;
private DonationManager _donationManager;
private InventoryManager _inventoryManager;
public ArrayList<Quest> _availableQuests;
private QuestSupplier _questSupplier = new RedisQuestSupplier(getPlugin(), new PubSubRouter(new PubSubJedisClient(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection())));
private Npc _questNPC;
private boolean _enableNPC;
private HologramManager _hologramManager;
private boolean _visualTick;
public QuestManager(HologramManager hologramManager, Location npc, InventoryManager inventoryManager, DonationManager donationManager)
{
super("Quest Manager");
_repository = new QuestRepository();
_sheetsManager = require(GoogleSheetsManager.class);
_clients = require(CoreClientManager.class);
_availableQuests = new ArrayList<>();
_donationManager = donationManager;
_inventoryManager = inventoryManager;
_hologramManager = hologramManager;
setupQuests();
_questNPC = require(NpcManager.class).getNpcByName("Mineplex Missions");
if (_questNPC == null)
{
_enableNPC = false;
}
else
{
Slime slime = (Slime) _questNPC.getEntity();
slime.setSize(3);
if (npc != null)
{
_questNPC.setLocation(npc);
}
_enableNPC = true;
}
}
@EventHandler
public void updateCreeper(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER || !_enableNPC)
return;
Slime slime = (Slime)_questNPC.getEntity();
slime.setSize(3);
for (Player player : UtilServer.getPlayers())
{
String prefix = _visualTick ? C.cAqua : C.cDAqua;
updateSlimeVisual(player, prefix);
}
_visualTick = !_visualTick;
}
public void updateSlimeVisual(Player player , String rewardPrefix)
{
if (!_enableNPC)
return;
int availableQuests = 5;
for (int questid : getCurrentQuests())
{
if (Get(player).getQuestFromAll(questid) == null)
continue;
Quest quest = Get(player).getQuestFromAll(questid);
if (quest.isActive())
availableQuests--;
if (!UtilTime.elapsed(quest.getLastCompleted(), 1000*60*60*24))
availableQuests--;
}
Hologram hologram;
QuestClientData client = Get(player);
if (client.getHologram() == null)
{
double yAdd = 2.3;
if(!UtilPlayer.is1_9(player))
{
yAdd = 2.45;
}
hologram = new Hologram(_hologramManager, _questNPC.getLocation().clone().add(0, yAdd, 0), "");
hologram.setHologramTarget(Hologram.HologramTarget.WHITELIST);
hologram.addPlayer(player);
client.setHologram(hologram);
hologram.start();
}
else
{
hologram = client.getHologram();
}
if (availableQuests > 0)
{
// Hologram
String text = rewardPrefix + availableQuests + " Mission" + (availableQuests > 1 ? "s" : "") + " Available";
hologram.setText(text);
}
else
{
String text = C.cGray + "No Missions Available";
hologram.setText(text);
}
}
@Override
public void addCommands()
{
addCommand(new OpenGuiCommand(this));
addCommand(new GetQuestCommand(this));
addCommand(new IncrementQuestCommand(this));
}
public void setupQuests()
{
_availableQuests.clear();
Map<String, List<List<String>>> sheet = _sheetsManager.getSheetData(GOOGLE_SHEET);
List<List<String>> table = new ArrayList<>();
for (String key : sheet.keySet())
{
if (key.equalsIgnoreCase(GOOGLE_TABLE))
table = sheet.get(key);
}
int size = table.size();
for (int i = 1; i < size; i++)
{
String id = table.get(i).get(0);
String name = table.get(i).get(1);
String task = table.get(i).get(2);
String type = table.get(i).get(3);
String cost = table.get(i).get(4);
String reward = table.get(i).get(5);
String trigger = table.get(i).get(6);
String statcompletion = table.get(i).get(7);
String item = table.get(i).get(8);
String rarity = table.get(i).get(9);
_availableQuests.add(new Quest(Integer.parseInt(id), name, task,
Integer.parseInt(cost),
reward,
QuestRarity.getByName(rarity),
type,
TriggerType.getByName(trigger),
item.split(","),
Integer.parseInt(statcompletion)));
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void openGui(PlayerInteractAtEntityEvent event)
{
if (!_enableNPC)
return;
Entity entity = event.getRightClicked();
if (entity.equals(_questNPC.getEntity()))
{
new QuestShop(this, _clients, _donationManager).attemptShopOpen(event.getPlayer());
}
}
@EventHandler
public void openGui(EntityDamageByEntityEvent event)
{
if (!_enableNPC)
return;
if (event.getDamager() instanceof Player)
{
Player player = (Player) event.getDamager();
if (event.getEntity().equals(_questNPC.getEntity()))
{
new QuestShop(this, _clients, _donationManager).attemptShopOpen(player);
}
}
}
@EventHandler
public void playerJoin(PlayerJoinEvent event)
{
QuestClientData questData = Get(event.getPlayer());
_repository.getQuests(_clients.Get(event.getPlayer()), new Callback<ArrayList<Pair<Integer, Triple<Integer, Long, Integer>>>>()
{
@Override
public void run(ArrayList<Pair<Integer, Triple<Integer, Long, Integer>>> data)
{
for (Pair<Integer, Triple<Integer, Long, Integer>> pair : data)
{
int id = pair.getLeft();
int value = pair.getRight().getLeft();
long time = pair.getRight().getMiddle();
int timesCompleted = pair.getRight().getRight();
for (Quest quest : _availableQuests)
{
if (quest.getID() == id)
{
Quest clone = quest.clone();
clone.setProgress(value);
clone.setLastCompleted(time);
clone.setTimesCompleted(timesCompleted);
questData.addQuest(clone);
}
}
}
}
});
}
public Quest getQuestByID(int id)
{
for (Quest quest : _availableQuests)
{
if (quest.getID() == id)
return quest;
}
return null;
}
public void addNewQuest(Player player, Quest quest)
{
QuestClientData data = Get(player);
for (Quest other : data.getAllQuests())
{
if (other.getID() == quest.getID())
{
other.setProgress(0);
_repository.addQuest(_clients.Get(player), other);
return;
}
}
Quest clone = quest.clone();
clone.setProgress(0);
Get(player).addQuest(clone);
_repository.addNew(_clients.Get(player), quest);
}
public void resetQuest(Player player, Quest quest, boolean completed)
{
if (completed)
{
quest.setTimesCompleted(quest.getTimesCompleted() + 1);
quest.setLastCompleted(System.currentTimeMillis());
}
Get(player).removeQuest(quest.getID());
_repository.resetQuest(_clients.Get(player), quest, completed);
}
public void incrementQuest(Player player, Quest quest, int value)
{
quest.increment(value);
if (quest.isCompleted())
{
UtilPlayer.message(player, F.main(QUEST_NAME, "You have completed the " + QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName()));
}
_repository.incrementQuest(_clients.Get(player), quest, value);
}
public Set<Integer> getCurrentQuests()
{
Set<Integer> set = new HashSet<>();
for (mineplex.quest.common.Quest quest : _questSupplier.get())
{
set.add(quest.getUniqueId());
}
return set;
}
public void rewardQuest(Player player, Quest quest, Consumer<Boolean> callback)
{
if (quest.getReward().contains(":"))
{
ChatColor color = ChatColor.YELLOW;
if (quest.getRewardName().equalsIgnoreCase("Shards"))
{
_donationManager.rewardCurrency(GlobalCurrency.TREASURE_SHARD, player, "Completing " + QUEST_NAME + ": " + quest.getID(), Integer.parseInt(quest.getReward().split(":")[1]), callback);
color = ChatColor.AQUA;
}
else if (quest.getRewardName().equalsIgnoreCase("Gems"))
{
_donationManager.rewardCurrency(GlobalCurrency.TREASURE_SHARD, player, "Completing " + QUEST_NAME + ": " + quest.getID(), Integer.parseInt(quest.getReward().split(":")[1]), callback);
color = ChatColor.GREEN;
}
else if (quest.getRewardName().equalsIgnoreCase("XP"))
{
require(StatsManager.class).incrementStat(player, "Global.ExpEarned", quest.getRewardAmount());
callback.accept(true);
}
else
{
_inventoryManager.addItemToInventory(player, quest.getRewardName(), quest.getRewardAmount());
callback.accept(true);
}
UtilPlayer.message(player, F.main(QUEST_NAME, "You have recieved " + color + quest.getRewardAmount() + " " + quest.getRewardName() + " " + ChatColor.GRAY + "for completing: " + ChatColor.YELLOW + quest.getName()));
}
}
public CoreClientManager getClients()
{
return _clients;
}
public DonationManager getDonations()
{
return _donationManager;
}
public InventoryManager getInventoryManager()
{
return _inventoryManager;
}
@Override
protected QuestClientData addPlayer(UUID uuid)
{
return new QuestClientData();
}
@Override
public void saveData(String name, int accountId)
{
Get(name).getHologram().stop();
}
public ArrayList<Quest> getAvailableQuests()
{
return _availableQuests;
}
}

View File

@ -0,0 +1,44 @@
package mineplex.core.quests;
import org.bukkit.ChatColor;
/**
* QuestRarity
*
* @author xXVevzZXx
*/
public enum QuestRarity
{
COMMON("Common", ChatColor.YELLOW), RARE("Rare", ChatColor.LIGHT_PURPLE), LEGENDARY("Legendary", ChatColor.GREEN);
private String _name;
private ChatColor _color;
private QuestRarity(String name, ChatColor color)
{
_name = name;
_color = color;
}
@Override
public String toString()
{
return _name;
}
public ChatColor getColor()
{
return _color;
}
public static QuestRarity getByName(String name)
{
for (QuestRarity rarity : values())
{
if (rarity.toString().equalsIgnoreCase(name))
return rarity;
}
return null;
}
}

View File

@ -0,0 +1,36 @@
package mineplex.core.quests;
/**
* TriggerType
*
* @author xXVevzZXx
*/
public enum TriggerType
{
KILL("Kill"), DIE("Die"), WIN("Win"), LOSE("Lose"), COLLECT("Collect"), PLAY("Play"), COMPLETE("Complete");
private String _name;
private TriggerType(String name)
{
_name = name;
}
@Override
public String toString()
{
return _name;
}
public static TriggerType getByName(String name)
{
for (TriggerType type : values())
{
if (type.toString().equalsIgnoreCase(name))
return type;
}
return null;
}
}

View File

@ -0,0 +1,55 @@
package mineplex.core.quests.command;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
/**
* GetQuestCommand
*
* @author xXVevzZXx
*/
public class GetQuestCommand extends CommandBase<QuestManager>
{
public GetQuestCommand(QuestManager plugin)
{
super(plugin, Rank.ADMIN, "GetMineplexMission");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You have to submit valid arguments"));
return;
}
if (Plugin.getQuestByID(Integer.parseInt(args[0])) == null)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, QuestManager.QUEST_NAME + " not found"));
return;
}
Player player = caller;
if (args.length == 2)
{
if (UtilPlayer.searchExact(args[1]) != null)
player = UtilPlayer.searchExact(args[1]);
}
Quest quest = Plugin.getQuestByID(Integer.parseInt(args[0]));
Plugin.addNewQuest(player, quest);
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "Added " + QuestManager.QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName()));
if (caller != player)
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You gave the " + QuestManager.QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName() + ChatColor.GRAY + " to " + ChatColor.YELLOW + player.getName()));
}
}

View File

@ -0,0 +1,67 @@
package mineplex.core.quests.command;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
/**
* CompleteQuestCommand
*
* @author xXVevzZXx
*/
public class IncrementQuestCommand extends CommandBase<QuestManager>
{
public IncrementQuestCommand(QuestManager plugin)
{
super(plugin, Rank.ADMIN, "IncrementMineplexMission");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 2)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You have to submit valid arguments"));
return;
}
Player player = caller;
if (args.length == 3)
{
if (UtilPlayer.searchExact(args[2]) != null)
player = UtilPlayer.searchExact(args[2]);
}
if (Plugin.Get(player).getQuest(Integer.parseInt(args[0])) == null)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, QuestManager.QUEST_NAME + " not found"));
return;
}
int increment = 0;
try
{
increment = Integer.parseInt(args[1]);
}
catch (NumberFormatException e)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You have to submit a valid number"));
return;
}
Quest quest = Plugin.Get(player).getQuest(Integer.parseInt(args[0]));
Plugin.incrementQuest(player, quest, increment);
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "Incremented " + QuestManager.QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName() + ChatColor.GRAY + " by " + increment));
if (caller != player)
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You incremented the " + QuestManager.QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName() + ChatColor.GRAY + " for " + ChatColor.YELLOW + player.getName() + ChatColor.GRAY + " by " + increment));
}
}

View File

@ -0,0 +1,27 @@
package mineplex.core.quests.command;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.quests.QuestManager;
import mineplex.core.quests.shop.QuestShop;
/**
* OpenGuiCommand
*
* @author xXVevzZXx
*/
public class OpenGuiCommand extends CommandBase<QuestManager>
{
public OpenGuiCommand(QuestManager plugin)
{
super(plugin, Rank.ALL, "Missions");
}
@Override
public void Execute(Player caller, String[] args)
{
new QuestShop(Plugin, Plugin.getClients(), Plugin.getDonations()).attemptShopOpen(caller);
}
}

View File

@ -0,0 +1,60 @@
package mineplex.core.quests.event;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import mineplex.core.quests.Quest;
/**
* QuestBuyEvent
*
* @author xXVevzZXx
*/
public class QuestInteractEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private boolean _cancelled = false;
private Quest _quest;
private String _cancelReason;
public QuestInteractEvent(Quest quest)
{
_quest = quest;
}
public Quest getQuest()
{
return _quest;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
public boolean isCancelled()
{
return _cancelled;
}
public void setCancelled(String reason)
{
_cancelled = true;
_cancelReason = reason;
}
public String getCancelMessage()
{
return _cancelReason;
}
}

View File

@ -0,0 +1,140 @@
package mineplex.core.quests.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.apache.commons.lang3.tuple.Triple;
import mineplex.core.account.CoreClient;
import mineplex.core.common.Pair;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UtilServer;
import mineplex.core.quests.Quest;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnLong;
/**
* QuestRepository
*
* @author xXVevzZXx
*/
public class QuestRepository extends RepositoryBase
{
private static final String INSTERT_NEW_QUEST = "INSERT INTO accountQuest (accountId, questId, progress, questCompletion, lastCompleted) VALUES (?, ?, ?, ?, ?);";
private static final String INCREMENT_QUEST = "UPDATE accountQuest SET progress=progress+? WHERE accountId=? AND questId=?;";
private static final String RESET_QUEST = "UPDATE accountQuest SET progress=-1 WHERE accountId=? AND questId=?;";
private static final String START_QUEST = "UPDATE accountQuest SET progress=0 WHERE accountId=? AND questId=?;";
private static final String COMPLETE_QUEST = "UPDATE accountQuest SET progress=-1, questCompletion=questCompletion+1, lastCompleted=? WHERE accountId=? AND questId=?;";
private static final String FETCH_QUESTS = "SELECT questId, progress, questCompletion, lastCompleted FROM accountQuest WHERE accountId=?";
public String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS accountQuest (id INT NOT NULL AUTO_INCREMENT, accountId INT NOT NULL, questId INT NOT NULL, progress INT, questCompletion INT, lastCompleted BIGINT NOT NULL, PRIMARY KEY (id), FOREIGN KEY (accountId) REFERENCES accounts (id), UNIQUE INDEX questIndex (accountId, questId), INDEX progressIndex (progress), INDEX completionIndex (questCompletion));";
public QuestRepository()
{
super(DBPool.getAccount());
createTable();
}
public void createTable()
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeUpdate(CREATE_TABLE);
}
});
}
public void getQuests(CoreClient client, Callback<ArrayList<Pair<Integer, Triple<Integer, Long, Integer>>>> callback)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeQuery(FETCH_QUESTS, new ResultSetCallable()
{
@Override
public void processResultSet(ResultSet resultSet) throws SQLException
{
ArrayList<Pair<Integer, Triple<Integer, Long, Integer>>> list = new ArrayList<>();
while (resultSet.next())
{
list.add(Pair.create(resultSet.getInt(1), Triple.of(resultSet.getInt(2), resultSet.getLong(4), resultSet.getInt(3))));
}
callback.run(list);
}
} ,new ColumnInt("accountId", client.getAccountId()));
}
});
}
public void resetQuest(CoreClient client, Quest quest, boolean completed)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
if (completed)
{
executeUpdate(COMPLETE_QUEST, new ColumnLong("lastCompleted", System.currentTimeMillis()), new ColumnInt("accountId", client.getAccountId()), new ColumnInt("questId", quest.getID()));
}
else
{
executeUpdate(RESET_QUEST, new ColumnInt("accountId", client.getAccountId()), new ColumnInt("questId", quest.getID()));
}
}
});
}
public void addQuest(CoreClient client, Quest quest)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeUpdate(START_QUEST, new ColumnInt("accountId", client.getAccountId()), new ColumnInt("questId", quest.getID()));
}
});
}
public void addNew(CoreClient client, Quest quest)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeInsert(INSTERT_NEW_QUEST, null,
new ColumnInt("accountId", client.getAccountId()),
new ColumnInt("questId", quest.getID()),
new ColumnInt("progress", 0),
new ColumnInt("questCompletion", 0),
new ColumnLong("lastCompleted", (long) 0));
}
});
}
public void incrementQuest(CoreClient client, Quest quest, int value)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeUpdate(INCREMENT_QUEST, new ColumnInt("progress", value), new ColumnInt("accountId", client.getAccountId()), new ColumnInt("questId", quest.getID()));
}
});
}
}

View File

@ -0,0 +1,93 @@
package mineplex.core.quests.shop;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
import mineplex.core.quests.event.QuestInteractEvent;
import mineplex.core.recharge.Recharge;
import mineplex.core.shop.confirmation.ConfirmationPage;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.SalesPackageBase;
import mineplex.core.shop.item.SalesPackageProcessor;
/**
* BuyQuestButton
*
* @author xXVevzZXx
*/
public class BuyQuestButton implements IButton
{
private final static int MAX_QUESTS = 5;
private QuestManager _questManager;
private QuestPage _page;
private Quest _quest;
public BuyQuestButton(QuestManager questManager, QuestPage page, Quest quest)
{
_questManager = questManager;
_quest = quest;
_page = page;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (!Recharge.Instance.use(player, "Buy Mineplex Mission", 1000, false, false))
{
return;
}
if (_questManager.Get(player).hasQuest(_quest))
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You already own that " + QuestManager.QUEST_NAME + "!"));
return;
}
if (_questManager.Get(player).getQuests().size() >= MAX_QUESTS)
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You can't own more than " + MAX_QUESTS + " active " + QuestManager.QUEST_NAME + " at once!"));
return;
}
if (_questManager.Get(player).hasQuestFromAll(_quest))
{
if (!UtilTime.elapsed(_questManager.Get(player).getQuestFromAll(_quest.getID()).getLastCompleted(), 1000*60*60*24))
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You already completed that " + QuestManager.QUEST_NAME + " today!"));
return;
}
}
QuestInteractEvent event = UtilServer.CallEvent(new QuestInteractEvent(_quest));
if (event.isCancelled())
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, event.getCancelMessage()));
return;
}
SalesPackageBase salesPackage = new QuestSale(ChatColor.YELLOW + "" + ChatColor.BOLD + _quest.getName(), Material.PAPER, _quest.getCost());
_page.getShop().openPageForPlayer(player, new ConfirmationPage<>(player, _page, new SalesPackageProcessor(player, GlobalCurrency.GEM, salesPackage, _page.getDonationManager(), () ->
{
_questManager.addNewQuest(player, _quest);
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You have bought: " + ChatColor.YELLOW + _quest.getName()));
player.closeInventory();
new QuestShop(_questManager, _questManager.getClients(), _questManager.getDonations()).attemptShopOpen(player);
}), salesPackage.buildIcon()));
}
}

View File

@ -0,0 +1,156 @@
package mineplex.core.quests.shop;
import java.util.ArrayList;
import java.util.Arrays;
import org.apache.commons.lang3.ArrayUtils;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.UtilTime;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.page.ShopPageBase;
/**
* QuestPage
*
* @author xXVevzZXx
*/
public class QuestPage extends ShopPageBase<QuestManager, QuestShop>
{
private QuestShop _questShop;
private QuestManager _manager;
public QuestPage(QuestManager plugin, QuestShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player)
{
super(plugin, shop, clientManager, donationManager, QuestManager.QUEST_NAME + " Page", player, 27);
_questShop = shop;
_manager = plugin;
buildPage();
}
@Override
protected void buildPage()
{
int i = 0;
setItem(i, ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, ChatColor.RESET + "" + ChatColor.BOLD + "Available " + QuestManager.QUEST_NAME + "s"));
{
int currentSlot = 4;
int diff = 0;
boolean forward = true;
for (int questID : getQuestShop().getQuestManager().getCurrentQuests())
{
if (forward)
{
currentSlot += diff;
}
else
{
currentSlot -= diff;
}
diff++;
forward = !forward;
Quest playerQuest = _shop.getQuestManager().Get(_player).getQuestFromAll(questID);
if (playerQuest != null)
{
if (!UtilTime.elapsed(playerQuest.getLastCompleted(), 1000*60*60*24))
{
continue;
}
if (playerQuest.isActive())
{
continue;
}
}
Quest quest = _shop.getQuestManager().getQuestByID(questID);
ItemStack item = new ItemStack(Material.PAPER);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.YELLOW + "" + ChatColor.BOLD + quest.getName());
meta.setLore(Arrays.asList(
ChatColor.LIGHT_PURPLE + quest.getTask(),
"",
ChatColor.GRAY + "Cost: " + ChatColor.GREEN + quest.getCost() + " Gems",
ChatColor.GRAY + "Reward: " + ChatColor.AQUA + quest.getRewardAmount() + " " + quest.getRewardName(),
"",
quest.getRarity().getColor() + "" + ChatColor.BOLD + quest.getRarity().toString(),
"",
ChatColor.GREEN + "Click to buy " + QuestManager.QUEST_NAME + "!"
));
item.setItemMeta(meta);
addButton(i + currentSlot, item, new BuyQuestButton(_manager, this, quest));
}
}
i = 9;
while (i < (9*2))
{
setItem(i, ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.BLACK.getData()));
i++;
}
i = 9*2;
addButton(i, ItemStackFactory.Instance.CreateStack(Material.EMPTY_MAP, (byte) 0, 1, ChatColor.RESET + "" + ChatColor.BOLD + QuestManager.QUEST_NAME + " Stats"), new IButton()
{
@Override
public void onClick(Player player, ClickType clickType)
{
player.closeInventory();
new QuestStatShop(_manager, _manager.getClients(), _manager.getDonations()).attemptShopOpen(player);
}
});
{
int currentSlot = 4;
int diff = 0;
boolean forward = true;
for (Quest quest : _shop.getQuestManager().Get(_player).getQuests())
{
if (forward)
{
currentSlot += diff;
}
else
{
currentSlot -= diff;
}
diff++;
forward = !forward;
ItemStack item = new ItemStack(Material.PAPER);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.YELLOW + "" + ChatColor.BOLD + quest.getName());
meta.setLore(Arrays.asList(ArrayUtils.addAll(quest.getQuestInfo(),
"",
(quest.isCompleted() ? ChatColor.GREEN + "Left Click to Complete" : ChatColor.RED + "Shift Right-Click to cancel")
)));
item.setItemMeta(meta);
item.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
addButton(i + currentSlot, item, new RedeemDeclineQuestButton(_donationManager, _manager, quest));
}
}
}
public QuestShop getQuestShop()
{
return _questShop;
}
}

View File

@ -0,0 +1,25 @@
package mineplex.core.quests.shop;
import org.bukkit.Material;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.shop.item.SalesPackageBase;
/**
* QuestSale
*
* @author xXVevzZXx
*/
public class QuestSale extends SalesPackageBase
{
public QuestSale(String name, Material mat, int cost)
{
super(name, mat, (byte) 0, new String[] {}, cost);
KnownPackage = false;
OneTimePurchaseOnly = false;
// CurrencyCostMap.clear();
CurrencyCostMap.put(GlobalCurrency.GEM, cost);
}
}

View File

@ -0,0 +1,34 @@
package mineplex.core.quests.shop;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.quests.QuestManager;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
/**
* QuestShop
*
* @author xXVevzZXx
*/
public class QuestShop extends ShopBase<QuestManager>
{
public QuestShop(QuestManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super(plugin, clientManager, donationManager, QuestManager.QUEST_NAME + " Shop");
}
@Override
protected ShopPageBase<QuestManager, ? extends ShopBase<QuestManager>> buildPagesFor(Player player)
{
return new QuestPage(getPlugin(), this, getClientManager(), getDonationManager(), player);
}
public QuestManager getQuestManager()
{
return getPlugin();
}
}

View File

@ -0,0 +1,35 @@
package mineplex.core.quests.shop;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.quests.QuestManager;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
/**
* QuestStatShop
*
* @author xXVevzZXx
*/
public class QuestStatShop extends ShopBase<QuestManager>
{
public QuestStatShop(QuestManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super(plugin, clientManager, donationManager, QuestManager.QUEST_NAME + " Stats");
}
@Override
protected ShopPageBase<QuestManager, ? extends ShopBase<QuestManager>> buildPagesFor(Player player)
{
return new QuestStatsPage(getPlugin(), this, getClientManager(), getDonationManager(), player, 0);
}
public QuestManager getQuestManager()
{
return getPlugin();
}
}

View File

@ -0,0 +1,128 @@
package mineplex.core.quests.shop;
import java.util.Arrays;
import org.apache.commons.lang3.ArrayUtils;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import mineplex.core.account.CoreClientManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestClientData;
import mineplex.core.quests.QuestManager;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.page.ShopPageBase;
/**
* QuestStatsPage
*
* @author xXVevzZXx
*/
public class QuestStatsPage extends ShopPageBase<QuestManager, QuestStatShop>
{
private QuestStatShop _questShop;
private QuestManager _manager;
private int _siteIndex;
public QuestStatsPage(QuestManager plugin, QuestStatShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player, int site)
{
super(plugin, shop, clientManager, donationManager, QuestManager.QUEST_NAME + " Stats", player, 6*9);
_siteIndex = site;
_questShop = shop;
_manager = plugin;
buildPage();
}
@Override
protected void buildPage()
{
removeButton(5*9);
removeButton((6*9) - 1);
int questID = (_siteIndex * 5 * 9);
for (int i = 0; i < 9*5; i++)
{
Quest quest = _manager.getQuestByID(questID);
if (quest == null)
{
setItem(i, null);
questID++;
continue;
}
QuestClientData data = _manager.Get(getPlayer());
ItemStack item = ItemStackFactory.Instance.CreateStack(Material.WOOL, DyeColor.GRAY.getWoolData(), 1, ChatColor.YELLOW + quest.getName());
if (data.hasQuestFromAll(quest))
{
Quest used = data.getQuestFromAll(questID);
item = ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, ChatColor.YELLOW + used.getName());
ItemMeta meta = item.getItemMeta();
meta.setLore(Arrays.asList(ArrayUtils.addAll(used.getQuestInfo(),
"",
ChatColor.GRAY + "Times Completed: " + ChatColor.YELLOW + used.getTimesCompleted()
)));
item.setItemMeta(meta);
}
setItem(i, item);
questID++;
}
if (_siteIndex > 0)
{
addButton(5*9, ItemStackFactory.Instance.CreateStack(Material.SIGN, (byte) 0, 1, ChatColor.YELLOW + "Previous Page"), new IButton()
{
@Override
public void onClick(Player player, ClickType clickType)
{
_siteIndex--;
buildPage();
}
});
}
if (((_siteIndex + 1) * 5 * 9) <= _manager.getAvailableQuests().size())
{
addButton((6*9) - 1, ItemStackFactory.Instance.CreateStack(Material.SIGN, (byte) 0, 1, ChatColor.YELLOW + "Next Page"), new IButton()
{
@Override
public void onClick(Player player, ClickType clickType)
{
_siteIndex++;
buildPage();
}
});
}
addButton(5*9 + 4, ItemStackFactory.Instance.CreateStack(Material.SIGN, (byte) 0, 1, ChatColor.YELLOW + "Back to " + QuestManager.QUEST_NAME + "s"), new IButton()
{
@Override
public void onClick(Player player, ClickType clickType)
{
player.closeInventory();
new QuestShop(_manager, getClientManager(), getDonationManager()).attemptShopOpen(player);
}
});
}
public QuestStatShop getQuestStatsShop()
{
return _questShop;
}
}

View File

@ -0,0 +1,101 @@
package mineplex.core.quests.shop;
import java.util.function.Consumer;
import javax.jws.Oneway;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.donation.DonationManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
import mineplex.core.quests.event.QuestInteractEvent;
import mineplex.core.recharge.Recharge;
import mineplex.core.shop.item.IButton;
/**
* RedeemDeclineQuest
*
* @author xXVevzZXx
*/
public class RedeemDeclineQuestButton implements IButton
{
private QuestManager _questManager;
private DonationManager _donations;
private Quest _quest;
public RedeemDeclineQuestButton(DonationManager donations, QuestManager questManager, Quest quest)
{
_questManager = questManager;
_donations = donations;
_quest = quest;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (!Recharge.Instance.use(player, "Decline Mineplex Mission", 1000, false, false))
{
return;
}
if (!_questManager.Get(player).hasQuest(_quest))
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You don't own that " + QuestManager.QUEST_NAME + "!"));
return;
}
QuestInteractEvent event = UtilServer.CallEvent(new QuestInteractEvent(_quest));
if (event.isCancelled())
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, event.getCancelMessage()));
return;
}
if (clickType == ClickType.SHIFT_RIGHT)
{
if (_quest.isCompleted())
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You can't cancel a completed " + QuestManager.QUEST_NAME + "!"));
return;
}
_questManager.resetQuest(player, _quest, false);
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You have cancelled that " + QuestManager.QUEST_NAME + "!"));
}
if (clickType == ClickType.LEFT)
{
if (!_quest.isCompleted())
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You haven't completed that " + QuestManager.QUEST_NAME + " yet!"));
return;
}
_questManager.rewardQuest(player, _quest, new Consumer<Boolean>()
{
@Override
public void accept(Boolean succes)
{
if (succes)
{
_questManager.resetQuest(player, _quest, true);
player.closeInventory();
}
}
});
}
player.closeInventory();
new QuestShop(_questManager, _questManager.getClients(), _donations).attemptShopOpen(player);
}
}

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