diff --git a/Art/Carl.png b/Art/Carl.png
new file mode 100644
index 000000000..5d4fe6d36
Binary files /dev/null and b/Art/Carl.png differ
diff --git a/Plugins/.idea/artifacts/Mineplex_Hub_test.xml b/Plugins/.idea/artifacts/Mineplex_Hub_test.xml
index d164c4c6a..0527ee7d4 100644
--- a/Plugins/.idea/artifacts/Mineplex_Hub_test.xml
+++ b/Plugins/.idea/artifacts/Mineplex_Hub_test.xml
@@ -1,5 +1,5 @@
-
+
$PROJECT_DIR$/../Testing/Hub/plugins
diff --git a/Plugins/.idea/artifacts/Mineplex_Votifier_jar.xml b/Plugins/.idea/artifacts/Mineplex_Votifier_jar.xml
new file mode 100644
index 000000000..372114469
--- /dev/null
+++ b/Plugins/.idea/artifacts/Mineplex_Votifier_jar.xml
@@ -0,0 +1,24 @@
+
+
+ $PROJECT_DIR$/out/artifacts/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/.idea/compiler.xml b/Plugins/.idea/compiler.xml
index ccd5607c1..27bcf4d80 100644
--- a/Plugins/.idea/compiler.xml
+++ b/Plugins/.idea/compiler.xml
@@ -20,8 +20,16 @@
+
+
+
+
+
+
-
+
+
+
diff --git a/Plugins/.idea/encodings.xml b/Plugins/.idea/encodings.xml
index e206d70d8..d82104827 100644
--- a/Plugins/.idea/encodings.xml
+++ b/Plugins/.idea/encodings.xml
@@ -1,5 +1,4 @@
-
-
+
\ No newline at end of file
diff --git a/Plugins/.idea/libraries/bukkit.xml b/Plugins/.idea/libraries/bukkit.xml
deleted file mode 100644
index 8053b86f3..000000000
--- a/Plugins/.idea/libraries/bukkit.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Plugins/.idea/misc.xml b/Plugins/.idea/misc.xml
index 76fba6e9f..aeea575e6 100644
--- a/Plugins/.idea/misc.xml
+++ b/Plugins/.idea/misc.xml
@@ -7,6 +7,15 @@
+
+
+
diff --git a/Plugins/.idea/modules.xml b/Plugins/.idea/modules.xml
index 1a9d9336c..14d5d7c0f 100644
--- a/Plugins/.idea/modules.xml
+++ b/Plugins/.idea/modules.xml
@@ -15,6 +15,8 @@
+
+
diff --git a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java
index 941527a80..fa7f5c43c 100644
--- a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java
+++ b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java
@@ -39,8 +39,9 @@ public class MotdManager implements Listener, Runnable
if (new File("updateMOTD.dat").exists())
{
List lines = new ArrayList();
- lines.add(" §b§l◄§f§lNEW§b§l► §f§l◄§b§lSKYWARS§f§l► §b§l◄§f§lNEW§b§l►");
+ lines.add(" §f§l◄ §6§lNEW §f§l▬ §c§lSSM/SG/SW Teams§f§l ▬ §c§lMPS Update §f§l►");
//lines.add(" §d§lRank Sale §a§l40% Off");
+ //lines.add(" §f§l◄§c§lMAINTENANCE§f§l►");
updateMainMotd(" §b§l§m §8§l§m[ §r §9§lMineplex§r §f§lGames§r §8§l§m ]§b§l§m §r", lines);
System.out.println("Updated Bungee MOTD");
diff --git a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java
index 24e40892c..1b8117d04 100644
--- a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java
+++ b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java
@@ -56,7 +56,7 @@ public class PlayerTracker implements Listener
{
public void run()
{
- _repository.removeElement(event.getPlayer().getName());
+ _repository.removeElement(event.getPlayer().getName().toLowerCase());
}
});
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/CurrencyType.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/CurrencyType.java
index b8c7eb796..6a007fefa 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/CurrencyType.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/CurrencyType.java
@@ -8,7 +8,7 @@ public enum CurrencyType
Coins(" Coins", Material.DOUBLE_PLANT),
Gems(" Gems", Material.EMERALD),
Gold(" Gold", Material.GOLD_NUGGET);
-
+
private String _prefix;
private Material _displayMaterial;
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/Rank.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/Rank.java
index 47719668a..74e648808 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/Rank.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/Rank.java
@@ -1,23 +1,24 @@
package mineplex.core.common;
-import mineplex.core.common.util.C;
-import mineplex.core.common.util.UtilPlayer;
-
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
+import mineplex.core.common.util.C;
+import mineplex.core.common.util.UtilPlayer;
+
public enum Rank
{
LT("LT", ChatColor.DARK_RED),
OWNER("Owner", ChatColor.DARK_RED),
DEVELOPER("Dev", ChatColor.RED),
ADMIN("Admin", ChatColor.RED),
+ JNR_DEV("Jr.Dev", ChatColor.RED),
SNR_MODERATOR("Sr.Mod", ChatColor.GOLD),
MODERATOR("Mod", ChatColor.GOLD),
- JNR_DEV("Jr.Dev", ChatColor.RED),
HELPER("Trainee", ChatColor.DARK_AQUA),
MAPLEAD("MapLead", ChatColor.DARK_PURPLE),
MAPDEV("Builder", ChatColor.BLUE),
+ MEDIA("Media", ChatColor.BLUE),
EVENT("Event", ChatColor.WHITE),
@@ -51,10 +52,6 @@ public enum Rank
public boolean Has(Player player, Rank rank, Rank[] specific, boolean inform)
{
- if (player != null)
- if (player.getName().equals("Chiss"))
- return true;
-
//Specific Rank
if (specific != null)
{
@@ -75,7 +72,7 @@ public enum Rank
{
UtilPlayer.message(player, C.mHead + "Permissions> " +
C.mBody + "This requires Permission Rank [" +
- C.mHead + rank +
+ C.mHead + rank.Name.toUpperCase() +
C.mBody + "].");
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/SchematicRunnable.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/SchematicRunnable.java
index 95ebe63d8..e3b8c1d0a 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/SchematicRunnable.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/block/schematic/SchematicRunnable.java
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
+import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.plugin.java.JavaPlugin;
@@ -85,7 +86,8 @@ public class SchematicRunnable implements Runnable
// We are done
System.out.println("Finished importing schematic with setblockrunnable!");
- if (_callback != null) _callback.run(_changedBlocks);
+ if (_callback != null)
+ _callback.run(_changedBlocks);
_task.cancel();
return;
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAction.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAction.java
index 1b870ada9..50d8fe661 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAction.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAction.java
@@ -1,11 +1,23 @@
package mineplex.core.common.util;
-
import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
public class UtilAction
{
+ private static VelocityReceiver _velocityFix;
+
+ public static void registerVelocityFix(VelocityReceiver velocityFix)
+ {
+ _velocityFix = velocityFix;
+ }
+
+ public static void velocity(Entity ent, Vector vec)
+ {
+ velocity(ent, vec, vec.length(), false, 0, 0, vec.length(), false);
+ }
+
public static void velocity(Entity ent, double str, double yAdd, double yMax, boolean groundBoost)
{
velocity(ent, ent.getLocation().getDirection(), str, false, 0, yAdd, yMax, groundBoost);
@@ -14,8 +26,11 @@ public class UtilAction
public static void velocity(Entity ent, Vector vec, double str, boolean ySet, double yBase, double yAdd, double yMax, boolean groundBoost)
{
if (Double.isNaN(vec.getX()) || Double.isNaN(vec.getY()) || Double.isNaN(vec.getZ()) || vec.length() == 0)
+ {
+ zeroVelocity(ent);
return;
-
+ }
+
//YSet
if (ySet)
vec.setY(yBase);
@@ -23,20 +38,43 @@ public class UtilAction
//Modify
vec.normalize();
vec.multiply(str);
-
+
//YAdd
vec.setY(vec.getY() + yAdd);
-
+
//Limit
if (vec.getY() > yMax)
vec.setY(yMax);
-
+
if (groundBoost)
if (UtilEnt.isGrounded(ent))
vec.setY(vec.getY() + 0.2);
-
+
//Velocity
ent.setFallDistance(0);
- ent.setVelocity(vec);
+
+ //Store It!
+ if (ent instanceof Player && _velocityFix != null)
+ {
+ _velocityFix.setPlayerVelocity(((Player)ent), vec);
+ }
+
+ ent.setVelocity(vec);
}
+
+ public static void zeroVelocity(Entity ent)
+ {
+ Vector vec = new Vector(0,0,0);
+ ent.setFallDistance(0);
+
+ //Store It!
+ if (ent instanceof Player && _velocityFix != null)
+ {
+ _velocityFix.setPlayerVelocity(((Player)ent), vec);
+ }
+
+ ent.setVelocity(vec);
+ }
+
+
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java
index fad8f1eef..8969368a4 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java
@@ -7,6 +7,7 @@ import java.util.TreeSet;
+
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@@ -25,7 +26,7 @@ public class UtilAlg
public static Location getMidpoint(Location a, Location b)
{
- return a.add(b.subtract(a).multiply(0.5));
+ return a.clone().add(b.clone().subtract(a.clone()).multiply(0.5));
}
public static Vector getTrajectory(Entity from, Entity to)
@@ -260,4 +261,132 @@ public class UtilAlg
return isInPyramid(player.getLocation().getDirection(), UtilAlg.getTrajectory(player.getEyeLocation(), target.getEyeLocation()), angleLimit) ||
isInPyramid(player.getLocation().getDirection(), UtilAlg.getTrajectory(player.getEyeLocation(), target.getLocation()), angleLimit);
}
+
+ public static Location getLocationAwayFromPlayers(ArrayList locs, ArrayList players)
+ {
+ Location bestLoc = null;
+ double bestDist = 0;
+
+ for (Location loc : locs)
+ {
+ double closest = -1;
+
+ for (Player player : players)
+ {
+ //Different Worlds
+ if (!player.getWorld().equals(loc.getWorld()))
+ continue;
+
+ double dist = UtilMath.offsetSquared(player.getLocation(), loc);
+
+ if (closest == -1 || dist < closest)
+ {
+ closest = dist;
+ }
+ }
+
+ if (closest == -1)
+ continue;
+
+ if (bestLoc == null || closest > bestDist)
+ {
+ bestLoc = loc;
+ bestDist = closest;
+ }
+ }
+
+ return bestLoc;
+ }
+
+ public static Location getLocationNearPlayers(ArrayList locs, ArrayList players, ArrayList dontOverlap)
+ {
+ Location bestLoc = null;
+ double bestDist = 0;
+
+ for (Location loc : locs)
+ {
+ double closest = -1;
+
+ boolean valid = true;
+
+ //Dont spawn on other players
+ for (Player player : dontOverlap)
+ {
+ if (!player.getWorld().equals(loc.getWorld()))
+ continue;
+
+ double dist = UtilMath.offsetSquared(player.getLocation(), loc);
+
+ if (dist < 0.8)
+ {
+ valid = false;
+ break;
+ }
+ }
+
+ if (!valid)
+ continue;
+
+ //Find closest player
+ for (Player player : players)
+ {
+ if (!player.getWorld().equals(loc.getWorld()))
+ continue;
+
+ double dist = UtilMath.offsetSquared(player.getLocation(), loc);
+
+ if (closest == -1 || dist < closest)
+ {
+ closest = dist;
+ }
+ }
+
+ if (closest == -1)
+ continue;
+
+ if (bestLoc == null || closest < bestDist)
+ {
+ bestLoc = loc;
+ bestDist = closest;
+ }
+ }
+
+ return bestLoc;
+ }
+
+ public static Vector calculateVelocity(Vector from, Vector to, int heightGain)
+ {
+ // Gravity of a potion
+ double gravity = 0.115;
+ // Block locations
+ int endGain = to.getBlockY() - from.getBlockY();
+
+ double dx1 = to.getBlockX() - from.getBlockX();
+ double dz1 = to.getBlockZ() - from.getBlockZ();
+
+ double horizDist = Math.sqrt(dx1 * dx1 + dz1 * dz1);
+ // Height gain
+ int gain = heightGain;
+ double maxGain = gain > (endGain + gain) ? gain : (endGain + gain);
+ // Solve quadratic equation for velocity
+ double a = -horizDist * horizDist / (4 * maxGain);
+ double b = horizDist;
+ double c = -endGain;
+ double slope = -b / (2 * a) - Math.sqrt(b * b - 4 * a * c) / (2 * a);
+ // Vertical velocity
+ double vy = Math.sqrt(maxGain * gravity);
+ // Horizontal velocity
+ double vh = vy / slope;
+ // Calculate horizontal direction
+ int dx = to.getBlockX() - from.getBlockX();
+ int dz = to.getBlockZ() - from.getBlockZ();
+ double mag = Math.sqrt(dx * dx + dz * dz);
+ double dirx = dx / mag;
+ double dirz = dz / mag;
+ // Horizontal velocity components
+ double vx = vh * dirx;
+ double vz = vh * dirz;
+ return new Vector(vx, vy, vz);
+ }
+
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java
index d87d16fa5..8b489c952 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java
@@ -4,21 +4,24 @@ import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+
import net.minecraft.server.v1_7_R4.EntityBat;
import net.minecraft.server.v1_7_R4.EntityCreature;
import net.minecraft.server.v1_7_R4.EntityEnderDragon;
import net.minecraft.server.v1_7_R4.EntityHuman;
import net.minecraft.server.v1_7_R4.EntityInsentient;
import net.minecraft.server.v1_7_R4.EntityLiving;
+import net.minecraft.server.v1_7_R4.EntityTrackerEntry;
import net.minecraft.server.v1_7_R4.Navigation;
+import net.minecraft.server.v1_7_R4.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_7_R4.PathfinderGoal;
import net.minecraft.server.v1_7_R4.PathfinderGoalLookAtPlayer;
import net.minecraft.server.v1_7_R4.PathfinderGoalMoveTowardsRestriction;
import net.minecraft.server.v1_7_R4.PathfinderGoalRandomLookaround;
import net.minecraft.server.v1_7_R4.PathfinderGoalSelector;
+import net.minecraft.server.v1_7_R4.WorldServer;
import org.bukkit.Bukkit;
-import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
@@ -32,6 +35,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Giant;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftCreature;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
@@ -582,6 +586,36 @@ public class UtilEnt
return false;
}
+ public static boolean CreatureLook(Entity ent, Entity target)
+ {
+ return CreatureLook(ent, target instanceof LivingEntity ? ((LivingEntity) target).getEyeLocation() : target.getLocation());
+ }
+
+ public static boolean CreatureLook(Entity ent, Location target)
+ {
+ Vector vec = UtilAlg.getTrajectory(ent.getLocation(), target);
+
+ return CreatureLook(ent, UtilAlg.GetPitch(vec), UtilAlg.GetYaw(vec));
+ }
+
+ public static boolean CreatureLook(Entity ent, float pitch, float yaw)
+ {
+ if (!(ent instanceof LivingEntity))
+ return false;
+
+ EntityLiving ec = ((CraftLivingEntity) ent).getHandle();
+ Location loc = ent.getLocation();
+
+ ec.setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), yaw, pitch);
+ ec.al = true;
+
+ EntityTrackerEntry entry = (EntityTrackerEntry) ((WorldServer) ec.world).tracker.trackedEntities.get(ec.getId());
+
+ entry.broadcast(new PacketPlayOutEntityHeadRotation(ec, (byte) (ec.yaw * 256.0F / 360.0F)));
+
+ return true;
+ }
+
public static void CreatureMove(Entity ent, Location target, float speed)
{
if (!(ent instanceof Creature))
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEvent.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEvent.java
index 79059c454..bd5346696 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEvent.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEvent.java
@@ -16,7 +16,8 @@ public class UtilEvent
L_BLOCK,
R,
R_AIR,
- R_BLOCK
+ R_BLOCK,
+ ANY
}
public static boolean isAction(PlayerInteractEvent event, ActionType action)
@@ -39,6 +40,9 @@ public class UtilEvent
if (action == ActionType.R_BLOCK)
return (event.getAction() == Action.RIGHT_CLICK_BLOCK);
+ if (action == ActionType.ANY)
+ return event.getAction() != Action.PHYSICAL;
+
return false;
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilMath.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilMath.java
index 396526e82..7c5f2ce64 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilMath.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilMath.java
@@ -90,5 +90,11 @@ public class UtilMath
return Math.random() * d;
}
+
+ public static T randomElement(T[] array) {
+ if (array.length == 0)
+ return null;
+ return array[random.nextInt(array.length)];
+ }
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java
index 5ad7351a6..60b2d613d 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java
@@ -7,21 +7,25 @@ import java.util.List;
import java.util.Random;
import java.util.UUID;
+import net.minecraft.server.v1_7_R4.EntityPlayer;
+import net.minecraft.server.v1_7_R4.Packet;
+import net.minecraft.server.v1_7_R4.PlayerConnection;
+
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
+import org.bukkit.craftbukkit.v1_7_R4.event.CraftEventFactory;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryView;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
-import net.minecraft.server.v1_7_R4.Packet;
-import net.minecraft.server.v1_7_R4.PlayerConnection;
-
public class UtilPlayer
{
private static Random RANDOM = new Random();
@@ -655,7 +659,19 @@ public class UtilPlayer
return ((CraftPlayer) player).getHandle().spectating;
return false;
}
-
+
+ public static InventoryView swapToInventory(Player player, Inventory inv) {
+
+ EntityPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
+ if (nmsPlayer.activeContainer != nmsPlayer.defaultContainer)
+ {
+ // Do this so that other inventories know their time is over.
+ CraftEventFactory.handleInventoryCloseEvent(nmsPlayer);
+ nmsPlayer.m();
+ }
+ return player.openInventory(inv);
+ }
+
/*
public void setListName(Player player, CoreClient client)
{
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java
index 694739fa9..4372b6fba 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java
@@ -2,6 +2,8 @@ package mineplex.core.common.util;
import java.util.Collection;
+import org.apache.commons.lang.WordUtils;
+
public class UtilText {
public static String listToString(Collection inputList, boolean comma) {
String out = "";
@@ -48,6 +50,11 @@ public class UtilText {
public static boolean isStringSimilar(String newString, String oldString, float matchRequirement)
{
+ if (newString.length() <= 3)
+ {
+ return newString.toLowerCase().equals(oldString.toLowerCase());
+ }
+
for (int i=0 ; i < newString.length() * matchRequirement ; i++)
{
int matchFromIndex = 0;
@@ -56,7 +63,7 @@ public class UtilText {
for (int j=0 ; j < oldString.length() ; j++)
{
//End of newString
- if (i+j > newString.length())
+ if (i+j >= newString.length())
{
break;
}
@@ -79,4 +86,13 @@ public class UtilText {
return false;
}
+
+ public static String[] wrap(String text, int lineLength)
+ {
+ return wrap(text, lineLength, true);
+ }
+
+ public static String[] wrap(String text, int lineLength, boolean wrapLongerWords) {
+ return WordUtils.wrap(text, lineLength, "\00D0", wrapLongerWords).split("\00D0");
+ }
}
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/VelocityReceiver.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/VelocityReceiver.java
new file mode 100644
index 000000000..8d621dab8
--- /dev/null
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/VelocityReceiver.java
@@ -0,0 +1,9 @@
+package mineplex.core.common.util;
+
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+
+public interface VelocityReceiver
+{
+ public void setPlayerVelocity(Player player, Vector velocity);
+}
diff --git a/Plugins/Mineplex.Core/.classpath b/Plugins/Mineplex.Core/.classpath
index 8171cd881..b60bc08f6 100644
--- a/Plugins/Mineplex.Core/.classpath
+++ b/Plugins/Mineplex.Core/.classpath
@@ -12,7 +12,7 @@
-
+
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/MiniDbClientPlugin.java b/Plugins/Mineplex.Core/src/mineplex/core/MiniDbClientPlugin.java
index 92e2ea3cb..2f479adeb 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/MiniDbClientPlugin.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/MiniDbClientPlugin.java
@@ -21,7 +21,7 @@ public abstract class MiniDbClientPlugin extends MiniCl
clientManager.addStoredProcedureLoginProcessor(this);
}
- public abstract void processLoginResultSet(String playerName, ResultSet resultSet) throws SQLException;
+ public abstract void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException;
public CoreClientManager getClientManager()
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/NCPDataManFix.java b/Plugins/Mineplex.Core/src/mineplex/core/NCPDataManFix.java
new file mode 100644
index 000000000..c531ad097
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/NCPDataManFix.java
@@ -0,0 +1,10 @@
+package mineplex.core;
+
+import fr.neatmonster.nocheatplus.config.ConfigManager;
+
+public class NCPDataManFix
+{
+ public NCPDataManFix() {
+ //ConfigManager.getConfigFile().set("data.consistencychecks.suppresswarnings", true);
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java
index ebec4be13..df6717c6a 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java
@@ -8,8 +8,11 @@ public class CoreClient
{
private int _accountId = -1;
private String _name;
+ private String _disguisedAs;
private Player _player;
private Rank _rank;
+ private Rank _disguisedRank;
+ private boolean _disguised;
public CoreClient(Player player)
{
@@ -62,4 +65,34 @@ public class CoreClient
{
_rank = rank;
}
+
+ public String getDisguisedAs()
+ {
+ return _disguisedAs;
+ }
+
+ public void setDisguisedAs(String originalName)
+ {
+ this._disguisedAs = originalName;
+ }
+
+ /**
+ * Only use this method if the client is actually disguised!
+ * @return
+ */
+ public Rank getDisguisedRank() {
+ return _disguisedRank;
+ }
+
+ public void setDisguisedRank(Rank disguisedRank) {
+ this._disguisedRank = disguisedRank;
+ }
+
+ public boolean isDisguised() {
+ return _disguised;
+ }
+
+ public void setDisguised(boolean disguised) {
+ this._disguised = disguised;
+ }
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java
index a76be2fcd..481bda4dd 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java
@@ -2,6 +2,7 @@ package mineplex.core.account;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
@@ -50,6 +51,7 @@ public class CoreClientManager extends MiniPlugin
private RedisDataRepository _accountCacheRepository;
private NautHashMap _loginProcessors = new NautHashMap();
+ private LinkedList _querylessLoginProcessors = new LinkedList();
private Object _clientLock = new Object();
@@ -110,7 +112,7 @@ public class CoreClientManager extends MiniPlugin
{
_clientList.remove(name);
}
-
+
_plugin.getServer().getPluginManager().callEvent(new ClientUnloadEvent(name));
}
@@ -118,16 +120,19 @@ public class CoreClientManager extends MiniPlugin
{
synchronized(_clientLock)
{
+ for(CoreClient client : _clientList.values())
+ {
+ if(client.getDisguisedAs() != null)
+ if(client.getDisguisedAs().equalsIgnoreCase(name))
+ return client;
+ }
return _clientList.get(name);
}
}
public CoreClient Get(Player player)
{
- synchronized(_clientLock)
- {
- return _clientList.get(player.getName());
- }
+ return Get(player.getName());
}
public int getPlayerCountIncludingConnecting()
@@ -135,6 +140,16 @@ public class CoreClientManager extends MiniPlugin
return Bukkit.getOnlinePlayers().size() + Math.max(0, _clientsConnecting.get());
}
+ /**
+ * Get the databse account id for a player. Requires the player is online
+ * @param player
+ * @return
+ */
+ public int getAccountId(Player player)
+ {
+ return Get(player).getAccountId();
+ }
+
@EventHandler(priority = EventPriority.LOWEST)
public void AsyncLogin(AsyncPlayerPreLoginEvent event)
{
@@ -221,13 +236,13 @@ public class CoreClientManager extends MiniPlugin
CoreClient client = Add(playerName);
client.SetRank(Rank.valueOf(token.Rank));
- client.setAccountId(_repository.login(_loginProcessors, uuid.toString(), client.GetPlayerName()));
+ client.setAccountId(_repository.login(_loginProcessors, _querylessLoginProcessors, uuid.toString(), client.GetPlayerName()));
// JSON sql response
Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
if (client.getAccountId() > 0)
- _accountCacheRepository.addElement(new AccountCache(uuid, client.getAccountId()));
+ _accountCacheRepository.addElement(new AccountCache(uuid, client.getAccountId()), 60 * 60 * 6);
}
catch (Exception exception)
{
@@ -248,7 +263,7 @@ public class CoreClientManager extends MiniPlugin
});
}
- private boolean LoadClient(final CoreClient client, final UUID uuid, String ipAddress)
+ public boolean LoadClient(final CoreClient client, final UUID uuid, String ipAddress)
{
TimingManager.start(client.GetPlayerName() + " LoadClient Total.");
long timeStart = System.currentTimeMillis();
@@ -261,7 +276,7 @@ public class CoreClientManager extends MiniPlugin
{
public void run()
{
- client.setAccountId(_repository.login(_loginProcessors, uuid.toString(), client.GetPlayerName()));
+ client.setAccountId(_repository.login(_loginProcessors, _querylessLoginProcessors, uuid.toString(), client.GetPlayerName()));
_clientLoginLock.remove(client.GetPlayerName());
}
});
@@ -301,7 +316,16 @@ public class CoreClientManager extends MiniPlugin
System.out.println(client.GetPlayerName() + "'s account id = " + client.getAccountId());
if (client.getAccountId() > 0)
- _accountCacheRepository.addElement(new AccountCache(uuid, client.getAccountId()));
+ {
+ try
+ {
+ _accountCacheRepository.addElement(new AccountCache(uuid, client.getAccountId()), 60 * 60 * 6);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
return !_clientLoginLock.containsKey(client.GetPlayerName());
}
@@ -442,7 +466,7 @@ public class CoreClientManager extends MiniPlugin
callback.run(matchedName);
return;
}
-
+
callback.run(matchedName);
}
}, caller, playerName, true);
@@ -473,7 +497,9 @@ public class CoreClientManager extends MiniPlugin
clientIterator.remove();
if (clientPlayer != null)
+ {
_plugin.getServer().getPluginManager().callEvent(new ClientUnloadEvent(clientPlayer.getName()));
+ }
}
}
}
@@ -495,6 +521,11 @@ public class CoreClientManager extends MiniPlugin
{
_loginProcessors.put(processor.getName(), processor);
}
+
+ public void addStoredProcedureLoginProcessor(IQuerylessLoginProcessor processor)
+ {
+ _querylessLoginProcessors.add(processor);
+ }
public boolean hasRank(Player player, Rank rank)
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/ILoginProcessor.java b/Plugins/Mineplex.Core/src/mineplex/core/account/ILoginProcessor.java
index aca0eb341..2f278165b 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/ILoginProcessor.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/ILoginProcessor.java
@@ -7,7 +7,7 @@ public interface ILoginProcessor
{
String getName();
- void processLoginResultSet(String playerName, ResultSet resultSet) throws SQLException;
+ void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException;
String getQuery(int accountId, String uuid, String name);
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/IQuerylessLoginProcessor.java b/Plugins/Mineplex.Core/src/mineplex/core/account/IQuerylessLoginProcessor.java
new file mode 100644
index 000000000..7c69bb1c1
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/IQuerylessLoginProcessor.java
@@ -0,0 +1,6 @@
+package mineplex.core.account;
+
+public interface IQuerylessLoginProcessor
+{
+ public void processLogin(String playerName, int accountId);
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/command/UpdateRank.java b/Plugins/Mineplex.Core/src/mineplex/core/account/command/UpdateRank.java
index 8ba37d68a..529148615 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/command/UpdateRank.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/command/UpdateRank.java
@@ -19,12 +19,20 @@ public class UpdateRank extends CommandBase
{
public UpdateRank(CoreClientManager plugin)
{
- super(plugin, Rank.ADMIN, "updateRank");
+ super(plugin, Rank.ADMIN, new Rank[] {Rank.JNR_DEV /*On test servers only*/}, "updateRank");
}
@Override
public void Execute(final Player caller, String[] args)
{
+ boolean testServer = Plugin.getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
+
+ if (Plugin.Get(caller).GetRank() == Rank.JNR_DEV && !testServer)
+ {
+ F.main(Plugin.getName(), F.elem(Rank.JNR_DEV.GetTag(true, true)) + "s are only permitted to set ranks on test servers!");
+ return;
+ }
+
if (args == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "/" + AliasUsed + " joeschmo MODERATOR"));
@@ -52,9 +60,10 @@ public class UpdateRank extends CommandBase
final Rank rank = tempRank;
- if (rank == Rank.ADMIN || rank == Rank.YOUTUBE || rank == Rank.JNR_DEV || rank == Rank.TWITCH || rank == Rank.MODERATOR || rank == Rank.HELPER || rank == Rank.ALL || rank == Rank.MAPDEV || rank == Rank.SNR_MODERATOR)
+ if (rank == Rank.ADMIN || rank == Rank.YOUTUBE || rank == Rank.TWITCH || rank == Rank.MODERATOR || rank == Rank.JNR_DEV || rank == Rank.HELPER || rank == Rank.ALL || rank == Rank.MAPDEV || rank == Rank.SNR_MODERATOR)
+ if (rank == Rank.ADMIN || rank == Rank.YOUTUBE || rank == Rank.TWITCH || rank == Rank.MODERATOR || rank == Rank.JNR_DEV || rank == Rank.HELPER || rank == Rank.ALL || rank == Rank.MAPDEV || rank == Rank.SNR_MODERATOR)
{
- if (rank == Rank.ADMIN && !Plugin.hasRank(caller, Rank.LT))
+ if (!testServer && rank.Has(Rank.ADMIN) && !Plugin.hasRank(caller, Rank.LT))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), ChatColor.RED + "" + ChatColor.BOLD + "Insufficient privileges!"));
return;
@@ -114,4 +123,4 @@ public class UpdateRank extends CommandBase
}
}
}
-}
+}
\ No newline at end of file
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java
index 954f3eaa9..c8dccb23e 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java
@@ -6,6 +6,7 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
@@ -14,6 +15,7 @@ import org.bukkit.craftbukkit.libs.com.google.gson.reflect.TypeToken;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.account.ILoginProcessor;
+import mineplex.core.account.IQuerylessLoginProcessor;
import mineplex.core.account.repository.token.LoginToken;
import mineplex.core.account.repository.token.RankUpdateToken;
import mineplex.core.common.Rank;
@@ -55,7 +57,7 @@ public class AccountRepository extends RepositoryBase
//executeUpdate(CREATE_ACCOUNT_TABLE);
}
- public int login(NautHashMap loginProcessors, String uuid, String name)
+ public int login(NautHashMap loginProcessors, LinkedList querylessLoginProcessors, String uuid, String name)
{
int accountId = -1;
try (
@@ -142,9 +144,14 @@ public class AccountRepository extends RepositoryBase
for (ILoginProcessor loginProcessor : loginProcessors.values())
{
- loginProcessor.processLoginResultSet(name, statement.getResultSet());
+ loginProcessor.processLoginResultSet(name, accountId, statement.getResultSet());
statement.getMoreResults();
}
+
+ for (IQuerylessLoginProcessor loginProcessor : querylessLoginProcessors)
+ {
+ loginProcessor.processLogin(name, accountId);
+ }
}
catch (Exception exception)
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java
index a1d818cca..f122d3034 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java
@@ -56,7 +56,7 @@ public enum Achievement
//Survival Games
SURVIVAL_GAMES_WINS("Katniss Everdeen", 600,
new String[]{"Survival Games.Wins"},
- new String[]{"Win 30 games of Survival Games"},
+ new String[]{"Win 20 games of Survival Games"},
new int[]{30},
AchievementCategory.SURVIVAL_GAMES),
@@ -87,8 +87,8 @@ public enum Achievement
//Skywars
SKYWARS_WINS("Sky King",2000,
new String[]{"Skywars.Wins"},
- new String[]{"Win 30 Games of Skywars"},
- new int[]{30},
+ new String[]{"Win 20 Games of Skywars"},
+ new int[]{20},
AchievementCategory.SKYWARS),
SKYWARS_BOMBER("Master Bomber",500,
@@ -326,7 +326,7 @@ public enum Achievement
SUPER_PAINTBALL_FLAWLESS_VICTORY("Flawless Victory", 1000,
new String[]{"Super Paintball.Wins"},
- new String[]{"Win a team with your entire team alive"},
+ new String[]{"Win a game with your entire team alive"},
new int[]{1},
AchievementCategory.SUPER_PAINTBALL),
@@ -630,6 +630,44 @@ public enum Achievement
new String[]{"Kill 2 enemies while blinded from", "a single flashbang"},
new int[]{1},
AchievementCategory.MINE_STRIKE),
+
+ //Bomb Lobbers
+ BOMB_LOBBERS_WINS("Master Bomber", 1200,
+ new String[]{"Bomb Lobbers.Wins"},
+ new String[]{"Win 100 games of Bomb Lobbers"},
+ new int[] {100},
+ AchievementCategory.BOMB_LOBBERS),
+
+ BOMB_LOBBERS_PROFESSIONAL_LOBBER("Professional Lobber", 1000,
+ new String[]{"Bomb Lobbers.Thrown"},
+ new String[]{"Throw 2000 TNT"},
+ new int[]{2000},
+ AchievementCategory.BOMB_LOBBERS),
+
+ BOMB_LOBBERS_ULTIMATE_KILLER("Ultimate Killer", 800,
+ new String[]{"Bomb Lobbers.Killer"},
+ new String[]{"Kill 6 players in a single game"},
+ new int[]{1},
+ AchievementCategory.BOMB_LOBBERS),
+
+ BOMB_LOBBERS_EXPLOSION_PROOF("Jelly Skin", 1200,
+ new String[]{"Bomb Lobbers.JellySkin"},
+ new String[]{"Win a game without taking any damage."},
+ new int[]{1},
+ AchievementCategory.BOMB_LOBBERS),
+
+ BOMB_LOBBERS_BLAST_PROOF("Blast Proof", 800,
+ new String[]{"Bomb Lobbers.BlastProof"},
+ new String[]{"Win 20 games using Armorer"},
+ new int[]{20},
+ AchievementCategory.BOMB_LOBBERS),
+
+ BOMB_LOBBERS_SNIPER("Sniper", 1000,
+ new String[]{"Bomb Lobbers.Direct Hit"},
+ new String[]{"Get 50 direct hits"},
+ new int[]{50},
+ AchievementCategory.BOMB_LOBBERS)
+
;
private String _name;
@@ -754,7 +792,7 @@ public enum Achievement
return _category;
}
- public AchievementData getLevelData(int exp)
+ public AchievementData getLevelData(long exp)
{
for (int i = 0; i < _levels.length; i++)
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java
index d777224ac..d19f0e93a 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java
@@ -15,8 +15,8 @@ import mineplex.core.stats.StatsManager;
public enum AchievementCategory
{
GLOBAL("Global", null,
- new StatDisplay[] { StatDisplay.GEMS_EARNED, null, new StatDisplay("Games Played", "GamesPlayed"), StatDisplay.TIME_IN_GAME },
- Material.EMERALD, 0, GameCategory.GLOBAL, null),
+ new StatDisplay[] { StatDisplay.GEMS_EARNED, null, new StatDisplay("Games Played", "GamesPlayed"), StatDisplay.TIME_IN_GAME, null, new StatDisplay("Daily Rewards", "DailyReward"), new StatDisplay("Times Voted", "DailyVote") },
+ Material.EMERALD, 0, GameCategory.GLOBAL, "None"),
BRIDGES("The Bridges", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
@@ -28,15 +28,15 @@ public enum AchievementCategory
SKYWARS("Skywars",null,
new StatDisplay[]{StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED},
- Material.FEATHER, 5, GameCategory.SURVIVAL, "Destructor Kit"),
+ Material.FEATHER, 0, GameCategory.SURVIVAL, "Destructor Kit"),
UHC("Ultra Hardcore", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
- Material.GOLDEN_APPLE, 0, GameCategory.SURVIVAL, "Extra Class Skills"),
+ Material.GOLDEN_APPLE, 0, GameCategory.SURVIVAL, "None"),
WIZARDS("Wizards", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
- Material.BLAZE_ROD, 0, GameCategory.SURVIVAL, "Extra Class Skills"),
+ Material.BLAZE_ROD, 0, GameCategory.SURVIVAL, "Witch Doctor Kit"),
CASTLE_SIEGE("Castle Siege", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, new StatDisplay("Kills as Defenders"), new StatDisplay("Deaths as Defenders"),
@@ -45,7 +45,7 @@ public enum AchievementCategory
BLOCK_HUNT("Block Hunt", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
- Material.GRASS, 0, GameCategory.CLASSICS, null),
+ Material.GRASS, 0, GameCategory.CLASSICS, "Infestor Kit"),
SMASH_MOBS("Super Smash Mobs", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
@@ -53,11 +53,11 @@ public enum AchievementCategory
MINE_STRIKE("MineStrike", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
- Material.TNT, 0, GameCategory.CLASSICS, null),
+ Material.TNT, 0, GameCategory.CLASSICS, "None"),
DRAW_MY_THING("Draw My Thing", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.GEMS_EARNED },
- Material.BOOK_AND_QUILL, 0, GameCategory.CLASSICS, null),
+ Material.BOOK_AND_QUILL, 0, GameCategory.CLASSICS, "Extra Tools Kit"),
CHAMPIONS("Champions", new String[] {"Champions Domination", "Champions TDM"},
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
@@ -65,7 +65,7 @@ public enum AchievementCategory
MASTER_BUILDERS("Master Builders", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.GEMS_EARNED },
- Material.WOOD, 0, GameCategory.CLASSICS, null),
+ Material.WOOD, 0, GameCategory.CLASSICS, "None"),
//Arcade
DRAGONS("Dragons", null,
@@ -74,7 +74,7 @@ public enum AchievementCategory
DRAGON_ESCAPE("Dragon Escape", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.GEMS_EARNED },
- Material.DRAGON_EGG, 0, GameCategory.ARCADE, null),
+ Material.DRAGON_EGG, 0, GameCategory.ARCADE, "Digger Kit"),
SHEEP_QUEST("Sheep Quest", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
@@ -82,11 +82,11 @@ public enum AchievementCategory
SNEAKY_ASSASSINS("Sneaky Assassins", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
- Material.INK_SACK, 0, GameCategory.ARCADE, null),
+ Material.INK_SACK, 0, GameCategory.ARCADE, "Briber Kit"),
ONE_IN_THE_QUIVER("One in the Quiver", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
- Material.BOW, 0, GameCategory.ARCADE, null),
+ Material.BOW, 0, GameCategory.ARCADE, "Slam Shooter Kit"),
SUPER_PAINTBALL("Super Paintball", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
@@ -97,11 +97,11 @@ public enum AchievementCategory
Material.HARD_CLAY, 14, GameCategory.ARCADE, null),
RUNNER("Runner", null,
- new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
+ new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
Material.LEATHER_BOOTS, 0, GameCategory.ARCADE, null),
SPLEEF("Super Spleef", null,
- new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
+ new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
Material.IRON_SPADE, 0, GameCategory.ARCADE, null),
DEATH_TAG("Death Tag", null,
@@ -110,7 +110,7 @@ public enum AchievementCategory
SNAKE("Snake", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
- Material.WOOL, 4, GameCategory.ARCADE, null),
+ Material.WOOL, 4, GameCategory.ARCADE, "Reversal Snake Kit"),
BACON_BRAWL("Bacon Brawl", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
@@ -118,9 +118,12 @@ public enum AchievementCategory
MICRO_BATTLE("Micro Battle", null,
new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
- Material.LAVA, 0, GameCategory.ARCADE, null);
+ Material.LAVA, 0, GameCategory.ARCADE, null),
+
+ BOMB_LOBBERS("Bomb Lobbers", null,
+ new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED },
+ Material.FIREBALL, 0, GameCategory.ARCADE, "Waller Kit");
-
private String _name;
private String[] _statsToPull;
private StatDisplay[] _statDisplays;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementData.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementData.java
index 41e9562a2..5f1f617fd 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementData.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementData.java
@@ -3,10 +3,10 @@ package mineplex.core.achievement;
public class AchievementData
{
private int _level;
- private int _expRemainder;
- private int _expNextLevel;
+ private long _expRemainder;
+ private long _expNextLevel;
- public AchievementData(int level, int expRemainder, int expNextLevel)
+ public AchievementData(int level, long expRemainder, long expNextLevel)
{
_level = level;
_expRemainder = expRemainder;
@@ -18,12 +18,12 @@ public class AchievementData
return _level;
}
- public int getExpRemainder()
+ public long getExpRemainder()
{
return _expRemainder;
}
- public int getExpNextLevel()
+ public long getExpNextLevel()
{
return _expNextLevel;
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementLog.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementLog.java
index 6d6e37f91..1684c162f 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementLog.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementLog.java
@@ -2,10 +2,10 @@ package mineplex.core.achievement;
public class AchievementLog
{
- public int Amount;
+ public long Amount;
public boolean LevelUp;
- public AchievementLog(int amount, boolean levelUp)
+ public AchievementLog(long amount, boolean levelUp)
{
Amount = amount;
LevelUp = levelUp;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java
index 4fe166860..76e58b6fb 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java
@@ -137,15 +137,6 @@ public class AchievementManager extends MiniPlugin
_log.remove(event.getPlayer().getName());
}
- @EventHandler
- public void playerJoin(PlayerJoinEvent event)
- {
- if (_giveInterfaceItem)
- {
- giveInterfaceItem(event.getPlayer());
- }
- }
-
public void clearLog(Player player)
{
_log.remove(player.getName());
@@ -161,22 +152,7 @@ public class AchievementManager extends MiniPlugin
_giveInterfaceItem = giveInterfaceItem;
}
- public void giveInterfaceItem(Player player)
- {
- if (!UtilGear.isMat(player.getInventory().getItem(_interfaceSlot), Material.SKULL_ITEM))
- {
- ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, ChatColor.RESET + C.cGreen + "/stats");
- SkullMeta meta = ((SkullMeta) item.getItemMeta());
- meta.setOwner(player.getName());
- item.setItemMeta(meta);
-
- player.getInventory().setItem(_interfaceSlot, item);
-
- UtilInv.Update(player);
- }
- }
-
- @EventHandler
+ /*@EventHandler
public void openShop(PlayerInteractEvent event)
{
if (!_shopEnabled)
@@ -188,7 +164,7 @@ public class AchievementManager extends MiniPlugin
openShop(event.getPlayer());
}
- }
+ }*/
public boolean hasCategory(Player player, Achievement[] required)
{
@@ -208,18 +184,22 @@ public class AchievementManager extends MiniPlugin
{
int level = get(sender, Achievement.GLOBAL_MINEPLEX_LEVEL).getLevel();
+ if (sender.getName().equalsIgnoreCase("B2_mp"))
+ return 101;
+
+ if (rank.Has(Rank.MODERATOR))
+ level = Math.max(level, 5);
+ if (rank.Has(Rank.SNR_MODERATOR))
+ level = Math.max(level, 15);
+ if (rank.Has(Rank.JNR_DEV))
+ level = Math.max(level, 25);
+ if (rank.Has(Rank.ADMIN))
+ level = Math.max(level, 30 + get(sender, Achievement.GLOBAL_GEM_HUNTER).getLevel());
+ if (rank.Has(Rank.OWNER))
+ level = Math.max(level, 50 + get(sender, Achievement.GLOBAL_GEM_HUNTER).getLevel());
+
if (sender.getName().equalsIgnoreCase("Phinary"))
level = -level;
- else if (sender.getName().equalsIgnoreCase("B2_mp"))
- return 101;
- else if (rank.Has(Rank.OWNER))
- level = Math.max(level, 50 + get(sender, Achievement.GLOBAL_GEM_HUNTER).getLevel());
- else if (rank.Has(Rank.ADMIN))
- level = Math.max(level, 30 + get(sender, Achievement.GLOBAL_GEM_HUNTER).getLevel());
- else if (rank.Has(Rank.SNR_MODERATOR))
- level = Math.max(level, 15);
- else if (rank.Has(Rank.MODERATOR))
- level = Math.max(level, 5);
return level;
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java
index 2ab5e498f..7867fab9a 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java
@@ -57,7 +57,7 @@ public class AchievementMainPage extends ShopPageBase lore = new ArrayList();
lore.add(" ");
- category.addStats(getClientManager(), _statsManager, lore, category == AchievementCategory.GLOBAL ? 5 : 2,
+ category.addStats(getClientManager(), _statsManager, lore, category == AchievementCategory.GLOBAL ? 10 : 2,
getPlayer(), _target);
lore.add(" ");
addAchievements(category, lore, 9);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
index f7371bf4c..37ff11c9b 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
@@ -345,7 +345,7 @@ public class AntiHack extends MiniPlugin
}
//Auto-Kick
- if (!handled && _clientManager.Get(player).GetRank() == Rank.YOUTUBE)
+ if (!handled && _clientManager.Get(player).GetRank() != Rank.YOUTUBE && _clientManager.Get(player).GetRank() != Rank.TWITCH)
{
player.playSound(player.getLocation(), Sound.ENDERDRAGON_GROWL, 2f, 0.5f);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManager.java b/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManager.java
index 973950020..0301e0225 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/benefit/BenefitManager.java
@@ -73,7 +73,7 @@ public class BenefitManager extends MiniDbClientPlugin
}
@Override
- public void processLoginResultSet(String playerName, ResultSet resultSet) throws SQLException
+ public void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException
{
Set(playerName, _repository.retrievePlayerBenefitData(resultSet));
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java
index fd5b8bbc0..c7fe26dcc 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java
@@ -100,6 +100,8 @@ public class BlockRestoreData
if (_toID == 78) _toData = (byte)Math.min(7, _toData + addData);
else _toData = addData;
}
+ else
+ _toData = addData;
_toID = toID;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java
new file mode 100644
index 000000000..bb6d8c9f3
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java
@@ -0,0 +1,159 @@
+package mineplex.core.bonuses;
+
+import java.util.List;
+
+import org.bukkit.ChatColor;
+
+import mineplex.core.common.util.C;
+
+public class BonusAmount
+{
+ private int _gems;
+ private int _coins;
+ private int _gold;
+ private int _bonusGems;
+ private int _bonusCoins;
+ private int _bonusGold;
+ private int _experience;
+ private int _bonusExperience;
+ private int _tickets;
+
+ public BonusAmount()
+ {
+
+ }
+
+ public int getGems()
+ {
+ return _gems;
+ }
+
+ public void setGems(int gems)
+ {
+ _gems = gems;
+ }
+
+ public int getCoins()
+ {
+ return _coins;
+ }
+
+ public void setCoins(int coins)
+ {
+ _coins = coins;
+ }
+
+ public int getGold()
+ {
+ return _gold;
+ }
+
+ public void setGold(int gold)
+ {
+ _gold = gold;
+ }
+
+ public int getBonusGems()
+ {
+ return _bonusGems;
+ }
+
+ public void setBonusGems(int bonusGems)
+ {
+ _bonusGems = bonusGems;
+ }
+
+ public int getBonusCoins()
+ {
+ return _bonusCoins;
+ }
+
+ public void setBonusCoins(int bonusCoins)
+ {
+ _bonusCoins = bonusCoins;
+ }
+
+ public int getBonusGold()
+ {
+ return _bonusGold;
+ }
+
+ public void setBonusGold(int bonusGold)
+ {
+ _bonusGold = bonusGold;
+ }
+
+ public int getTotalGems()
+ {
+ return getGems() + getBonusGems();
+ }
+
+ public int getTotalCoins()
+ {
+ return getCoins() + getBonusCoins();
+ }
+
+ public int getTotalGold()
+ {
+ return getGold() + getBonusGold();
+ }
+
+ public int getExperience()
+ {
+ return _experience;
+ }
+
+ public void setExperience(int experience)
+ {
+ _experience = experience;
+ }
+
+ public int getBonusExperience()
+ {
+ return _bonusExperience;
+ }
+
+ public void setBonusExperience(int bonusExperience)
+ {
+ _bonusExperience = bonusExperience;
+ }
+
+ public int getTotalExperience()
+ {
+ return getExperience() + getBonusExperience();
+ }
+
+ public int getTickets()
+ {
+ return _tickets;
+ }
+
+ public void setTickets(int tickets)
+ {
+ _tickets = tickets;
+ }
+
+ public boolean isGreaterThanZero()
+ {
+ return _bonusCoins > 0 || _coins > 0 || _bonusGems > 0 || _gems > 0 || _gold > 0 || _bonusGold > 0;
+ }
+
+ public void addLore(List lore)
+ {
+ lore.add(C.cYellow + "Rewards");
+ addLore(lore, getTickets(), 0, "Carl Spin Ticket" + (getTickets() > 1 ? "s" : ""));
+ addLore(lore, getCoins(), getBonusCoins(), "Coins");
+ addLore(lore, getGems(), getBonusGems(), "Gems");
+ addLore(lore, getGold(), getBonusGold(), "Gold");
+ addLore(lore, getExperience(), getBonusExperience(), "Experience");
+ }
+
+ private void addLore(List lore, int amount, int bonus, String suffix)
+ {
+ if (amount > 0)
+ lore.add(" " + C.cWhite + amount + " " + suffix);
+
+// if (bonus > 0)
+// lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + bonus + " " + suffix);
+ }
+}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java
new file mode 100644
index 000000000..346f58b1c
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java
@@ -0,0 +1,127 @@
+package mineplex.core.bonuses;
+
+import java.sql.Date;
+import java.sql.Timestamp;
+
+import mineplex.core.hologram.Hologram;
+import mineplex.database.tables.records.BonusRecord;
+
+public class BonusClientData
+{
+ private Hologram _hologram;
+
+ private int _accountId;
+ private Timestamp _dailyTime;
+ private Date _rankTime;
+ private Date _voteTime;
+ private int _dailyStreak;
+ private int _maxDailyStreak;
+ private int _voteStreak;
+ private int _maxVoteStreak;
+ private int _tickets;
+
+ public BonusClientData()
+ {
+ _accountId = -1;
+ }
+
+ public void setAccountId(Integer value)
+ {
+ _accountId = value;
+ }
+
+ public Integer getAccountId()
+ {
+ return _accountId;
+ }
+
+ public void setDailyTime(Timestamp value)
+ {
+ _dailyTime = value;
+ }
+
+ public Timestamp getDailyTime()
+ {
+ return _dailyTime;
+ }
+
+ public void setRankTime(Date value)
+ {
+ _rankTime = value;
+ }
+
+ public Date getRankTime()
+ {
+ return _rankTime;
+ }
+
+ public void setVoteTime(Date value)
+ {
+ _voteTime = value;
+ }
+
+ public Date getVoteTime()
+ {
+ return _voteTime;
+ }
+
+ public void setDailyStreak(Integer value)
+ {
+ _dailyStreak = value;
+ }
+
+ public Integer getDailyStreak()
+ {
+ return _dailyStreak;
+ }
+
+ public void setMaxDailyStreak(Integer value)
+ {
+ _maxDailyStreak = value;
+ }
+
+ public Integer getMaxDailyStreak()
+ {
+ return _maxDailyStreak;
+ }
+
+ public void setVoteStreak(Integer value)
+ {
+ _voteStreak = value;
+ }
+
+ public Integer getVoteStreak()
+ {
+ return _voteStreak;
+ }
+
+ public void setMaxVoteStreak(Integer value)
+ {
+ _maxVoteStreak = value;
+ }
+
+ public Integer getMaxVoteStreak()
+ {
+ return _maxVoteStreak;
+ }
+
+ public void setTickets(Integer value)
+ {
+ _tickets = value;
+ }
+
+ public Integer getTickets()
+ {
+ return _tickets;
+ }
+
+ public Hologram getHologram()
+ {
+ return _hologram;
+ }
+
+ public void setHologram(Hologram hologram)
+ {
+ _hologram = hologram;
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java
new file mode 100644
index 000000000..0e0b52abf
--- /dev/null
+++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java
@@ -0,0 +1,1152 @@
+package mineplex.core.bonuses;
+
+import java.sql.Date;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.TimeZone;
+
+import mineplex.core.MiniClientPlugin;
+import mineplex.core.account.CoreClient;
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.account.ILoginProcessor;
+import mineplex.core.account.IQuerylessLoginProcessor;
+import mineplex.core.account.event.ClientUnloadEvent;
+import mineplex.core.bonuses.redis.VoteHandler;
+import mineplex.core.bonuses.redis.VotifierCommand;
+import mineplex.core.common.Rank;
+import mineplex.core.common.util.C;
+import mineplex.core.common.util.Callback;
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilParticle;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.common.util.UtilServer;
+import mineplex.core.common.util.UtilParticle.ParticleType;
+import mineplex.core.common.util.UtilParticle.ViewDist;
+import mineplex.core.database.DBPool;
+import mineplex.core.donation.DonationManager;
+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.pet.PetManager;
+import mineplex.core.recharge.Recharge;
+import mineplex.core.reward.RewardManager;
+import mineplex.core.stats.StatsManager;
+import mineplex.core.updater.UpdateType;
+import mineplex.core.updater.event.UpdateEvent;
+import mineplex.database.Tables;
+import mineplex.core.bonuses.animations.AnimationCarl;
+import mineplex.core.bonuses.commands.AnimationCommand;
+import mineplex.core.bonuses.commands.GuiCommand;
+import mineplex.core.bonuses.commands.TicketCommand;
+import mineplex.core.bonuses.event.CarlSpinnerEvent;
+import mineplex.core.bonuses.gui.BonusGui;
+import mineplex.database.tables.records.BonusRecord;
+import mineplex.core.bonuses.gui.SpinGui;
+import mineplex.core.poll.PollManager;
+import mineplex.serverdata.commands.ServerCommandManager;
+
+import org.jooq.DSLContext;
+import org.jooq.SQLDialect;
+import org.jooq.impl.DSL;
+import org.bukkit.Bukkit;
+import org.bukkit.Sound;
+import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity;
+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.PlayerInteractEntityEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import net.minecraft.server.v1_7_R4.DataWatcher;
+import net.minecraft.server.v1_7_R4.PacketPlayOutEntityMetadata;
+
+public class BonusManager extends MiniClientPlugin implements ILoginProcessor
+{
+
+ public static final TimeZone TIMEZONE = TimeZone.getTimeZone("UTC");
+
+ private static long timeOffSet = 0;
+
+ private ArrayList