Merge branch 'develop' into feature/dinnerbone-morph

This commit is contained in:
LCastr0 2016-12-22 03:51:40 -02:00
commit 09afab39d6
161 changed files with 8927 additions and 2098 deletions

View File

@ -20,6 +20,11 @@
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-serverdata</artifactId>
<version>dev-SNAPSHOT</version>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,162 @@
package mineplex.core.common;
import java.util.Iterator;
import java.util.Map;
import java.util.NavigableMap;
import java.util.PrimitiveIterator;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import com.google.common.base.Preconditions;
/**
* An Iterator that shuffles and provides integers from a specified range.
* The shuffle strategy is based on the Fisher-Yates shuffle.
*
* @see #nextInts(int)
* @see #nextInt()
*/
public class RangeShuffleIterator implements PrimitiveIterator.OfInt
{
private static final Random random = new Random();
private final IntSet _remaining;
private int _remainingCount;
/**
* Create a RangeShuffleIterator encompassing the specified range (inclusive)
*
* @param start The range lower bound, inclusive
* @param end The range upper bound, inclusive
*/
public RangeShuffleIterator(int start, int end)
{
Preconditions.checkArgument(start <= end);
_remaining = new IntSet(start, end);
_remainingCount = end - start + 1;
}
/**
* Provide a specified number of integers in an int array. If the number
* of elements remaining is fewer than {@code maxAmount}, return all
* remaining elements.
*
* @param maxAmount The number of elements to retrieve
* @return An array containing the retrieved elements
*/
public int[] nextInts(int maxAmount)
{
int[] ret = new int[Math.min(_remainingCount, maxAmount)];
for (int i = 0; i < ret.length; i++)
{
ret[i] = nextInt();
}
return ret;
}
@Override
public int nextInt()
{
if (!hasNext())
{
throw new IllegalStateException("No remaining ranges to iterate");
}
int selectedPosition = random.nextInt(_remainingCount);
Iterator<Map.Entry<Integer, Integer>> it = _remaining.ranges().iterator();
final int selected;
while (true)
{
Map.Entry<Integer, Integer> range = it.next();
int span = range.getValue() - range.getKey();
if (span < selectedPosition)
{
selectedPosition -= span + 1;
}
else
{
selected = range.getKey() + selectedPosition;
break;
}
}
_remaining.remove(selected);
--_remainingCount;
return selected;
}
@Override
public boolean hasNext()
{
return _remainingCount > 0;
}
/**
* A set of integers. The set is seeded by a single range, and the only
* supported operation is int removal.
* <p>
* This implementation only exists for performance reasons.
*/
private static class IntSet
{
/**
* A set of ranges representing the remaining integers in this set
*/
private final NavigableMap<Integer, Integer> ranges = new TreeMap<>();
/**
* Create an IntSet containing all numbers from {@code start} to
* {@code end}, inclusive
*
* @param start The range lower bound, inclusive
* @param end The range upper bound, inclusive
*/
private IntSet(int start, int end)
{
ranges.put(start, end);
}
public Set<Map.Entry<Integer, Integer>> ranges()
{
return ranges.entrySet();
}
/**
* Remove an integer from this IntSet
* @param value The integer to remove
*/
public void remove(int value)
{
Map.Entry<Integer,Integer> range = ranges.floorEntry(value);
if (range == null || range.getValue() < value)
{
return;
}
int lower = range.getKey();
int upper = range.getValue();
if (upper > value)
{
reinsert(value + 1, upper);
}
reinsert(lower, Math.min(upper, value - 1));
}
private void reinsert(int start, int end)
{
if (end < start)
{
ranges.remove(start);
}
else
{
ranges.put(start, end);
}
}
}
}

View File

@ -104,6 +104,11 @@ public class F
return rank.getColor() + cmd + " " + C.mBody + body + " " + rank(rank);
}
public static String help(String cmd, String body, Rank rank, ChatColor displayColor)
{
return displayColor + cmd + " " + C.mBody + body + " " + rank(rank);
}
public static String rank(Rank rank)
{
if (rank == Rank.ALL)

View File

@ -4,6 +4,7 @@ import com.google.common.collect.Sets;
import org.apache.commons.lang3.Validate;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
@ -218,7 +219,7 @@ public class PlayerMap<V> implements Map<UUID, V>
private static class RemovalListener implements Listener
{
@EventHandler
@EventHandler (priority = EventPriority.MONITOR)
public void onQuit(PlayerQuitEvent event)
{
synchronized (LOCK)

View File

@ -1,7 +1,10 @@
package mineplex.core.common.util;
import com.google.common.collect.Lists;
import mineplex.core.common.events.PlayerRecieveBroadcastEvent;
import mineplex.serverdata.Region;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.Sound;
@ -13,6 +16,7 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.lang.reflect.Field;
import java.util.*;
@ -52,7 +56,7 @@ public class UtilServer
{
return Bukkit.getServer();
}
public static void broadcast(String message)
{
for (Player cur : getPlayers())
@ -61,13 +65,13 @@ public class UtilServer
UtilPlayer.message(cur, message);
}
}
public static void broadcast(LinkedList<String> messages)
{
for (Player cur : getPlayers())
UtilPlayer.message(cur, messages);
}
public static void broadcastSpecial(String event, String message)
{
for (Player cur : getPlayers())
@ -78,32 +82,32 @@ public class UtilServer
cur.playSound(cur.getLocation(), Sound.ORB_PICKUP, 2f, 0f);
}
}
public static void broadcast(String sender, String message)
{
broadcast("§f§l" + sender + " " + "§b" + message);
}
public static void broadcastMagic(String sender, String message)
{
broadcast("§2§k" + message);
}
public static double getFilledPercent()
public static double getFilledPercent()
{
return (double)getPlayers().length / (double)UtilServer.getServer().getMaxPlayers();
return (double) getPlayers().length / (double) UtilServer.getServer().getMaxPlayers();
}
public static void RegisterEvents(Listener listener)
{
getPluginManager().registerEvents(listener, getPlugin());
}
public static void Unregister(Listener listener)
{
HandlerList.unregisterAll(listener);
}
public static JavaPlugin getPlugin()
{
return JavaPlugin.getProvidingPlugin(UtilServer.class);
@ -135,6 +139,16 @@ public class UtilServer
return getPlugin().getConfig().getString("serverstatus.name");
}
public static Region getRegion()
{
return getPlugin().getConfig().getBoolean("serverstatus.us") ? Region.US : Region.EU;
}
public static String getGroup()
{
return getPlugin().getConfig().getString("serverstatus.group");
}
public static boolean isTestServer()
{
return getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
@ -185,4 +199,39 @@ public class UtilServer
{
return getPlugin().getConfig().getString("webServer");
}
public static BukkitTask runAsync(Runnable runnable)
{
return getPlugin().getServer().getScheduler().runTaskAsynchronously(getPlugin(), runnable);
}
public static BukkitTask runAsync(Runnable runnable, long time)
{
return getPlugin().getServer().getScheduler().runTaskLaterAsynchronously(getPlugin(), runnable, time);
}
public static BukkitTask runAsyncTimer(Runnable runnable, long time, long period)
{
return getPlugin().getServer().getScheduler().runTaskTimerAsynchronously(getPlugin(), runnable, time, period);
}
public static BukkitTask runSync(Runnable runnable)
{
return getPlugin().getServer().getScheduler().runTask(getPlugin(), runnable);
}
public static BukkitTask runSyncLater(Runnable runnable, long delay)
{
return getPlugin().getServer().getScheduler().runTaskLater(getPlugin(), runnable, delay);
}
public static BukkitTask runSyncTimer(Runnable runnable, long delay, long period)
{
return getPlugin().getServer().getScheduler().runTaskTimer(getPlugin(), runnable, delay, period);
}
public static BukkitTask runSyncTimer(BukkitRunnable runnable, long delay, long period)
{
return runnable.runTaskTimer(getPlugin(), delay, period);
}
}

View File

@ -45,6 +45,11 @@
<artifactId>anticheat</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.5</version>
</dependency>
</dependencies>
<build>

View File

@ -14,6 +14,18 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import com.google.gson.Gson;
import mineplex.cache.player.PlayerCache;
@ -26,26 +38,14 @@ import mineplex.core.account.event.ClientWebResponseEvent;
import mineplex.core.account.repository.AccountRepository;
import mineplex.core.account.repository.token.ClientToken;
import mineplex.core.common.Rank;
import mineplex.core.common.timing.TimingManager;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UUIDFetcher;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTasks;
import mineplex.core.common.timing.TimingManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.utils.UtilGameProfile;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
public class CoreClientManager extends MiniPlugin
{
@ -453,6 +453,12 @@ public class CoreClientManager extends MiniPlugin
return !CLIENT_LOGIN_LOCKS.containsKey(client.getName());
}
public ClientToken loadOfflineClient(UUID uuid)
{
String client = _repository.getClientByUUID(uuid);
return new Gson().fromJson(client, ClientToken.class);
}
@EventHandler(priority = EventPriority.LOWEST)
public void Login(PlayerLoginEvent event)

File diff suppressed because it is too large Load Diff

View File

@ -1,71 +0,0 @@
package mineplex.core.antihack;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import mineplex.serverdata.database.DBPool;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class AntiHackRepository
{
private String _serverName;
//private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS AntiHack_Kick_Log (id INT NOT NULL AUTO_INCREMENT, updated LONG, playerName VARCHAR(256), motd VARCHAR(56), gameType VARCHAR(56), map VARCHAR(256), serverName VARCHAR(256), report VARCHAR(256), ping VARCHAR(25), PRIMARY KEY (id));";
private static String UPDATE_PLAYER_OFFENSES = "INSERT INTO AntiHack_Kick_Log (updated, playerName, motd, gameType, map, serverName, report, ping) VALUES (now(), ?, ?, ?, ?, ?, ?, ?);";
public AntiHackRepository(String serverName)
{
_serverName = serverName;
}
public void initialize()
{
}
public void saveOffense(final Player player, final String motd, final String game, final String map, final String report)
{
new Thread(new Runnable()
{
public void run()
{
PreparedStatement preparedStatement = null;
try (Connection connection = DBPool.getMineplexStats().getConnection())
{
preparedStatement = connection.prepareStatement(UPDATE_PLAYER_OFFENSES);
preparedStatement.setString(1, player.getName());
preparedStatement.setString(2, motd);
preparedStatement.setString(3, game);
preparedStatement.setString(4, map);
preparedStatement.setString(5, _serverName);
preparedStatement.setString(6, report);
preparedStatement.setString(7, ((CraftPlayer)player).getHandle().ping + "ms");
preparedStatement.execute();
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
}).start();
}
}

View File

@ -1,5 +1,7 @@
package mineplex.core.antihack;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.minecraft.server.v1_8_R3.ChatComponentText;
import net.minecraft.server.v1_8_R3.ChatModifier;
import net.minecraft.server.v1_8_R3.EnumChatFormat;
@ -25,10 +27,9 @@ public class CheckThresholds
return _friendlyName;
}
public IChatBaseComponent format(int violationLevel)
public void format(ComponentBuilder builder, int violationLevel)
{
EnumChatFormat color = getSeverity(violationLevel)._color;
return new ChatComponentText(_friendlyName).setChatModifier(new ChatModifier().setColor(color));
builder.append(_friendlyName, ComponentBuilder.FormatRetention.NONE).color(getSeverity(violationLevel)._color);
}
public Severity getSeverity(int violationLevel)
@ -51,14 +52,14 @@ public class CheckThresholds
public enum Severity
{
NONE(EnumChatFormat.GREEN),
LOW(EnumChatFormat.GREEN),
MEDIUM(EnumChatFormat.GOLD),
HIGH(EnumChatFormat.RED),
NONE(ChatColor.GREEN),
LOW(ChatColor.GREEN),
MEDIUM(ChatColor.GOLD),
HIGH(ChatColor.RED),
;
private final EnumChatFormat _color;
private final ChatColor _color;
Severity(EnumChatFormat color)
Severity(ChatColor color)
{
_color = color;
}

View File

@ -1,8 +0,0 @@
package mineplex.core.antihack;
import org.bukkit.entity.Player;
public interface Detector
{
public void Reset(Player player);
}

View File

@ -0,0 +1,50 @@
package mineplex.core.antihack;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import com.mineplex.anticheat.api.MineplexLink;
import mineplex.core.Managers;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.disguise.disguises.DisguiseBase;
public class MineplexLinkImpl implements MineplexLink
{
private final DisguiseManager _disguiseManager = Managers.require(DisguiseManager.class);
@Override
public EntityType getActiveDisguise(Player player)
{
DisguiseBase disguise = _disguiseManager.getActiveDisguise(player);
return disguise != null ? disguise.getDisguiseType() : null;
}
@Override
public boolean isSpectator(Player player)
{
return UtilPlayer.isSpectator(player);
}
@Override
public double getTPS()
{
return MinecraftServer.getServer().recentTps[0]; // Return the average TPS from the last minute
}
@Override
public int getPing(Player player)
{
return Math.min(((CraftPlayer) player).getHandle().ping, 1000);
}
@Override
public boolean isUsingItem(Player player)
{
return ((CraftPlayer) player).getHandle().bS(); // See Anticheat javadoc
}
}

View File

@ -0,0 +1,87 @@
package mineplex.core.antihack;
import com.mineplex.anticheat.checks.Check;
import com.mineplex.anticheat.checks.CheckManager;
import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TObjectIntHashMap;
/**
* Locally cached information about a user's max violations and total number of alerts for each
* check type.
* <p>
* Instances of this have no concept of identity i.e. account id is not tracked by this.
*/
public class ViolationLevels
{
private final TObjectIntMap<Class<? extends Check>> _maxViolations;
private final TObjectIntMap<Class<? extends Check>> _totalAlerts;
private final TObjectIntMap<Class<? extends Check>> _lastBan;
public ViolationLevels()
{
_maxViolations = new TObjectIntHashMap<>(CheckManager.AVAILABLE_CHECKS.size());
_totalAlerts = new TObjectIntHashMap<>(CheckManager.AVAILABLE_CHECKS.size());
_lastBan = new TObjectIntHashMap<>(CheckManager.AVAILABLE_CHECKS.size());
}
public void updateMaxViolations(Class<? extends Check> check, int violationLevel)
{
if (violationLevel > _maxViolations.get(check))
{
_maxViolations.put(check, violationLevel);
}
}
public void updateMaxViolationsSinceLastBan(Class<? extends Check> check, int violationLevel)
{
if (violationLevel > _lastBan.get(check))
{
_lastBan.put(check, violationLevel);
}
}
public void incrementAlerts(Class<? extends Check> check)
{
int cur = _totalAlerts.get(check);
setTotalAlerts(check, cur + 1);
}
public void setTotalAlerts(Class<? extends Check> check, int totalAlerts)
{
_totalAlerts.put(check, totalAlerts);
}
public int getTotalAlertsForCheck(Class<? extends Check> check)
{
if (_totalAlerts.containsKey(check))
{
return _totalAlerts.get(check);
}
return -1;
}
public int getMaxViolationsForCheck(Class<? extends Check> check)
{
if (_maxViolations.containsKey(check))
{
return _maxViolations.get(check);
}
return -1;
}
public int getLastBanViolationsForCheck(Class<? extends Check> check)
{
if (_lastBan.containsKey(check))
{
return _lastBan.get(check);
}
return -1;
}
}

View File

@ -4,6 +4,7 @@ import com.mineplex.anticheat.api.PlayerViolationEvent;
import com.mineplex.anticheat.checks.combat.KillauraTypeA;
import com.mineplex.anticheat.checks.combat.KillauraTypeD;
import com.mineplex.anticheat.checks.move.Glide;
import com.mineplex.anticheat.checks.move.HeadRoll;
import com.mineplex.anticheat.checks.move.Speed;
import mineplex.core.common.util.UtilServer;
import org.bukkit.event.Listener;
@ -13,40 +14,19 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public abstract class AntiHackAction implements Listener
public abstract class AntiHackAction
{
private static final Map<Class<?>, AntiHackAction> ACTIONS = new HashMap<>();
private static final AntiHackAction NOOP_ACTION = new NoopAction();
private static final Date NEXT_BAN_WAVE = new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5));
static
{
ACTIONS.put(KillauraTypeA.class, new ImmediateBanAction(200));
ACTIONS.put(KillauraTypeD.class, new BanwaveAction(2000));
ACTIONS.put(Glide.class, new ImmediateBanAction(10000));
ACTIONS.put(Speed.class, new ImmediateBanAction(10000));
}
private int _vl;
private final int _vl;
AntiHackAction(int vl)
{
this._vl = vl;
UtilServer.RegisterEvents(this);
}
public abstract void handle(PlayerViolationEvent event);
public int getMinVl()
public final int getMinVl()
{
return this._vl;
}
public static AntiHackAction getAction(Class<?> checkClass)
{
AntiHackAction action = ACTIONS.getOrDefault(checkClass, NOOP_ACTION);
return action;
}
public abstract void handle(PlayerViolationEvent event);
}

View File

@ -1,17 +1,18 @@
package mineplex.core.antihack.actions;
import com.mineplex.anticheat.api.PlayerViolationEvent;
import mineplex.core.Managers;
import mineplex.core.antihack.banwave.BanWaveManager;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
class BanwaveAction extends AntiHackAction
public class BanwaveAction extends AntiHackAction
{
private static final int BAN_DELAY_AVERAGE = 6 * 60 * 60 * 1000; // 6 hours
private static final int BAN_DELAY_VARIANCE_SPAN = 4 * 60 * 60 * 1000; // 4 hours total; 2 on either side
BanwaveAction(int vl)
public BanwaveAction(int vl)
{
super(vl);
}
@ -27,7 +28,6 @@ class BanwaveAction extends AntiHackAction
event.getPlayer(),
banTime,
event.getCheckClass(),
"[GWEN] Hacking [BanWave]",
event.getViolations(),
UtilServer.getServerName()
);

View File

@ -5,9 +5,9 @@ import mineplex.core.Managers;
import mineplex.core.antihack.AntiHack;
import mineplex.core.common.util.UtilServer;
class ImmediateBanAction extends AntiHackAction
public class ImmediateBanAction extends AntiHackAction
{
ImmediateBanAction(int vl)
public ImmediateBanAction(int vl)
{
super(vl);
}
@ -17,12 +17,7 @@ class ImmediateBanAction extends AntiHackAction
{
if (event.getViolations() >= this.getMinVl())
{
String server = UtilServer.getServerName();
if (server.contains("-"))
{
server = server.substring(0, server.indexOf('-'));
}
Managers.get(AntiHack.class).doBan(event.getPlayer(), "[GWEN] Hacking [" + server + "]");
Managers.get(AntiHack.class).doBan(event.getPlayer(), event.getCheckClass());
}
}
}

View File

@ -1,49 +0,0 @@
package mineplex.core.antihack.actions;
import com.mineplex.anticheat.api.PlayerViolationEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
public class MixedAction extends AntiHackAction
{
private List<AntiHackAction> _actions = new ArrayList<>();
private Map<UUID, Set<AntiHackAction>> _punished = new HashMap<>();
public MixedAction(AntiHackAction firstAction, AntiHackAction... actions)
{
super(firstAction.getMinVl());
this._actions.add(firstAction);
this._actions.addAll(Arrays.asList(actions));
}
@Override
public void handle(PlayerViolationEvent event)
{
for (int i = this._actions.size() - 1; i >= 0; i--)
{
AntiHackAction action = this._actions.get(i);
if (action.getMinVl() <= event.getViolations())
{
if (_punished.computeIfAbsent(event.getPlayer().getUniqueId(), key -> new HashSet<>()).add(action))
{
action.handle(event);
}
break;
}
}
}
public int getMinVl()
{
return this._actions.get(0).getMinVl();
}
}

View File

@ -4,7 +4,7 @@ import com.mineplex.anticheat.api.PlayerViolationEvent;
public class NoopAction extends AntiHackAction
{
NoopAction()
public NoopAction()
{
super(Integer.MAX_VALUE);
}

View File

@ -0,0 +1,9 @@
package mineplex.core.antihack.animations;
import mineplex.core.antihack.AntiHack;
import org.bukkit.entity.Player;
public interface BanwaveAnimation
{
void run(Player player, Runnable after);
}

View File

@ -0,0 +1,123 @@
package mineplex.core.antihack.animations;
import com.google.common.util.concurrent.AtomicDouble;
import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.guardians.AntiHackGuardian;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilServer;
import net.minecraft.server.v1_8_R3.MathHelper;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
public class BanwaveAnimationSpin implements BanwaveAnimation
{
@Override
public void run(Player player, Runnable after)
{
float oldWalkSpeed = player.getWalkSpeed();
player.setWalkSpeed(0);
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 999999, -10));
double radius = 4;
double heightAdj = 8;
double baseDeg = 18;
Location center = player.getLocation().add(0, heightAdj, 0);
AntiHackGuardian north = new AntiHackGuardian(center.clone().add(0, 0, -radius), 0, 0, 0, 0, 0, 0, false);
AntiHackGuardian east = new AntiHackGuardian(center.clone().add(radius, 0, 0), 0, 0, 0, 0, 0, 0, false);
AntiHackGuardian south = new AntiHackGuardian(center.clone().add(0, 0, radius), 0, 0, 0, 0, 0, 0, false);
AntiHackGuardian west = new AntiHackGuardian(center.clone().add(-radius, 0, 0), 0, 0, 0, 0, 0, 0, false);
UtilEnt.CreatureLook(east.getEntity(), player);
UtilEnt.CreatureLook(west.getEntity(), player);
UtilEnt.CreatureLook(south.getEntity(), player);
UtilEnt.CreatureLook(north.getEntity(), player);
Function<Double, Double> magic = seconds -> Math.pow(2, seconds - 5);
UtilServer.runSyncLater(() ->
{
north.shoot(player);
east.shoot(player);
south.shoot(player);
west.shoot(player);
// We get 5 seconds, or 100 ticks
AtomicInteger timer = new AtomicInteger(5);
AtomicDouble cNorth = new AtomicDouble(270);
AtomicDouble cEast = new AtomicDouble(0);
AtomicDouble cSouth = new AtomicDouble(90);
AtomicDouble cWest = new AtomicDouble(180);
UtilServer.runSyncTimer(new BukkitRunnable()
{
public void run()
{
timer.getAndIncrement();
if (timer.get() > 100)
{
cancel();
player.removePotionEffect(PotionEffectType.JUMP);
player.setWalkSpeed(oldWalkSpeed);
Location location = player.getLocation();
UtilParticle.PlayParticle(UtilParticle.ParticleType.HUGE_EXPLOSION, player.getLocation(), 3f, 3f, 3f, 0, 32, UtilParticle.ViewDist.MAX, UtilServer.getPlayers());
after.run();
north.shoot(null);
south.shoot(null);
east.shoot(null);
west.shoot(null);
UtilEnt.CreatureLook(north.getEntity(), location);
UtilEnt.CreatureLook(south.getEntity(), location);
UtilEnt.CreatureLook(east.getEntity(), location);
UtilEnt.CreatureLook(west.getEntity(), location);
UtilServer.runSyncLater(() ->
{
north.remove();
south.remove();
east.remove();
west.remove();
}, 40L);
return;
}
double seconds = timer.get() / 20.0;
double rate = magic.apply(seconds) * 3 * baseDeg;
player.getLocation(center);
center.add(0, heightAdj, 0);
{
cNorth.addAndGet(rate);
north.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cNorth.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cNorth.get())));
}
{
cSouth.addAndGet(rate);
south.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cSouth.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cSouth.get())));
}
{
cEast.addAndGet(rate);
east.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cEast.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cEast.get())));
}
{
cWest.addAndGet(rate);
west.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cWest.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cWest.get())));
}
}
}, 5L, 1L);
}, 20);
}
}

View File

@ -5,14 +5,25 @@ import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.account.CoreClient;
import mineplex.core.account.CoreClientManager;
import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.logging.AntihackLogger;
import mineplex.core.antihack.redisnotifications.GwenBanwaveNotification;
import mineplex.core.common.util.UtilServer;
import mineplex.serverdata.commands.ServerCommandManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import com.google.gson.JsonObject;
import com.mineplex.anticheat.checks.Check;
import com.mineplex.anticheat.checks.CheckManager;
@ReflectivelyCreateMiniPlugin
public class BanWaveManager extends MiniPlugin
{
private final BanWaveRepository _repository = new BanWaveRepository();
private final CoreClientManager _clientManager = require(CoreClientManager.class);
private BanWaveManager()
{
@ -32,29 +43,39 @@ public class BanWaveManager extends MiniPlugin
if (info.getTimeToBan() < now)
{
require(AntiHack.class).doBanWave(event.getPlayer(), info.getMessage());
require(AntiHack.class).doBanWave(event.getPlayer(), info);
_repository.flagDone(info);
}
});
});
}
public void insertBanWaveInfo(Player player, long timeToBan, Class<?> checkClass, String message, int vl, String server)
public void insertBanWaveInfo(Player player, long timeToBan, Class<? extends Check> checkClass, int vl, String server)
{
insertBanWaveInfo(player, timeToBan, checkClass, message, vl, server, null);
insertBanWaveInfo(player, timeToBan, checkClass, vl, server, null);
}
public void insertBanWaveInfo(Player player, long timeToBan, Class<?> checkClass, String message, int vl, String server, Runnable after)
public void insertBanWaveInfo(Player player, long timeToBan, Class<? extends Check> checkClass, int vl, String server, Runnable after)
{
runAsync(() ->
{
CoreClient client = require(CoreClientManager.class).Get(player);
String id = AntiHack.generateId();
String newMessage = "[GWEN] [BanWave] " + id;
this._repository.insertBanWaveInfo(client.getAccountId(), timeToBan, checkClass.getName(), message, vl, server);
CoreClient client = _clientManager.Get(player);
if (after != null)
if (this._repository.insertBanWaveInfo(client.getAccountId(), timeToBan, CheckManager.getCheckSimpleName(checkClass), newMessage, vl, server))
{
after.run();
runAsync(() ->
{
GwenBanwaveNotification notification = new GwenBanwaveNotification(UtilServer.getServerName(), player.getName(), player.getUniqueId().toString(), CheckManager.getCheckSimpleName(checkClass), id, timeToBan);
ServerCommandManager.getInstance().publishCommand(notification);
});
JsonObject custom = new JsonObject();
custom.addProperty("is-banwave", true);
require(AntihackLogger.class).saveMetadata(player, id, after, custom);
}
});
}

View File

@ -59,9 +59,9 @@ public class BanWaveRepository extends MinecraftRepository
}, new ColumnInt("accountId", accountId));
}
void insertBanWaveInfo(int accountId, long timeToBan, String hackType, String message, int vl, String server)
boolean insertBanWaveInfo(int accountId, long timeToBan, String hackType, String message, int vl, String server)
{
executeInsert(INSERT_PENDING, null,
int affectedRows = executeInsert(INSERT_PENDING, null,
new ColumnInt("accountId", accountId),
new ColumnLong("timeToBan", timeToBan),
new ColumnVarChar("hacktype", 64, hackType),
@ -69,6 +69,7 @@ public class BanWaveRepository extends MinecraftRepository
new ColumnInt("vl", vl),
new ColumnVarChar("server", 32, server)
);
return affectedRows > 0;
}
void flagDone(BanWaveInfo info)

View File

@ -0,0 +1,24 @@
package mineplex.core.antihack.commands;
import org.bukkit.entity.Player;
import mineplex.core.antihack.AntiHack;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
public class AnticheatOffCommand extends CommandBase<AntiHack>
{
public AnticheatOffCommand(AntiHack plugin)
{
super(plugin, Rank.DEVELOPER, "acoff");
}
@Override
public void Execute(Player caller, String[] args)
{
Plugin.disableAnticheat();
UtilPlayer.message(caller, F.main(Plugin.getName(), "Disabled anticheat"));
}
}

View File

@ -0,0 +1,24 @@
package mineplex.core.antihack.commands;
import org.bukkit.entity.Player;
import mineplex.core.antihack.AntiHack;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
public class AnticheatOnCommand extends CommandBase<AntiHack>
{
public AnticheatOnCommand(AntiHack plugin)
{
super(plugin, Rank.DEVELOPER, "acon");
}
@Override
public void Execute(Player caller, String[] args)
{
Plugin.enableAnticheat();
UtilPlayer.message(caller, F.main(Plugin.getName(), "Enabled anticheat"));
}
}

View File

@ -0,0 +1,30 @@
package mineplex.core.antihack.commands;
import org.bukkit.entity.Player;
import mineplex.core.antihack.AntiHack;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
public class DetailedMessagesCommand extends CommandBase<AntiHack>
{
public DetailedMessagesCommand(AntiHack plugin)
{
super(plugin, Rank.DEVELOPER, "detailedmessages");
}
@Override
public void Execute(Player caller, String[] args)
{
if (Plugin.toggleDetailedMessage(caller))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "Detailed messages enabled"));
}
else
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "Detailed messages disabled"));
}
}
}

View File

@ -0,0 +1,47 @@
package mineplex.core.antihack.commands;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import com.mineplex.anticheat.MineplexAnticheat;
import com.mineplex.anticheat.checks.Check;
import com.mineplex.anticheat.checks.CheckManager;
import mineplex.core.antihack.AntiHack;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
public class GetVlsCommand extends CommandBase<AntiHack>
{
public GetVlsCommand(AntiHack plugin)
{
super(plugin, Rank.DEVELOPER, "getvls");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length > 0)
{
Player p = Bukkit.getPlayerExact(args[0]);
if (p != null)
{
CheckManager manager = MineplexAnticheat.getPlugin(MineplexAnticheat.class).getCheckManager();
for (Check check : manager.getActiveChecks())
{
UtilPlayer.message(caller, F.desc(check.getName(), String.valueOf(check.getViolationLevel(p))));
}
}
else
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "Could not find player"));
}
}
else
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "No player specified"));
}
}
}

View File

@ -0,0 +1,51 @@
package mineplex.core.antihack.commands;
import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.animations.BanwaveAnimationSpin;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
public class TestBanCommand extends CommandBase<AntiHack>
{
public TestBanCommand(AntiHack plugin)
{
super(plugin, Rank.DEVELOPER, "testban");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length > 0)
{
Player p = Bukkit.getPlayerExact(args[0]);
if (p != null)
{
new BanwaveAnimationSpin().run(p, () ->
{
String reason = C.cRed + C.Bold + "You are banned for permanent by Test" +
"\n" + C.cWhite + "Seems to be speeding up time. (" + ThreadLocalRandom.current().nextInt(200, 400) + " packets/150 ms)" +
"\n" + C.cDGreen + "Unfairly banned? Appeal at " + C.cGreen + "www.mineplex.com/appeals";
p.kickPlayer(reason);
Plugin.announceBan(p);
});
}
else
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "Could not find player"));
}
}
else
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "No player specified"));
}
}
}

View File

@ -1,4 +1,4 @@
package mineplex.core.antihack;
package mineplex.core.antihack.guardians;
import com.mineplex.spigot.ChunkAddEntityEvent;
import mineplex.core.Managers;

View File

@ -0,0 +1,129 @@
package mineplex.core.antihack.guardians;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import mineplex.core.MiniPlugin;
import mineplex.core.PlayerSelector;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.Rank;
import mineplex.core.common.util.UtilLambda;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@ReflectivelyCreateMiniPlugin
public class GuardianManager extends MiniPlugin
{
private static final int MAX_STALKED_PLAYERS = 3;
private static final int STALK_COOLDOWN_TIME_SECONDS = 5;
private static final int MIN_STALK_TIME = 10 * 20;
private static final int MAX_STALK_TIME = 20 * 20;
private static final int MAX_MIN_DIFF = MAX_STALK_TIME - MIN_STALK_TIME;
private static final Function<Integer, Double> STALK_END_PROBABILITY_EQUATION = x ->
{
return 1.0/ MAX_MIN_DIFF * x; // linear equation with points (0, 0) and (diff, 1)
};
private final Cache<UUID, Boolean> _stalkingCooldown = CacheBuilder.newBuilder()
.concurrencyLevel(1)
.expireAfterWrite(STALK_COOLDOWN_TIME_SECONDS, TimeUnit.SECONDS)
.build();
private final List<UUID> _stalking = new ArrayList<>();
private List<AntiHackGuardian> _guardians = new ArrayList<>();
private GuardianManager()
{
super("GuardianManager");
this._plugin.getServer().getScheduler().runTaskTimer(this._plugin, () ->
{
for (AntiHackGuardian guardian : this._guardians)
{
if (guardian.getTarget() != null && !guardian.getTarget().isOnline())
{
this._stalking.remove(guardian.getTarget().getUniqueId());
guardian.stopTargeting();
}
else if (guardian.getTargetingTime() > MIN_STALK_TIME)
{
double threshold = STALK_END_PROBABILITY_EQUATION.apply(guardian.getTargetingTime() - MIN_STALK_TIME);
if (Math.random() <= threshold)
{
this._stalking.remove(guardian.getTarget().getUniqueId());
_stalkingCooldown.put(guardian.getTarget().getUniqueId(), true);
guardian.stopTargeting();
}
}
guardian.tick();
}
}, 0L, 1L);
this._plugin.getServer().getScheduler().runTaskTimer(this._plugin, () ->
{
if (_stalking.size() >= MAX_STALKED_PLAYERS)
{
return;
}
if (_guardians.size() == 0)
{
return;
}
List<Player> targets = PlayerSelector.selectPlayers(
UtilLambda.and(
PlayerSelector.NOT_VANISHED,
PlayerSelector.hasAnyRank(false,
Rank.ALL,
Rank.ULTRA,
Rank.HERO,
Rank.LEGEND,
Rank.TITAN,
Rank.TWITCH,
Rank.YOUTUBE_SMALL,
Rank.YOUTUBE,
Rank.MEDIA,
Rank.ADMIN,
Rank.DEVELOPER,
Rank.OWNER,
Rank.LT
),
player -> !_stalking.contains(player.getUniqueId()),
player -> _stalkingCooldown.getIfPresent(player.getUniqueId()) == null
));
while (_stalking.size() < MAX_STALKED_PLAYERS && targets.size() > 0)
{
Player target = targets.remove(ThreadLocalRandom.current().nextInt(targets.size()));
int start = ThreadLocalRandom.current().nextInt(_guardians.size());
for (int i = start, j = 0; j < _guardians.size(); i++, j++)
{
if (i >= _guardians.size())
{
i -= _guardians.size();
}
AntiHackGuardian guardian = _guardians.get(i);
if (!guardian.isTargeting())
{
guardian.target(target);
_stalking.add(target.getUniqueId());
break;
}
}
}
}, 0L, 20L);
}
public void registerGuardian(AntiHackGuardian guardian)
{
this._guardians.add(guardian);
}
}

View File

@ -0,0 +1,196 @@
package mineplex.core.antihack.logging;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Optional;
import org.bukkit.plugin.java.JavaPlugin;
import com.mineplex.anticheat.checks.Check;
import com.mineplex.anticheat.checks.CheckManager;
import mineplex.core.antihack.ViolationLevels;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
import gnu.trove.map.TIntObjectMap;
public class AnticheatDatabase extends MinecraftRepository
{
/*
CREATE TABLE IF NOT EXISTS anticheat_vl_logs (accountId INT, checkId INT, maxViolations INT, totalAlerts INT, sinceLastBan INT, PRIMARY KEY(accountId, checkId));
CREATE TABLE IF NOT EXISTS anticheat_ban_metadata (id INT NOT NULL AUTO_INCREMENT, accountId INT, banId CHAR(10) NOT NULL, data MEDIUMTEXT NOT NULL, PRIMARY KEY(id));
*/
private static final String INSERT_INTO_METADATA = "INSERT INTO anticheat_ban_metadata (accountId, banId, data) VALUES (?, ?, ?);";
private static final String UPDATE_VIOLATIONS = "INSERT INTO anticheat_vl_logs (accountId, checkId, "
+ "maxViolations, sinceLastBan, totalAlerts) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY"
+ " UPDATE maxViolations = VALUES(maxViolations), totalAlerts = VALUES(totalAlerts), sinceLastBan = VALUES(sinceLastBan);";
private static final String CLEAR_LAST_BAN_VIOLATIONS = "UPDATE anticheat_vl_logs SET sinceLastBan = 0 WHERE accountId = ?;";
private static final String GET_VLS = "SELECT checkId, maxViolations, sinceLastBan, totalAlerts FROM anticheat_vl_logs";
private static final String GET_VLS_BY_ACCOUNT_ID = GET_VLS + " WHERE accountId = ?";
private static final String GET_VLS_FOR_CHECK = GET_VLS + " WHERE checkId = ? AND accountId = ?";
public AnticheatDatabase(JavaPlugin plugin)
{
super(DBPool.getAccount());
}
/**
* Submit a set of user violation changes batch style.
*
* @param uploadQueue the {@link TIntObjectMap} describing the changes.
*/
public void saveViolationLevels(Map<Integer, ViolationLevels> uploadQueue)
{
try (Connection connection = getConnection())
{
PreparedStatement preparedStatement = connection.prepareStatement(UPDATE_VIOLATIONS);
uploadQueue.forEach((accountId, vls) ->
{
CheckManager.AVAILABLE_CHECKS.values().forEach(check ->
{
int checkId = CheckManager.getCheckId(check),
maxVls = vls.getMaxViolationsForCheck(check),
maxVlsSinceLastBan = vls.getLastBanViolationsForCheck(check),
totalAlerts = vls.getTotalAlertsForCheck(check);
// if neither value has been set don't store anything
if (maxVls < 0 && totalAlerts < 0 && maxVlsSinceLastBan < 0)
{
return;
}
maxVls = Math.max(maxVls, 0);
maxVlsSinceLastBan = Math.max(maxVlsSinceLastBan, 0);
totalAlerts = Math.max(totalAlerts, 0);
try
{
preparedStatement.setInt(1, accountId);
preparedStatement.setInt(2, checkId);
preparedStatement.setInt(3, maxVls);
preparedStatement.setInt(4, maxVlsSinceLastBan);
preparedStatement.setInt(5, totalAlerts);
preparedStatement.addBatch();
}
catch (SQLException e)
{
e.printStackTrace();
}
});
});
preparedStatement.executeBatch();
}
catch (SQLException ex)
{
ex.printStackTrace();
}
}
/**
* Attempts to retrieve violation levels for the given account id.
*
* @param accountId The account id;
* @return an {@link Optional} describing the user's violation levels, or an empty one if none
* are found.
* @throws SQLException On failing to connect to the database.
*/
public Optional<ViolationLevels> getViolationLevels(int accountId)
{
ViolationLevels levels = new ViolationLevels();
try (Connection connection = getConnection())
{
PreparedStatement statement = connection.prepareStatement(GET_VLS_BY_ACCOUNT_ID);
statement.setInt(1, accountId);
ResultSet result = statement.executeQuery();
while (result.next())
{
int checkId = result.getInt("checkId");
Class<? extends Check> checkType = CheckManager.getCheckById(checkId);
if (checkType == null)
{
System.err.println("Whoops. Unintended refactor?");
continue;
}
levels.updateMaxViolations(checkType, result.getInt("maxViolations"));
levels.updateMaxViolationsSinceLastBan(checkType, result.getInt("sinceLastBan"));
levels.setTotalAlerts(checkType, result.getInt("totalAlerts"));
}
}
catch (SQLException ex)
{
ex.printStackTrace();
}
return Optional.of(levels);
}
public void clearLastBan(int accountId, Runnable after)
{
try (Connection connection = getConnection())
{
PreparedStatement statement = connection.prepareStatement(CLEAR_LAST_BAN_VIOLATIONS);
statement.setInt(1, accountId);
statement.executeUpdate();
}
catch (SQLException e)
{
e.printStackTrace();
}
finally
{
if (after != null)
after.run();
}
}
public void saveMetadata(int accountId, String id, String base64, Runnable after)
{
try (Connection connection = getConnection())
{
PreparedStatement statement = connection.prepareStatement(INSERT_INTO_METADATA);
statement.setInt(1, accountId);
statement.setString(2, id);
statement.setString(3, base64);
statement.executeUpdate();
}
catch (SQLException ex)
{
ex.printStackTrace();
}
finally
{
if (after != null)
after.run();
}
}
@Override
protected void initialize()
{
}
@Override
protected void update()
{
}
}

View File

@ -0,0 +1,23 @@
package mineplex.core.antihack.logging;
import java.util.UUID;
import org.bukkit.event.Listener;
import com.google.gson.JsonElement;
import mineplex.core.common.util.UtilServer;
public abstract class AnticheatMetadata implements Listener
{
public AnticheatMetadata()
{
UtilServer.RegisterEvents(this);
}
public abstract String getId();
public abstract JsonElement build(UUID player);
public abstract void remove(UUID player);
}

View File

@ -0,0 +1,214 @@
package mineplex.core.antihack.logging;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.tukaani.xz.LZMA2Options;
import org.tukaani.xz.XZ;
import org.tukaani.xz.XZOutputStream;
import com.google.gson.Gson;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.mineplex.anticheat.api.PlayerViolationEvent;
import com.mineplex.anticheat.checks.Check;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.ViolationLevels;
import mineplex.core.antihack.logging.builtin.PartyInfoMetadata;
import mineplex.core.antihack.logging.builtin.PlayerInfoMetadata;
import mineplex.core.antihack.logging.builtin.ServerInfoMetadata;
import mineplex.core.antihack.logging.builtin.ViolationInfoMetadata;
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.common.util.UtilServer;
@ReflectivelyCreateMiniPlugin
public class AntihackLogger extends MiniPlugin
{
public static final Gson GSON = new Gson();
private static final int PUSH_QUEUE_TIME_IN_SECONDS = 60;
private final CoreClientManager _clientManager = require(CoreClientManager.class);
private final Map<Integer, ViolationLevels> _violationLevels = new ConcurrentHashMap<>();
private final Map<String, AnticheatMetadata> _metadata = new HashMap<>();
private final AnticheatDatabase _db;
private AntihackLogger()
{
super("AnticheatPlugin");
_db = new AnticheatDatabase(getPlugin());
runSyncTimer(this::pushQueuedViolationChanges, 20, 20 * PUSH_QUEUE_TIME_IN_SECONDS);
registerMetadata(new ServerInfoMetadata());
registerMetadata(new ViolationInfoMetadata());
registerMetadata(new PartyInfoMetadata());
registerMetadata(new PlayerInfoMetadata());
}
@Override
public void disable()
{
pushQueuedViolationChanges();
}
@EventHandler
public void addCommands()
{
if (UtilServer.isTestServer())
{
addCommand(new CommandBase<AntihackLogger>(this, Rank.SNR_MODERATOR, "savemetadata")
{
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 1)
{
Player player = Bukkit.getPlayer(args[0]);
if (player != null)
{
JsonObject custom = new JsonObject();
custom.addProperty("is-test-metadata", true);
String id = AntiHack.generateId();
saveMetadata(player, id, () ->
{
UtilPlayer.message(caller, F.main(getName(), "Saved metadata for " + player.getName() + " with id " + id));
}, custom);
}
}
}
});
}
}
private void pushQueuedViolationChanges()
{
Map<Integer, ViolationLevels> clone = new HashMap<>(_violationLevels);
runAsync(() -> _db.saveViolationLevels(clone));
}
@EventHandler
public void onCheckFail(PlayerViolationEvent event)
{
ViolationLevels playerVls = _violationLevels.get(_clientManager.getAccountId(event.getPlayer()));
Class<? extends Check> check = event.getCheckClass();
playerVls.updateMaxViolations(check, event.getViolations());
playerVls.updateMaxViolationsSinceLastBan(check, event.getViolations());
playerVls.incrementAlerts(check);
}
@EventHandler
public void onLoad(PlayerLoginEvent event)
{
runAsync(() ->
{
int accountId = _clientManager.getAccountId(event.getPlayer());
_db.getViolationLevels(accountId)
.ifPresent(vls ->
{
_violationLevels.put(accountId, vls);
});
});
}
@EventHandler
public void onQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
int accountId =_clientManager.getAccountId(event.getPlayer());
ViolationLevels levels = _violationLevels.get(accountId);
if (levels != null)
{
Map<Integer, ViolationLevels> clone = new HashMap<>();
clone.put(accountId, levels);
runAsync(() -> _db.saveViolationLevels(clone));
}
_metadata.values().forEach(metadata -> metadata.remove(event.getPlayer().getUniqueId()));
}
public void saveMetadata(Player player, String id, Runnable after, JsonObject custom)
{
runAsync(() ->
{
JsonObject info = new JsonObject();
for (AnticheatMetadata anticheatMetadata : _metadata.values())
{
try
{
info.add(anticheatMetadata.getId(), anticheatMetadata.build(player.getUniqueId()));
}
catch (Throwable t)
{
t.printStackTrace();
}
}
info.add("custom", custom == null ? JsonNull.INSTANCE: custom);
String str = GSON.toJson(info);
byte[] b = str.getBytes(StandardCharsets.UTF_8);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try
{
XZOutputStream o2 = new XZOutputStream(bout, new LZMA2Options(LZMA2Options.PRESET_MIN), XZ.CHECK_NONE);
o2.write(b);
o2.close();
}
catch (IOException ex)
{
// Should never happen
ex.printStackTrace();
}
String base64 = Base64.getEncoder().encodeToString(bout.toByteArray());
_db.saveMetadata(_clientManager.getAccountId(player), id, base64, after);
});
}
public void registerMetadata(AnticheatMetadata metadata)
{
if (!this._metadata.containsKey(metadata.getId()))
{
this._metadata.put(metadata.getId(), metadata);
}
else
{
throw new IllegalArgumentException("Attempting to register: " + metadata.getId());
}
}
public void resetViolations(Player player, Runnable after)
{
_db.clearLastBan(_clientManager.getAccountId(player), after);
}
}

View File

@ -0,0 +1,55 @@
package mineplex.core.antihack.logging.builtin;
import java.util.UUID;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import mineplex.core.antihack.logging.AnticheatMetadata;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import static mineplex.core.Managers.require;
public class PartyInfoMetadata extends AnticheatMetadata
{
private static final String KEY_OWNER = "owner";
private static final String KEY_MEMBERS = "members";
@Override
public String getId()
{
return "party-info";
}
@Override
public JsonElement build(UUID player)
{
Party party = require(PartyManager.class).getPlayerParties().get(player);
if (party != null)
{
JsonObject partyData = new JsonObject();
partyData.addProperty(KEY_OWNER, party.getOwner());
JsonArray members = new JsonArray();
party.getMembers().forEach(m -> members.add(new JsonPrimitive(m)));
partyData.add(KEY_MEMBERS, members);
return partyData;
}
else
{
return JsonNull.INSTANCE;
}
}
@Override
public void remove(UUID player)
{
}
}

View File

@ -0,0 +1,51 @@
package mineplex.core.antihack.logging.builtin;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import mineplex.core.account.CoreClientManager;
import mineplex.core.antihack.logging.AnticheatMetadata;
import static mineplex.core.Managers.require;
public class PlayerInfoMetadata extends AnticheatMetadata
{
private static final String KEY_UUID = "uuid";
private static final String KEY_ACCOUNT_ID = "accountid";
private static final String KEY_NAME = "name";
private final CoreClientManager _clientManager = require(CoreClientManager.class);
@Override
public String getId()
{
return "player-info";
}
@Override
public JsonElement build(UUID player)
{
JsonObject object = new JsonObject();
object.addProperty(KEY_UUID, player.toString());
Player bPlayer = Bukkit.getPlayer(player);
if (bPlayer != null)
{
object.addProperty(KEY_NAME, bPlayer.getName());
object.addProperty(KEY_ACCOUNT_ID, _clientManager.getAccountId(bPlayer));
}
return object;
}
@Override
public void remove(UUID player)
{
}
}

View File

@ -0,0 +1,38 @@
package mineplex.core.antihack.logging.builtin;
import java.util.UUID;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import mineplex.core.antihack.logging.AnticheatMetadata;
import mineplex.core.common.util.UtilServer;
public class ServerInfoMetadata extends AnticheatMetadata
{
private static final String KEY_SERVER_NAME = "server-name";
private static final String KEY_SERVER_REGION = "server-region";
private static final String KEY_SERVER_GROUP = "server-group";
@Override
public String getId()
{
return "server-info";
}
@Override
public JsonElement build(UUID player)
{
JsonObject info = new JsonObject();
info.addProperty(KEY_SERVER_NAME, UtilServer.getServerName());
info.addProperty(KEY_SERVER_REGION, UtilServer.getRegion().name());
info.addProperty(KEY_SERVER_GROUP, UtilServer.getGroup());
return info;
}
@Override
public void remove(UUID player)
{
}
}

View File

@ -0,0 +1,154 @@
package mineplex.core.antihack.logging.builtin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mineplex.anticheat.api.CheckDisabledEvent;
import com.mineplex.anticheat.api.PlayerViolationEvent;
import com.mineplex.anticheat.checks.Check;
import mineplex.core.antihack.logging.AnticheatMetadata;
import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.TObjectLongMap;
import gnu.trove.map.hash.TObjectIntHashMap;
import gnu.trove.map.hash.TObjectLongHashMap;
public class ViolationInfoMetadata extends AnticheatMetadata
{
private static final Location MUTABLE_LOCATION = new Location(null, 0, 0, 0);
private static final String KEY_JOIN_TIME_MS = "join-time-ms";
private static final String KEY_JOIN_TIME_TICK = "join-time-tick";
private static final String KEY_CURRENT_TIME = "current-time";
private static final String KEY_MS = "ms";
private static final String KEY_TICK = "tick";
private static final String KEY_VIOLATION_INFO = "violation-info";
private static final String KEY_VL = "current-vl";
private static final String KEY_MESSAGE = "msg";
private static final String KEY_PLAYER_INFO = "player-info";
private static final String KEY_LOCATION = "loc";
private static final String KEY_WORLD = "world";
private static final String KEY_X = "x";
private static final String KEY_Y = "y";
private static final String KEY_Z = "z";
private static final String KEY_YAW = "yaw";
private static final String KEY_PITCH = "pitch";
private static final JsonObject VAL_CHECK_DISABLED;
static
{
VAL_CHECK_DISABLED = new JsonObject();
VAL_CHECK_DISABLED.addProperty(KEY_MESSAGE, "disabled");
}
private TObjectLongMap<UUID> _joinTime = new TObjectLongHashMap<>();
private TObjectIntMap<UUID> _joinTimeTick = new TObjectIntHashMap<>();
private Map<UUID, Map<Class<? extends Check>, List<JsonObject>>> _violations = new HashMap<>();
@Override
public String getId()
{
return "violation-info";
}
@Override
public JsonElement build(UUID player)
{
JsonObject object = new JsonObject();
object.addProperty(KEY_JOIN_TIME_MS, _joinTime.get(player));
object.addProperty(KEY_JOIN_TIME_TICK, _joinTimeTick.get(player));
_violations.get(player).forEach((check, list) ->
{
JsonArray checkElem = new JsonArray();
list.forEach(checkElem::add);
object.add(check.getName(), checkElem);
});
return object;
}
@Override
public void remove(UUID player)
{
_joinTime.remove(player);
_joinTimeTick.remove(player);
_violations.remove(player);
}
@EventHandler
public void onJoin(PlayerJoinEvent event)
{
long thisMs = System.currentTimeMillis();
int thisTick = MinecraftServer.getServer().at();
_joinTime.put(event.getPlayer().getUniqueId(), thisMs);
_joinTimeTick.put(event.getPlayer().getUniqueId(), thisTick);
_violations.put(event.getPlayer().getUniqueId(), new HashMap<>());
}
@EventHandler
public void onDisabledCheck(CheckDisabledEvent event)
{
_violations.values().forEach(map ->
{
List<JsonObject> data = map.get(event.getCheck());
if (data != null)
{
data.add(VAL_CHECK_DISABLED);
}
});
}
@EventHandler
public void onViolation(PlayerViolationEvent event)
{
long thisMs = System.currentTimeMillis();
int thisTick = MinecraftServer.getServer().at();
List<JsonObject> violations = _violations.get(event.getPlayer().getUniqueId()).computeIfAbsent(event.getCheckClass(), key -> new ArrayList<>());
JsonObject currentTime = new JsonObject();
currentTime.addProperty(KEY_MS, thisMs);
currentTime.addProperty(KEY_TICK, thisTick);
JsonObject violationInfo = new JsonObject();
violationInfo.addProperty(KEY_VL, event.getViolations());
violationInfo.addProperty(KEY_MESSAGE, event.getMessage());
event.getPlayer().getLocation(MUTABLE_LOCATION);
JsonObject playerInfo = new JsonObject();
JsonObject location = new JsonObject();
location.addProperty(KEY_WORLD, MUTABLE_LOCATION.getWorld().getName());
location.addProperty(KEY_X, MUTABLE_LOCATION.getX());
location.addProperty(KEY_Y, MUTABLE_LOCATION.getY());
location.addProperty(KEY_Z, MUTABLE_LOCATION.getZ());
location.addProperty(KEY_YAW, MUTABLE_LOCATION.getYaw());
location.addProperty(KEY_PITCH, MUTABLE_LOCATION.getPitch());
playerInfo.add(KEY_LOCATION, location);
JsonObject data = new JsonObject();
data.add(KEY_CURRENT_TIME, currentTime);
data.add(KEY_VIOLATION_INFO, violationInfo);
data.add(KEY_PLAYER_INFO, playerInfo);
violations.add(data);
}
}

View File

@ -0,0 +1,46 @@
package mineplex.core.antihack.redisnotifications;
import mineplex.serverdata.commands.ServerCommand;
public class GwenBanNotification extends ServerCommand
{
private final String _serverName;
private final String _playerName;
private final String _playerUUID;
private final String _hackType;
private final String _metadataId;
public GwenBanNotification(String serverName, String playerName, String playerUUID, String hackType, String metadataId)
{
_serverName = serverName;
_playerName = playerName;
_playerUUID = playerUUID;
_hackType = hackType;
_metadataId = metadataId;
}
public String getServerName()
{
return _serverName;
}
public String getPlayerName()
{
return _playerName;
}
public String getPlayerUUID()
{
return _playerUUID;
}
public String getHackType()
{
return _hackType;
}
public String getMetadataId()
{
return _metadataId;
}
}

View File

@ -0,0 +1,53 @@
package mineplex.core.antihack.redisnotifications;
import mineplex.serverdata.commands.ServerCommand;
public class GwenBanwaveNotification extends ServerCommand
{
private final String _serverName;
private final String _playerName;
private final String _playerUUID;
private final String _hackType;
private final String _metadataId;
private final long _timeToBan;
public GwenBanwaveNotification(String serverName, String playerName, String playerUUID, String hackType, String metadataId, long timeToBan)
{
_serverName = serverName;
_playerName = playerName;
_playerUUID = playerUUID;
_hackType = hackType;
_metadataId = metadataId;
_timeToBan = timeToBan;
}
public String getServerName()
{
return _serverName;
}
public String getPlayerName()
{
return _playerName;
}
public String getPlayerUUID()
{
return _playerUUID;
}
public String getHackType()
{
return _hackType;
}
public String getMetadataId()
{
return _metadataId;
}
public long getTimeToBan()
{
return _timeToBan;
}
}

View File

@ -1,172 +0,0 @@
package mineplex.core.antihack.types;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map.Entry;
import mineplex.core.MiniPlugin;
import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.Detector;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class Fly extends MiniPlugin implements Detector
{
private AntiHack Host;
private HashMap<Player, Entry<Integer, Double>> _floatTicks = new HashMap<Player, Entry<Integer, Double>>(); //Ticks, PrevY
private HashMap<Player, Entry<Integer, Double>> _hoverTicks = new HashMap<Player, Entry<Integer, Double>>(); //Ticks, PrevY
private HashMap<Player, Entry<Integer, Double>> _riseTicks = new HashMap<Player, Entry<Integer, Double>>(); //Ticks, PrevY
public Fly (AntiHack host)
{
super("Fly Detector", host.getPlugin());
Host = host;
}
@EventHandler(priority = EventPriority.MONITOR)
public void updateFlyhack(PlayerMoveEvent event)
{
if (!Host.isEnabled())
return;
Player player = event.getPlayer();
//100% Valid
if (Host.isValid(player, true))
Reset(player);
//Hasn't moved, just looking around
if (UtilMath.offset(event.getFrom(), event.getTo()) <= 0)
{
updateFloat(player);
return;
}
else
{
_floatTicks.remove(player);
}
updateHover(player);
updateRise(player);
}
private void updateFloat(Player player)
{
int count = 0;
if (_floatTicks.containsKey(player))
{
if (player.getLocation().getY() == _floatTicks.get(player).getValue())
{
count = _floatTicks.get(player).getKey() + 1;
}
else
{
count = 0;
}
}
if (count > Host.FloatHackTicks)
{
Host.addSuspicion(player, "Fly (Float)");
count -= 2;
}
_floatTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY()));
}
private void updateHover(Player player)
{
int count = 0;
if (_hoverTicks.containsKey(player))
{
if (player.getLocation().getY() == _hoverTicks.get(player).getValue())
{
count = _hoverTicks.get(player).getKey() + 1;
}
else
{
count = 0;
}
//player.sendMessage(count + " - " + player.getLocation().getY() + " vs " + _hoverTicks.get(player).getValue());
}
if (count > Host.HoverHackTicks)
{
Host.addSuspicion(player, "Fly (Hover)");
count -= 2;
}
_hoverTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY()));
}
private void updateRise(Player player)
{
int count = 0;
if (_riseTicks.containsKey(player))
{
if (player.getLocation().getY() >= _riseTicks.get(player).getValue())
{
boolean nearBlocks = false;
for (Block block : UtilBlock.getSurrounding(player.getLocation().getBlock(), true))
{
if (block.getType() != Material.AIR)
{
nearBlocks = true;
break;
}
}
for (PotionEffect effect : player.getActivePotionEffects())
if (effect.getType() == PotionEffectType.JUMP || effect.getType().equals(PotionEffectType.JUMP))
nearBlocks = true;
if (nearBlocks)
{
count = 0;
}
else
{
count = _riseTicks.get(player).getKey() + 1;
}
}
else
{
count = 0;
}
}
if (count > Host.RiseHackTicks)
{
//Only give Offense if actually rising - initial ticks can be trigged via Hover.
if (player.getLocation().getY() > _riseTicks.get(player).getValue())
Host.addSuspicion(player, "Fly (Rise)");
count -= 2;
}
_riseTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY()));
}
@Override
public void Reset(Player player)
{
_floatTicks.remove(player);
_hoverTicks.remove(player);
_riseTicks.remove(player);
}
}

View File

@ -1,78 +0,0 @@
package mineplex.core.antihack.types;
import java.util.HashMap;
import mineplex.core.MiniPlugin;
import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.Detector;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;
public class Idle extends MiniPlugin implements Detector
{
private AntiHack Host;
private HashMap<Player, Long> _idleTime = new HashMap<Player, Long>();
public Idle (AntiHack host)
{
super("Idle Detector", host.getPlugin());
Host = host;
}
@EventHandler(priority = EventPriority.MONITOR)
public void updateFlyhack(PlayerMoveEvent event)
{
if (!Host.isEnabled())
return;
Player player = event.getPlayer();
_idleTime.put(player, System.currentTimeMillis());
}
@EventHandler(priority = EventPriority.MONITOR)
public void updateFreeCam(UpdateEvent event)
{
if (!Host.isEnabled())
return;
if (event.getType() != UpdateType.FAST)
return;
for (Player player : UtilServer.getPlayers())
{
//100% Valid
if (Host.isValid(player, true))
continue;
if (!_idleTime.containsKey(player))
continue;
if (!UtilTime.elapsed(_idleTime.get(player), Host.IdleTime))
continue;
//Host.addSuspicion(player, "Lag / Fly (Idle)");
//player.kickPlayer(C.cGold + "Mineplex " + C.cRed + "Anti-Cheat " + C.cWhite + "Kicked for Lag / Fly (Idle)");
UtilPlayer.message(player, C.cRed + C.Bold + "Mineplex Anti-Cheat detected Lagging / Fly (Idle)");
UtilPlayer.message(player, C.cRed + C.Bold + "You have been returned to Lobby.");
Host.Portal.sendPlayerToServer(player, "Lobby");
}
}
@Override
public void Reset(Player player)
{
_idleTime.remove(player);
}
}

View File

@ -1,123 +0,0 @@
package mineplex.core.antihack.types;
import java.util.ArrayList;
import java.util.HashMap;
import mineplex.core.MiniPlugin;
import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.Detector;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
public class Reach extends MiniPlugin implements Detector
{
private AntiHack Host;
private HashMap<Player, ArrayList<Location>> _history = new HashMap<Player, ArrayList<Location>>();
public Reach (AntiHack host)
{
super("Reach Detector", host.getPlugin());
Host = host;
}
@EventHandler(priority = EventPriority.LOWEST)
public void recordMove(UpdateEvent event)
{
if (!Host.isEnabled())
return;
if (event.getType() != UpdateType.TICK)
return;
for (Player player : UtilServer.getPlayers())
{
if (player.getGameMode() != GameMode.SURVIVAL || UtilPlayer.isSpectator(player))
continue;
if (!_history.containsKey(player))
_history.put(player, new ArrayList<Location>());
_history.get(player).add(0, player.getLocation());
while (_history.get(player).size() > 40)
{
_history.get(player).remove(_history.get(player).size()-1);
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void reachDetect(EntityDamageEvent event)
{
if (event.getCause() != DamageCause.ENTITY_ATTACK)
return;
if (!(event.getEntity() instanceof Player))
return;
LivingEntity damagerEntity = UtilEvent.GetDamagerEntity(event, false);
if (!(damagerEntity instanceof Player))
return;
Player damager = (Player)damagerEntity;
Player damagee = (Player)event.getEntity();
if (!isInRange(damager.getLocation(), damagee.getLocation()))
{
ArrayList<Location> damageeHistory = _history.get(damagee);
if (damageeHistory != null)
{
for (Location historyLoc : damageeHistory)
{
if (isInRange(damager.getLocation(), historyLoc))
{
return;
}
}
}
//Host.addSuspicion(damager, "Reach");
}
}
private boolean isInRange(Location a, Location b)
{
//2d Range
double distFlat = UtilMath.offset2d(a, b); //Limit is 3.40
if (distFlat > 3.4)
{
return true;
}
//3d Range
double dist = UtilMath.offset(a, b); //Limit is 6 (highest i saw was 5.67)
if (dist > 6.0)
{
return true;
}
return false;
}
@Override
public void Reset(Player player)
{
_history.remove(player);
}
}

View File

@ -1,105 +0,0 @@
package mineplex.core.antihack.types;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map.Entry;
import mineplex.core.MiniPlugin;
import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.Detector;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTime;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class Speed extends MiniPlugin implements Detector
{
private AntiHack Host;
private HashMap<Player, Entry<Integer, Long>> _speedTicks = new HashMap<Player, Entry<Integer, Long>>(); //Ticks, PrevY
public Speed (AntiHack host)
{
super("Speed Detector", host.getPlugin());
Host = host;
}
@EventHandler(priority = EventPriority.MONITOR)
public void updateSpeedhack(PlayerMoveEvent event)
{
if (!Host.isEnabled())
return;
Player player = event.getPlayer();
//100% Valid
if (Host.isValid(player, false))
return;
UpdateSpeed(player, event);
}
private void UpdateSpeed(Player player, PlayerMoveEvent event)
{
int count = 0;
if (_speedTicks.containsKey(player))
{
double offset;
if (event.getFrom().getY() > event.getTo().getY())
{
offset = UtilMath.offset2d(event.getFrom(), event.getTo());
}
else
{
offset = UtilMath.offset(event.getFrom(), event.getTo());
}
//Limit
double limit = 0.74;
if (UtilEnt.isGrounded(player))
limit = 0.32;
for (PotionEffect effect : player.getActivePotionEffects())
{
if (effect.getType().equals(PotionEffectType.SPEED))
{
if (UtilEnt.isGrounded(player))
limit += 0.08 * (effect.getAmplifier() + 1);
else
limit += 0.04 * (effect.getAmplifier() + 1);
}
}
//Check
if (offset > limit && !UtilTime.elapsed(_speedTicks.get(player).getValue(), 100))//Counters Lag
{
count = _speedTicks.get(player).getKey() + 1;
}
else
{
count = 0;
}
}
if (count > Host.SpeedHackTicks)
{
Host.addSuspicion(player, "Speed (Fly/Move)");
count -= 2;
}
_speedTicks.put(player, new AbstractMap.SimpleEntry<Integer, Long>(count, System.currentTimeMillis()));
}
@Override
public void Reset(Player player)
{
_speedTicks.remove(player);
}
}

View File

@ -0,0 +1,159 @@
package mineplex.core.communities;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.game.GameDisplay;
public class Community
{
private final int _id;
private String _name;
private String _description;
private Map<UUID, CommunityMemberInfo> _members = new HashMap<>();
private Map<UUID, CommunityJoinRequestInfo> _joinRequests = new HashMap<>();
private ChatColor[] _chatFormat;
private long _chatDelay;
private GameDisplay _favoriteGame;
private PrivacySetting _privacy;
public Community(int id, String name)
{
_id = id;
_name = name;
_description = "No Description Set";
_chatFormat = new ChatColor[] {ChatColor.BLUE, ChatColor.RED, ChatColor.GREEN};
_chatDelay = 1000;
_favoriteGame = GameDisplay.ChampionsCTF;
_privacy = PrivacySetting.RECRUITING;
}
public Integer getId()
{
return _id;
}
public String getName()
{
return _name;
}
public void setName(String name)
{
_name = name;
}
public String getDescription()
{
return _description;
}
public void setDescription(String description)
{
_description = description;
}
public Map<UUID, CommunityMemberInfo> getMembers()
{
return _members;
}
public Map<UUID, CommunityJoinRequestInfo> getJoinRequests()
{
return _joinRequests;
}
public ChatColor[] getChatFormatting()
{
return _chatFormat;
}
public void setChatFormatting(ChatColor[] colors)
{
_chatFormat = colors;
}
public Long getChatDelay()
{
return _chatDelay;
}
public void setChatDelay(Long delay)
{
_chatDelay = delay;
}
public GameDisplay getFavoriteGame()
{
return _favoriteGame;
}
public void setFavoriteGame(GameDisplay game)
{
_favoriteGame = game;
}
public PrivacySetting getPrivacySetting()
{
return _privacy;
}
public void setPrivacySetting(PrivacySetting privacy)
{
_privacy = privacy;
}
public void sendChat(String chat)
{
getMembers().values().stream().filter(info -> info.ReadingChat).forEach(member -> UtilPlayer.message(Bukkit.getPlayer(member.UUID), chat));
}
public void message(String message)
{
getMembers().values().forEach(member -> UtilPlayer.message(Bukkit.getPlayer(member.UUID), message));
}
public void message(String message, CommunityRole minimumRole)
{
getMembers().values().stream().filter(member -> member.Role.ordinal() <= minimumRole.ordinal()).forEach(member -> UtilPlayer.message(Bukkit.getPlayer(member.UUID), message));
}
public static enum PrivacySetting
{
OPEN("Open to Join"),
RECRUITING("Accepting Join Requests"),
PRIVATE("Closed")
;
private String _display;
private PrivacySetting(String display)
{
_display = display;
}
public String getDisplayText()
{
return _display;
}
public static PrivacySetting parsePrivacy(String privacy)
{
for (PrivacySetting setting : PrivacySetting.values())
{
if (setting.toString().equalsIgnoreCase(privacy))
{
return setting;
}
}
return PrivacySetting.RECRUITING;
}
}
}

View File

@ -0,0 +1,21 @@
package mineplex.core.communities;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CommunityBrowserUpdateEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
public CommunityBrowserUpdateEvent() {}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,31 @@
package mineplex.core.communities;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CommunityDisbandEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Community _community;
public CommunityDisbandEvent(Community community)
{
_community = community;
}
public Community getCommunity()
{
return _community;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,47 @@
package mineplex.core.communities;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityJoinRequestInfo
{
public String Name;
public final UUID UUID;
public final int AccountId;
private ItemStack _icon;
public CommunityJoinRequestInfo(String name, UUID uuid, int accountId)
{
Name = name;
UUID = uuid;
AccountId = accountId;
buildIcon();
}
private void buildIcon()
{
ItemBuilder builder = new ItemBuilder(Material.SKULL_ITEM);
builder.setTitle(C.cGreenB + Name);
builder.setLore(C.cRed, C.cYellow + "Left Click " + C.cWhite + "Accept", C.cYellow + "Shift-Right Click " + C.cWhite + "Deny");
builder.setData((short)3);
builder.setPlayerHead(Name);
_icon = builder.build();
}
public void update(String name)
{
Name = name;
buildIcon();
}
public ItemStack getRepresentation()
{
return _icon;
}
}

View File

@ -0,0 +1,31 @@
package mineplex.core.communities;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CommunityJoinRequestsUpdateEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Community _community;
public CommunityJoinRequestsUpdateEvent(Community community)
{
_community = community;
}
public Community getCommunity()
{
return _community;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,709 @@
package mineplex.core.communities;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
import com.google.common.collect.Lists;
import mineplex.core.Managers;
import mineplex.core.MiniDbClientPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.jsonchat.ClickEvent;
import mineplex.core.common.jsonchat.JsonMessage;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.communities.Community.PrivacySetting;
import mineplex.core.communities.commands.CommunityCommand;
import mineplex.core.communities.redis.CommunityChat;
import mineplex.core.communities.redis.CommunityChatHandler;
import mineplex.core.communities.redis.CommunityCloseJoinRequest;
import mineplex.core.communities.redis.CommunityCloseJoinRequestHandler;
import mineplex.core.communities.redis.CommunityCreate;
import mineplex.core.communities.redis.CommunityCreateHandler;
import mineplex.core.communities.redis.CommunityDisband;
import mineplex.core.communities.redis.CommunityDisbandHandler;
import mineplex.core.communities.redis.CommunityInvite;
import mineplex.core.communities.redis.CommunityInviteHandler;
import mineplex.core.communities.redis.CommunityJoinRequest;
import mineplex.core.communities.redis.CommunityJoinRequestHandler;
import mineplex.core.communities.redis.CommunityUnInvite;
import mineplex.core.communities.redis.CommunityUnInviteHandler;
import mineplex.core.communities.redis.CommunityUpdateMemberChatReading;
import mineplex.core.communities.redis.CommunityUpdateMemberChatReadingHandler;
import mineplex.core.communities.redis.CommunityUpdateMemberRole;
import mineplex.core.communities.redis.CommunityUpdateMemberRoleHandler;
import mineplex.core.communities.redis.CommunityUpdateMembership;
import mineplex.core.communities.redis.CommunityUpdateMembershipHandler;
import mineplex.core.communities.redis.CommunityUpdateName;
import mineplex.core.communities.redis.CommunityUpdateNameHandler;
import mineplex.core.communities.redis.CommunityUpdateSetting;
import mineplex.core.communities.redis.CommunityUpdateSettingHandler;
import mineplex.core.communities.storage.CommunityRepository;
import mineplex.core.preferences.Preference;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.recharge.Recharge;
import mineplex.serverdata.Region;
import mineplex.serverdata.commands.ServerCommandManager;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.data.PlayerStatus;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
public class CommunityManager extends MiniDbClientPlugin<CommunityMemberData>
{
public final Pattern ALPHA_NUMERIC_PATTERN = Pattern.compile("[^A-Za-z0-9]");
public final String[] BLOCKED_NAMES = new String[] {"help", "chat", "create", "description", "disband", "invite", "join", "mcs", "rename", "uninvite", "trainee", "mod", "moderator", "srmod", "seniormod", "seniormoderator", "builder", "maplead", "twitch", "youtube", "support", "admin", "administrator", "leader", "dev", "developer", "owner", "party", "mineplex", "mineplexOfficial", "staff", "mineplexstaff", "qualityassurance", "traineemanagement", "modcoordination", "forumninja", "communitymanagement", "event", "socialmedia"};
private final CommunityRepository _repo;
private final Map<Integer, Community> _loadedCommunities;
public final List<Integer> BrowserIds = new LinkedList<>();
public final DataRepository<PlayerStatus> StatusRepository;
private ServerRepository _serverRepo;
private boolean _us;
private boolean _cycling = false;
@SuppressWarnings("deprecation")
public CommunityManager(JavaPlugin plugin, CoreClientManager clientManager)
{
super("Communities", plugin, clientManager);
StatusRepository = new RedisDataRepository<PlayerStatus>(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(),
Region.currentRegion(), PlayerStatus.class, "playerStatus");
_us = plugin.getConfig().getBoolean("serverstatus.us");
Region region = _us ? Region.US : Region.EU;
_serverRepo = ServerManager.getServerRepository(region);
_repo = new CommunityRepository(plugin, StatusRepository, _us);
_loadedCommunities = new ConcurrentHashMap<>();
Bukkit.getScheduler().scheduleAsyncRepeatingTask(plugin, () ->
{
if (_cycling)
{
return;
}
LinkedList<Community> communities = new LinkedList<>();
_loadedCommunities.values().forEach(community -> communities.add(community));
_repo.updateMembersAndJoinRequests(communities);
}, 0L, 20 * 5);
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () ->
{
cycleBrowser();
}, 0L, 20 * 30);
_repo.loadCommunities(_loadedCommunities);
addCommand(new CommunityCommand(this));
ServerCommandManager.getInstance().registerCommandType(CommunityChat.class, new CommunityChatHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityCloseJoinRequest.class, new CommunityCloseJoinRequestHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityCreate.class, new CommunityCreateHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityDisband.class, new CommunityDisbandHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityInvite.class, new CommunityInviteHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityJoinRequest.class, new CommunityJoinRequestHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityUnInvite.class, new CommunityUnInviteHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityUpdateMemberChatReading.class, new CommunityUpdateMemberChatReadingHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityUpdateMemberRole.class, new CommunityUpdateMemberRoleHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityUpdateMembership.class, new CommunityUpdateMembershipHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityUpdateName.class, new CommunityUpdateNameHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityUpdateSetting.class, new CommunityUpdateSettingHandler(this));
}
private void cycleBrowser()
{
if (_cycling)
{
return;
}
_cycling = true;
runAsync(() ->
{
final List<Integer> resultant = Lists.newArrayList();
final List<Integer> ids = new LinkedList<>();
_loadedCommunities.values().stream().filter(c -> c.getMembers().size() >= 5 && c.getPrivacySetting() != PrivacySetting.PRIVATE).forEach(c -> resultant.add(c.getId()));
Random random = new Random();
while (!resultant.isEmpty())
{
ids.add(resultant.remove(random.nextInt(resultant.size())));
}
runSync(() ->
{
BrowserIds.clear();
BrowserIds.addAll(ids);
_cycling = false;
UtilServer.CallEvent(new CommunityBrowserUpdateEvent());
});
});
}
public Community getLoadedCommunity(Integer id)
{
return _loadedCommunities.get(id);
}
public Community getLoadedCommunity(String name)
{
for (Entry<Integer, Community> entry : _loadedCommunities.entrySet())
{
if (entry.getValue().getName().equalsIgnoreCase(name))
{
return entry.getValue();
}
}
return null;
}
public void handleCommunitySettingUpdate(Integer id, String sender, CommunitySetting setting, String newValue)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
setting.parseValueInto(newValue, community);
//community.message(F.main(getName(), F.name(sender) + " has changed settings in " + F.name(community.getName()) + "!"));
UtilServer.CallEvent(new CommunitySettingUpdateEvent(community));
}
public void handleCommunityNameUpdate(Integer id, String sender, String name)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
String oldName = community.getName();
community.setName(name);
community.message(F.main(getName(), F.name(sender) + " has changed the name of " + F.name(oldName) + " to " + F.name(community.getName()) + "!"));
UtilServer.CallEvent(new CommunityNameUpdateEvent(community));
}
public void handleCommunityMembershipRoleUpdate(Integer id, String sender, UUID uuid, CommunityRole role)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
CommunityMemberInfo member = community.getMembers().get(uuid);
member.Role = role;
if (Bukkit.getPlayer(uuid) != null)
{
if (role.ordinal() > CommunityRole.COLEADER.ordinal())
{
UtilPlayer.message(Bukkit.getPlayer(uuid), F.main(getName(), F.name(sender) + " has changed your role to " + F.elem(role.getDisplay()) + " in " + F.name(community.getName()) + "!"));
}
Get(Bukkit.getPlayer(uuid)).setRoleIn(community, role);
}
String name = member.Name;
community.message(F.main(getName(), F.name(sender) + " has changed " + F.name(name + "'s") + " role to " + F.elem(role.getDisplay()) + " in " + F.name(community.getName()) + "!"), CommunityRole.COLEADER);
UtilServer.CallEvent(new CommunityMembershipUpdateEvent(community));
}
public void handleCommunityMembershipUpdate(Integer id, String sender, String playerName, UUID playerUUID, Integer accountId, boolean kick, boolean leave)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
if (kick)
{
community.message(F.main(getName(), F.name(sender) + " has kicked " + F.name(playerName) + " from " + F.name(community.getName()) + "!"));
community.getMembers().remove(playerUUID);
if (Bukkit.getPlayer(playerUUID) != null)
{
Get(Bukkit.getPlayer(playerUUID)).leaveCommunity(community);
}
}
else if (leave)
{
community.message(F.main(getName(), F.name(playerName) + " has left " + F.name(community.getName()) + "!"));
community.getMembers().remove(playerUUID);
if (Bukkit.getPlayer(playerUUID) != null)
{
Get(Bukkit.getPlayer(playerUUID)).leaveCommunity(community);
}
}
else
{
community.getMembers().put(playerUUID, new CommunityMemberInfo(playerName, playerUUID, accountId, CommunityRole.MEMBER, System.currentTimeMillis()));
if (Bukkit.getPlayer(playerUUID) != null)
{
Get(Bukkit.getPlayer(playerUUID)).joinCommunity(community);
Get(Bukkit.getPlayer(playerUUID)).Invites.remove(community.getId());
}
community.message(F.main(getName(), F.name(playerName) + " has joined " + F.name(community.getName()) + "!"));
}
UtilServer.CallEvent(new CommunityMembershipUpdateEvent(community));
if (Bukkit.getPlayer(playerUUID) != null)
{
UtilServer.CallEvent(new CommunityMemberDataUpdateEvent(Bukkit.getPlayer(playerUUID)));
}
}
public void handleCommunityInvite(Integer id, String sender, String targetName, UUID targetUUID)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
if (Bukkit.getPlayer(targetUUID) != null)
{
if (!Get(Bukkit.getPlayer(targetUUID)).Invites.contains(community.getId()))
{
Get(Bukkit.getPlayer(targetUUID)).Invites.add(community.getId());
if (Managers.get(PreferencesManager.class).get(Bukkit.getPlayer(targetUUID)).isActive(Preference.COMMUNITY_INVITES))
{
new JsonMessage(F.main(getName(), "You have been invited to join " + F.elem(community.getName()) + " by " + F.name(sender) + "! Click to join!")).click(ClickEvent.RUN_COMMAND, "/community join " + community.getName()).sendToPlayer(Bukkit.getPlayer(targetUUID));
}
UtilServer.CallEvent(new CommunityMemberDataUpdateEvent(Bukkit.getPlayer(targetUUID)));
}
}
community.message(F.main(getName(), F.name(sender) + " has invited " + F.name(targetName) + " to " + F.name(community.getName()) + "!"), CommunityRole.COLEADER);
}
public void handleCommunityUninvite(Integer id, String sender, String targetName, UUID targetUUID, boolean announce)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
if (Bukkit.getPlayer(targetUUID) != null)
{
Get(Bukkit.getPlayer(targetUUID)).Invites.remove(community.getId());
if (Managers.get(PreferencesManager.class).get(Bukkit.getPlayer(targetUUID)).isActive(Preference.COMMUNITY_INVITES) && announce)
{
UtilPlayer.message(Bukkit.getPlayer(targetUUID), F.main(getName(), "Your invitation to join " + F.elem(community.getName()) + " has been revoked by " + F.name(sender) + "!"));
}
UtilServer.CallEvent(new CommunityMemberDataUpdateEvent(Bukkit.getPlayer(targetUUID)));
}
if (announce)
{
community.message(F.main(getName(), F.name(targetName) + "'s invitation to join " + F.name(community.getName()) + " has been revoked by " + F.name(sender) + "!"), CommunityRole.COLEADER);
}
}
public void handleCommunityJoinRequest(Integer id, String playerName, UUID playerUUID, Integer accountId)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
if (Bukkit.getPlayer(playerUUID) != null)
{
UtilPlayer.message(Bukkit.getPlayer(playerUUID), F.main(getName(), "You have requested to join " + F.elem(community.getName()) + "!"));
}
community.getJoinRequests().put(playerUUID, new CommunityJoinRequestInfo(playerName, playerUUID, accountId));
community.message(F.main(getName(), F.name(playerName) + " has requested to join " + F.name(community.getName()) + "!"), CommunityRole.COLEADER);
UtilServer.CallEvent(new CommunityJoinRequestsUpdateEvent(community));
}
public void handleCommunityCloseJoinRequest(Integer id, String sender, String playerName, UUID playerUUID, Integer accountId, boolean announce)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
community.getJoinRequests().remove(playerUUID);
if (announce)
{
if (Bukkit.getPlayer(playerUUID) != null)
{
UtilPlayer.message(Bukkit.getPlayer(playerUUID), F.main(getName(), "Your request to join " + F.name(community.getName()) + " has been denied by " + F.name(sender) + "!"));
}
community.message(F.main(getName(), F.name(playerName) + "'s request to join " + F.name(community.getName()) + " has been denied by " + F.name(sender) + "!"), CommunityRole.COLEADER);
}
UtilServer.CallEvent(new CommunityJoinRequestsUpdateEvent(community));
}
public void handleCommunityCreation(Integer id, UUID leaderUUID)
{
runAsync(() ->
{
_repo.loadCommunity(id, _loadedCommunities);
runSync(() ->
{
Community community = _loadedCommunities.get(id);
if (Bukkit.getPlayer(leaderUUID) != null)
{
Player leader = Bukkit.getPlayer(leaderUUID);
UtilPlayer.message(leader, F.main(getName(), "You have created a community named " + F.name(community.getName()) + "!"));
Get(leader).joinCommunity(id, CommunityRole.LEADER);
}
});
});
}
public void handleCommunityDisband(Integer id, String senderName)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
community.message(F.main(getName(), F.name(senderName) + " has disbanded community " + F.name(community.getName()) + "!"));
UtilServer.CallEvent(new CommunityDisbandEvent(community));
UtilServer.GetPlayers().stream().filter(player -> Get(player).Invites.contains(community.getId())).forEach(player -> Get(player).Invites.remove(community.getId()));
community.getMembers().keySet().stream().filter(uuid -> Bukkit.getPlayer(uuid) != null).forEach(uuid -> Get(Bukkit.getPlayer(uuid)).leaveCommunity(community));
_loadedCommunities.remove(community.getId());
runSync(() ->
{
if (BrowserIds.remove(community.getId()))
{
UtilServer.CallEvent(new CommunityBrowserUpdateEvent());
}
});
}
public void handleToggleReadingCommunityChat(Integer id, UUID uuid, boolean reading)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
if (community.getMembers().containsKey(uuid))
{
community.getMembers().get(uuid).ReadingChat = reading;
if (reading)
{
UtilPlayer.message(Bukkit.getPlayer(uuid), F.main(getName(), "You are now reading chat from " + F.name(community.getName()) + "!"));
}
else
{
UtilPlayer.message(Bukkit.getPlayer(uuid), F.main(getName(), "You are no longer reading chat from " + F.name(community.getName()) + "!"));
}
}
}
public void handleCommunityChat(Integer id, String senderName, String message)
{
Community community = _loadedCommunities.get(id);
if (community == null)
{
return;
}
community.sendChat(community.getChatFormatting()[0] + C.Bold + community.getName() + " " + community.getChatFormatting()[1] + C.Bold + senderName + " " + community.getChatFormatting()[2] + message);
}
public void handleInvite(Player sender, Community community, String target)
{
CommunityJoinRequestInfo[] jr = community.getJoinRequests().values().stream().filter(data -> data.Name.equalsIgnoreCase(target)).toArray(size -> new CommunityJoinRequestInfo[size]);
if (jr.length == 1)
{
UtilPlayer.message(sender, F.main(getName(), "You have accepted " + F.name(target) + "'s join request to " + F.name(community.getName()) + "!"));
runAsync(() ->
{
_repo.addToCommunity(jr[0].AccountId, community.getId());
_repo.removeJoinRequest(community.getId(), jr[0].AccountId);
});
new CommunityCloseJoinRequest(community.getId(), sender.getName(), jr[0].Name, jr[0].UUID.toString(), jr[0].AccountId, false).publish();
new CommunityUpdateMembership(community.getId(), sender.getName(), jr[0].Name, jr[0].UUID.toString(), jr[0].AccountId, false, false).publish();
return;
}
runAsync(() ->
{
if (_repo.inviteToCommunity(community.getId(), target))
{
if (!community.getMembers().containsKey(sender.getUniqueId()))
{
UtilPlayer.message(sender, F.main(getName(), "You have invited " + F.name(target) + " to join " + F.name(community.getName()) + "!"));
}
new CommunityInvite(community.getId(), sender.getName(), target, Managers.get(CoreClientManager.class).loadUUIDFromDB(target).toString()).publish();
}
else
{
UtilPlayer.message(sender, F.main(getName(), "Either " + F.name(target) + " does not exist or you have already invited them to " + F.name(community.getName()) + "!"));
}
});
}
public void handleUninvite(Player sender, Community community, String target)
{
runAsync(() ->
{
if (_repo.deleteInviteToCommunity(community.getId(), target))
{
if (!community.getMembers().containsKey(sender.getUniqueId()))
{
UtilPlayer.message(sender, F.main(getName(), "You have revoked " + F.name(target) + "'s invitation to join " + F.name(community.getName()) + "!"));
}
new CommunityUnInvite(community.getId(), sender.getName(), target, Managers.get(CoreClientManager.class).loadUUIDFromDB(target).toString(), true).publish();
}
else
{
UtilPlayer.message(sender, F.main(getName(), "Either " + F.name(target) + " does not exist or you have not invited them to " + F.name(community.getName()) + "!"));
}
});
}
public void handleRejectInvite(Player sender, Community community)
{
final String playerName = Managers.get(CoreClientManager.class).Get(sender).getName();
runAsync(() ->
{
_repo.deleteInviteToCommunity(community.getId(), playerName);
});
new CommunityUnInvite(community.getId(), sender.getName(), sender.getName(), sender.getUniqueId().toString(), false).publish();
}
public void handleJoinRequest(Player sender, Community community)
{
final int accountId = Managers.get(CoreClientManager.class).getAccountId(sender);
if (Get(sender).Invites.contains(community.getId()))
{
String playerName = Managers.get(CoreClientManager.class).Get(sender).getName(); //Guarantee real name (important in this instance)
runAsync(() ->
{
_repo.addToCommunity(accountId, community.getId());
_repo.deleteInviteToCommunity(community.getId(), playerName);
});
new CommunityUnInvite(community.getId(), sender.getName(), sender.getName(), sender.getUniqueId().toString(), false).publish();
new CommunityUpdateMembership(community.getId(), sender.getName(), sender.getName(), sender.getUniqueId().toString(), accountId, false, false).publish();
return;
}
runAsync(() ->
{
_repo.addJoinRequest(community.getId(), accountId);
});
new CommunityJoinRequest(community.getId(), sender.getName(), sender.getUniqueId().toString(), accountId).publish();
}
public void handleCloseJoinRequest(Player sender, Community community, CommunityJoinRequestInfo info, boolean announce)
{
runAsync(() ->
{
_repo.removeJoinRequest(community.getId(), info.AccountId);
});
new CommunityCloseJoinRequest(community.getId(), sender.getName(), info.Name, info.UUID.toString(), info.AccountId, announce).publish();
}
public void handleJoin(Player sender, Community community, boolean fromInvite)
{
final int accountId = Managers.get(CoreClientManager.class).getAccountId(sender);
final String playerName = Managers.get(CoreClientManager.class).Get(sender).getName();
runAsync(() ->
{
_repo.addToCommunity(accountId, community.getId());
if (fromInvite)
{
_repo.deleteInviteToCommunity(community.getId(), playerName);
}
});
new CommunityUpdateMembership(community.getId(), sender.getName(), sender.getName(), sender.getUniqueId().toString(), accountId, false, false).publish();
if (fromInvite)
{
new CommunityUnInvite(community.getId(), sender.getName(), sender.getName(), sender.getUniqueId().toString(), false).publish();
}
}
public void handleKick(Player sender, Community community, CommunityMemberInfo info)
{
runAsync(() ->
{
_repo.removeFromCommunity(info.AccountId, community.getId());
});
new CommunityUpdateMembership(community.getId(), sender.getName(), info.Name, info.UUID.toString(), info.AccountId, true, false).publish();
}
public void handleLeave(Player sender, Community community, CommunityMemberInfo info)
{
runAsync(() ->
{
_repo.removeFromCommunity(info.AccountId, community.getId());
});
new CommunityUpdateMembership(community.getId(), sender.getName(), info.Name, info.UUID.toString(), info.AccountId, false, true).publish();
}
public void handleSettingUpdate(Player sender, Community community, CommunitySetting setting, String newValue)
{
runAsync(() ->
{
_repo.updateCommunitySetting(setting, community.getId(), newValue);
});
new CommunityUpdateSetting(community.getId(), sender.getName(), setting.toString(), newValue).publish();
}
public void handleNameUpdate(Player sender, Community community, String newName)
{
runAsync(() ->
{
_repo.updateCommunityName(community.getId(), newName);
});
new CommunityUpdateName(community.getId(), sender.getName(), newName).publish();
}
public void handleRoleUpdate(Player sender, Community community, CommunityMemberInfo info, CommunityRole role)
{
runAsync(() ->
{
_repo.updateCommunityRole(info.AccountId, community.getId(), role);
});
new CommunityUpdateMemberRole(community.getId(), sender.getName(), info.UUID.toString(), role.toString()).publish();
}
public void handleCreate(Player sender, String name)
{
int accountId = Managers.get(CoreClientManager.class).getAccountId(sender);
runAsync(() ->
{
_repo.createCommunity(name, accountId, id ->
{
if (id == -1)
{
sender.sendMessage(F.main(getName(), "Failed to create community " + F.elem(name)));
}
else
{
new CommunityCreate(sender.getUniqueId().toString(), id).publish();
}
});
});
}
public void handleDisband(Player sender, Community community)
{
runAsync(() ->
{
_repo.deleteCommunity(community.getId());
});
new CommunityDisband(sender.getName(), community.getId()).publish();
}
public void handleToggleReadingChat(Player sender, Community community)
{
final int accountId = Managers.get(CoreClientManager.class).getAccountId(sender);
final boolean reading = !community.getMembers().get(sender.getUniqueId()).ReadingChat;
runAsync(() ->
{
_repo.setReadingChat(accountId, community.getId(), reading);
});
new CommunityUpdateMemberChatReading(community.getId(), sender.getUniqueId().toString(), reading).publish();
}
@Override
public String getQuery(int accountId, String uuid, String name)
{
return "SELECT cm.communityId, cm.communityRole, c.region FROM communityMembers AS cm INNER JOIN communities AS c ON c.id=cm.communityId WHERE accountId=" + accountId + ";";
}
@Override
public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
{
CommunityMemberData data = new CommunityMemberData();
while (resultSet.next())
{
Integer communityId = resultSet.getInt("communityId");
CommunityRole role = CommunityRole.parseRole(resultSet.getString("communityRole"));
String region = resultSet.getString("region");
if ((_us && region.equalsIgnoreCase("US")) || (!_us && region.equalsIgnoreCase("EU")))
{
data.joinCommunity(communityId, role);
}
}
Set(uuid, data);
}
@EventHandler
public void loadInvites(PlayerJoinEvent event)
{
final int accountId = Managers.get(CoreClientManager.class).getAccountId(event.getPlayer());
final CommunityMemberData data = Get(event.getPlayer());
runAsync(() ->
{
_repo.loadInvites(accountId, data.Invites);
runSync(() ->
{
if (data.Invites.size() > 0 && Managers.get(PreferencesManager.class).get(event.getPlayer()).isActive(Preference.COMMUNITY_INVITES))
{
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have been invited to join " + F.elem(data.Invites.size()) + " communities!"));
}
});
});
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onChat(AsyncPlayerChatEvent event)
{
if (!event.getMessage().startsWith("!"))
{
return;
}
event.setCancelled(true);
Player sender = event.getPlayer();
if (Get(sender).getCommunityChattingTo() != -1)
{
Community target = _loadedCommunities.get(Get(sender).getCommunityChattingTo());
if (target == null || !target.getMembers().containsKey(event.getPlayer().getUniqueId()))
{
UtilPlayer.message(sender, F.main(getName(), "You are not in that community! Use " + F.elem("/com chat <community>") + " to select a new community to chat to!"));
}
else
{
if (Recharge.Instance.use(sender, "Community Chat to " + target.getId(), target.getChatDelay(), false, false))
{
new CommunityChat(sender.getName(), target.getId(), event.getMessage().substring(1)).publish();
}
else
{
UtilPlayer.message(sender, F.main(getName(), "You cannot chat to " + F.name(target.getName()) + " that quickly!"));
}
}
}
else
{
UtilPlayer.message(sender, F.main(getName(), "You are not chatting to a specific community! Use " + F.elem("/com chat <community>") + " to select a community to chat to."));
}
}
@Override
protected CommunityMemberData addPlayer(UUID uuid)
{
return new CommunityMemberData();
}
}

View File

@ -0,0 +1,84 @@
package mineplex.core.communities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mineplex.core.Managers;
public class CommunityMemberData
{
private final Map<Integer, CommunityRole> _communities = new HashMap<>();
public final List<Integer> Invites = new ArrayList<>();
private int _chattingTo = -1;
public CommunityMemberData()
{
}
public int getTotalCommunities()
{
return _communities.size();
}
public boolean ownsCommunity()
{
return _communities.containsValue(CommunityRole.LEADER);
}
public int getCommunityChattingTo()
{
return _chattingTo;
}
public void setCommunityChattingTo(Community community)
{
_chattingTo = community.getId();
}
public Community[] getCommunities()
{
Community[] communities = new Community[_communities.size()];
int index = 0;
for (Integer comId : _communities.keySet())
{
communities[index] = Managers.get(CommunityManager.class).getLoadedCommunity(comId);
index++;
}
return communities;
}
public boolean isMemberOf(Community community)
{
return _communities.containsKey(community.getId());
}
public CommunityRole getRoleIn(Community community)
{
return _communities.get(community.getId());
}
public void joinCommunity(Integer communityId, CommunityRole role)
{
_communities.put(communityId, role);
}
public void joinCommunity(Community community)
{
joinCommunity(community.getId(), CommunityRole.MEMBER);
}
public void setRoleIn(Community community, CommunityRole role)
{
_communities.replace(community.getId(), role);
}
public void leaveCommunity(Community community)
{
_communities.remove(community.getId());
}
}

View File

@ -0,0 +1,32 @@
package mineplex.core.communities;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CommunityMemberDataUpdateEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Player _player;
public CommunityMemberDataUpdateEvent(Player player)
{
_player = player;
}
public Player getPlayer()
{
return _player;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,99 @@
package mineplex.core.communities;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilTime;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityMemberInfo
{
public String Name;
public final UUID UUID;
public final int AccountId;
public CommunityRole Role;
public boolean OwnsCommunity = false;
public boolean ReadingChat = true;
private ItemStack _memberIcon, _outsiderIcon;
private long _sinceLastLogin;
private boolean _online = false;
private String _currentServer = "";
public CommunityMemberInfo(String name, UUID uuid, int accountId, CommunityRole role, long timeSinceLastLogin)
{
Name = name;
UUID = uuid;
AccountId = accountId;
Role = role;
_sinceLastLogin = timeSinceLastLogin;
buildIcons();
}
private void buildIcons()
{
ItemBuilder builder = new ItemBuilder(Material.SKULL_ITEM).setTitle(C.cGreenB + Name).setLore(C.cRed, C.cYellow + "Role " + C.cWhite + Role.getDisplay());
_outsiderIcon = builder.build();
builder.setTitle(!_online ? C.cRedB + Name : C.cGreenB + Name);
if (_online)
{
builder.addLore(C.cYellow + "Server " + C.cWhite + _currentServer);
}
else
{
builder.addLore(C.cYellow + "Last Seen " + C.cWhite + UtilTime.MakeStr(_sinceLastLogin) + " Ago");
}
if (_online)
{
builder.setData((short)3);
builder.setPlayerHead(Name);
}
_memberIcon = builder.build();
}
public void update(String name, CommunityRole role, long timeSinceLastLogin, boolean online, String currentServer)
{
Name = name;
Role = role;
_sinceLastLogin = timeSinceLastLogin;
_online = online;
_currentServer = currentServer;
buildIcons();
}
public boolean isOnline()
{
return _online;
}
public ItemStack getRepresentation(CommunityRole viewerRole)
{
if (viewerRole == null)
{
return _outsiderIcon;
}
ItemBuilder builder = new ItemBuilder(_memberIcon);
if ((viewerRole == CommunityRole.LEADER && Role != CommunityRole.LEADER) || (viewerRole.ordinal() < Role.ordinal()))
{
builder.addLore(C.cGold);
}
if (viewerRole == CommunityRole.LEADER && Role != CommunityRole.LEADER)
{
builder.addLore(C.cYellow + (Role == CommunityRole.COLEADER ? "Shift-" : "" ) + "Left Click " + C.cWhite + "Promote");
if (Role != CommunityRole.MEMBER)
{
builder.addLore(C.cYellow + "Right Click " + C.cWhite + "Demote");
}
}
if (viewerRole.ordinal() < Role.ordinal())
{
builder.addLore(C.cYellow + "Shift-Right Click " + C.cWhite + "Kick");
}
return builder.build();
}
}

View File

@ -0,0 +1,31 @@
package mineplex.core.communities;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CommunityMembershipUpdateEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Community _community;
public CommunityMembershipUpdateEvent(Community community)
{
_community = community;
}
public Community getCommunity()
{
return _community;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,31 @@
package mineplex.core.communities;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CommunityNameUpdateEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Community _community;
public CommunityNameUpdateEvent(Community community)
{
_community = community;
}
public Community getCommunity()
{
return _community;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,34 @@
package mineplex.core.communities;
public enum CommunityRole
{
LEADER("Leader"),
COLEADER("Co-Leader"),
MEMBER("Member")
;
private String _displayName;
private CommunityRole(String displayName)
{
_displayName = displayName;
}
public String getDisplay()
{
return _displayName;
}
public static CommunityRole parseRole(String role)
{
for (CommunityRole test : CommunityRole.values())
{
if (test.toString().equalsIgnoreCase(role))
{
return test;
}
}
return CommunityRole.MEMBER;
}
}

View File

@ -0,0 +1,124 @@
package mineplex.core.communities;
import org.bukkit.ChatColor;
import mineplex.core.common.Pair;
import mineplex.core.common.util.Callback;
import mineplex.core.communities.Community.PrivacySetting;
import mineplex.core.game.GameDisplay;
public enum CommunitySetting
{
CHAT_NAME_COLOR(1, pair ->
{
String value = pair.getLeft();
Community community = pair.getRight();
ChatColor color = ChatColor.valueOf(value);
if (color == null || !color.isColor())
{
return;
}
community.setChatFormatting(new ChatColor[] {color, community.getChatFormatting()[1], community.getChatFormatting()[2]});
}
),
CHAT_PLAYER_COLOR(2, pair ->
{
String value = pair.getLeft();
Community community = pair.getRight();
ChatColor color = ChatColor.valueOf(value);
if (color == null || !color.isColor())
{
return;
}
community.setChatFormatting(new ChatColor[] {community.getChatFormatting()[0], color, community.getChatFormatting()[2]});
}
),
CHAT_MESSAGE_COLOR(3, pair ->
{
String value = pair.getLeft();
Community community = pair.getRight();
ChatColor color = ChatColor.valueOf(value);
if (color == null || !color.isColor())
{
return;
}
community.setChatFormatting(new ChatColor[] {community.getChatFormatting()[0], community.getChatFormatting()[1], color});
}
),
CHAT_DELAY(4, pair ->
{
String value = pair.getLeft();
Community community = pair.getRight();
try
{
Long delay = Long.parseLong(value);
community.setChatDelay(delay);
}
catch (Exception e)
{
return;
}
}
),
FAVORITE_GAME(5, pair ->
{
String value = pair.getLeft();
Community community = pair.getRight();
GameDisplay display = GameDisplay.matchName(value);
community.setFavoriteGame(display);
}
),
PRIVACY(6, pair ->
{
String value = pair.getLeft();
Community community = pair.getRight();
PrivacySetting setting = PrivacySetting.parsePrivacy(value);
community.setPrivacySetting(setting);
}
),
DESCRIPTION(7, pair ->
{
String value = pair.getLeft();
Community community = pair.getRight();
community.setDescription(value);
});
private int _id;
private Callback<Pair<String, Community>> _parser;
private CommunitySetting(int id, Callback<Pair<String, Community>> parseValue)
{
_id = id;
_parser = parseValue;
}
public int getId()
{
return _id;
}
public void parseValueInto(String value, Community community)
{
_parser.run(Pair.create(value, community));
}
public static CommunitySetting getSetting(Integer id)
{
for (CommunitySetting setting : CommunitySetting.values())
{
if (setting.getId() == id)
{
return setting;
}
}
return null;
}
}

View File

@ -0,0 +1,31 @@
package mineplex.core.communities;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CommunitySettingUpdateEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Community _community;
public CommunitySettingUpdateEvent(Community community)
{
_community = community;
}
public Community getCommunity()
{
return _community;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,42 @@
package mineplex.core.communities.commands;
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.communities.Community;
import mineplex.core.communities.CommunityManager;
public class CommunityChatCommand extends CommandBase<CommunityManager>
{
public CommunityChatCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "chat");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.help("/com chat <community>", "Selects which community you chat to", Rank.ALL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (!c.getMembers().containsKey(caller.getUniqueId()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not in " + F.name(c.getName()) + "!"));
return;
}
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are now chatting to " + F.name(c.getName()) + "! Use " + F.elem("!") + " before your message to use community chat!"));
Plugin.Get(caller).setCommunityChattingTo(c);
}
}

View File

@ -0,0 +1,68 @@
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.command.MultiCommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.communities.Community;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.gui.community.CommunityMembersPage;
import mineplex.core.communities.gui.overview.CommunityOverviewPage;
public class CommunityCommand extends MultiCommandBase<CommunityManager>
{
public CommunityCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "community", "communities", "com");
AddCommand(new CommunityChatCommand(plugin));
AddCommand(new CommunityCreateCommand(plugin));
AddCommand(new CommunityDescriptionCommand(plugin));
AddCommand(new CommunityDisbandCommand(plugin));
AddCommand(new CommunityInviteCommand(plugin));
AddCommand(new CommunityJoinCommand(plugin));
AddCommand(new CommunityMCSCommand(plugin));
//AddCommand(new CommunityMenuCommand(plugin));
AddCommand(new CommunityRenameCommand(plugin));
AddCommand(new CommunityUnInviteCommand(plugin));
}
@Override
protected void Help(Player caller, String[] args)
{
if (args.length > 0)
{
if (args[0].equalsIgnoreCase("help"))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "Community Commands:"));
UtilPlayer.message(caller, F.help("/com <community>", "Opens a community's menu", Rank.ALL, ChatColor.DARK_AQUA));
//UtilPlayer.message(caller, F.help("/com menu", "Opens your community menu", Rank.ALL));
UtilPlayer.message(caller, F.help("/com invite <player> <community>", "Invites a player to a community you manage", Rank.ALL, ChatColor.DARK_AQUA));
UtilPlayer.message(caller, F.help("/com uninvite <player> <community>", "Revokes a player's invitation to a community you manage", Rank.ALL, ChatColor.DARK_AQUA));
UtilPlayer.message(caller, F.help("/com join <community>", "Joins a community that is open or you have been invited to", Rank.ALL, ChatColor.DARK_AQUA));
UtilPlayer.message(caller, F.help("/com chat <community>", "Selects which community you chat to", Rank.ALL, ChatColor.DARK_AQUA));
UtilPlayer.message(caller, F.help("/com create <name>", "Creates a new community", Rank.ETERNAL, ChatColor.DARK_AQUA));
UtilPlayer.message(caller, F.help("/com rename <community> <name>", "Changes the name of a community you own", Rank.ETERNAL, ChatColor.DARK_AQUA));
UtilPlayer.message(caller, F.help("/com mcs <community>", "Opens the Mineplex Community Server of a community you manage", Rank.ALL, ChatColor.DARK_AQUA));
UtilPlayer.message(caller, F.help("/com description <community> <description>", "Sets the description of a community you manage", Rank.ALL, ChatColor.DARK_AQUA));
UtilPlayer.message(caller, F.help("/com disband <community>", "Disbands a community you own", Rank.ETERNAL, ChatColor.DARK_AQUA));
return;
}
Community community = Plugin.getLoadedCommunity(args[0]);
if (community == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "Could not find community " + F.name(args[0]) + "!"));
}
else
{
new CommunityMembersPage(caller, community);
}
return;
}
new CommunityOverviewPage(caller);
}
}

View File

@ -0,0 +1,65 @@
package mineplex.core.communities.commands;
import java.util.Arrays;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.chat.Chat;
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.communities.Community;
import mineplex.core.communities.CommunityManager;
public class CommunityCreateCommand extends CommandBase<CommunityManager>
{
public CommunityCreateCommand(CommunityManager plugin)
{
super(plugin, Rank.ETERNAL, "create");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.help("/com create <name>", "Creates a new community", Rank.ETERNAL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
if (c != null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "A community already exists with that name!"));
return;
}
if (Plugin.Get(caller).ownsCommunity())
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You already own a community!"));
return;
}
if (args[0].length() > 15 || Plugin.ALPHA_NUMERIC_PATTERN.matcher(args[0]).find())
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "A community name cannot be longer than 15 characters and must be alphanumeric!"));
return;
}
if (Arrays.asList(Plugin.BLOCKED_NAMES).contains(args[0].toLowerCase()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That name is not allowed!"));
return;
}
Plugin.runAsync(() ->
{
if (Managers.get(Chat.class).getFilteredMessage(caller, args[0]).contains("*"))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That name is not allowed!"));
}
else
{
Plugin.handleCreate(caller, args[0]);
}
});
}
}

View File

@ -0,0 +1,77 @@
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
import mineplex.core.chat.Chat;
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.communities.Community;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityRole;
import mineplex.core.communities.CommunitySetting;
public class CommunityDescriptionCommand extends CommandBase<CommunityManager>
{
public CommunityDescriptionCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "description");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 2)
{
UtilPlayer.message(caller, F.help("/com description <community> <description>", "Sets the description of a community you manage", Rank.ALL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
String desc = args[1];
for (int i = 2; i < args.length; i++)
{
desc += (" " + args[i]);
}
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().getOrDefault(caller.getUniqueId(), new CommunityMemberInfo(caller.getName(), caller.getUniqueId(), -1, CommunityRole.MEMBER, -1L)).Role.ordinal() > CommunityRole.COLEADER.ordinal())
{
if (!Managers.get(CoreClientManager.class).Get(caller).GetRank().has(Rank.ADMIN))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not a co-leader of " + F.name(c.getName()) + "!"));
return;
}
}
if (desc.length() > 30)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "A community description cannot be longer than 30 characters!"));
return;
}
if (Plugin.ALPHA_NUMERIC_PATTERN.matcher(desc.replace(" ", "").replace("!", "").replace("?", "").replace(".", "").replace("'", "").replace("\"", "")).find())
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "A community description must be alphanumeric!"));
return;
}
final String description = desc;
Plugin.runAsync(() ->
{
if (Managers.get(Chat.class).getFilteredMessage(caller, description).contains("*"))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That description is not allowed!"));
}
else
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You have changed the description of " + F.name(c.getName()) + " to " + F.elem(description) + "!"));
Plugin.handleSettingUpdate(caller, c, CommunitySetting.DESCRIPTION, description);
}
});
}
}

View File

@ -0,0 +1,52 @@
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
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.communities.Community;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityRole;
public class CommunityDisbandCommand extends CommandBase<CommunityManager>
{
public CommunityDisbandCommand(CommunityManager plugin)
{
super(plugin, Rank.ETERNAL, "disband");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.help("/com disband <community>", "Disbands a community you own", Rank.ETERNAL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().getOrDefault(caller.getUniqueId(), new CommunityMemberInfo(caller.getName(), caller.getUniqueId(), -1, CommunityRole.MEMBER, -1L)).Role != CommunityRole.LEADER)
{
if (!Managers.get(CoreClientManager.class).Get(caller).GetRank().has(Rank.ADMIN))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not the leader of " + F.name(c.getName()) + "!"));
return;
}
}
if (!c.getMembers().containsKey(caller.getUniqueId()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You have disbanded community " + F.name(c.getName()) + "!"));
}
Plugin.handleDisband(caller, c);
}
}

View File

@ -0,0 +1,57 @@
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
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.communities.Community;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityRole;
public class CommunityInviteCommand extends CommandBase<CommunityManager>
{
public CommunityInviteCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "invite");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 2)
{
UtilPlayer.message(caller, F.help("/com invite <player> <community>", "Invites a player to a community you manage", Rank.ALL, ChatColor.AQUA));
return;
}
String player = args[0];
Community c = Plugin.getLoadedCommunity(args[1]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().getOrDefault(caller.getUniqueId(), new CommunityMemberInfo(caller.getName(), caller.getUniqueId(), -1, CommunityRole.MEMBER, -1L)).Role.ordinal() > CommunityRole.COLEADER.ordinal())
{
if (!Managers.get(CoreClientManager.class).Get(caller).GetRank().has(Rank.ADMIN))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not a co-leader of " + F.name(c.getName()) + "!"));
return;
}
}
for (CommunityMemberInfo info : c.getMembers().values())
{
if (info.Name.equalsIgnoreCase(player))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), F.name(player) + " is already a member of " + F.name(c.getName()) + "!"));
return;
}
}
Plugin.handleInvite(caller, c, player);
}
}

View File

@ -0,0 +1,47 @@
package mineplex.core.communities.commands;
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.communities.Community;
import mineplex.core.communities.Community.PrivacySetting;
import mineplex.core.communities.CommunityManager;
public class CommunityJoinCommand extends CommandBase<CommunityManager>
{
public CommunityJoinCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "join");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.help("/com join <community>", "Joins a community that is open or you have been invited to", Rank.ALL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().containsKey(caller.getUniqueId()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are already in " + F.name(c.getName()) + "!"));
return;
}
if (c.getPrivacySetting() != PrivacySetting.OPEN && !Plugin.Get(caller).Invites.contains(c.getId()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are have not been invited to " + F.name(c.getName()) + "!"));
return;
}
Plugin.handleJoin(caller, c, Plugin.Get(caller).Invites.contains(c.getId()));
}
}

View File

@ -0,0 +1,50 @@
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
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.communities.Community;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityRole;
import mineplex.core.personalServer.PersonalServerManager;
public class CommunityMCSCommand extends CommandBase<CommunityManager>
{
public CommunityMCSCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "mcs");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.help("/com mcs <community>", "Opens the Mineplex Community Server of a community you manage", Rank.ALL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().getOrDefault(caller.getUniqueId(), new CommunityMemberInfo(caller.getName(), caller.getUniqueId(), -1, CommunityRole.MEMBER, -1L)).Role.ordinal() > CommunityRole.COLEADER.ordinal())
{
if (!Managers.get(CoreClientManager.class).Get(caller).GetRank().has(Rank.ADMIN))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not a co-leader of " + F.name(c.getName()) + "!"));
return;
}
}
Managers.get(PersonalServerManager.class).hostCommunityServer(caller, c);
}
}

View File

@ -0,0 +1,22 @@
package mineplex.core.communities.commands;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.gui.overview.CommunityOverviewPage;
public class CommunityMenuCommand extends CommandBase<CommunityManager>
{
public CommunityMenuCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "menu");
}
@Override
public void Execute(Player caller, String[] args)
{
new CommunityOverviewPage(caller);
}
}

View File

@ -0,0 +1,81 @@
package mineplex.core.communities.commands;
import java.util.Arrays;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
import mineplex.core.chat.Chat;
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.communities.Community;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityRole;
public class CommunityRenameCommand extends CommandBase<CommunityManager>
{
public CommunityRenameCommand(CommunityManager plugin)
{
super(plugin, Rank.ETERNAL, "rename");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 2)
{
UtilPlayer.message(caller, F.help("/com rename <community> <name>", "Changes the name of a community you own", Rank.ETERNAL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
String newName = args[1];
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().getOrDefault(caller.getUniqueId(), new CommunityMemberInfo(caller.getName(), caller.getUniqueId(), -1, CommunityRole.MEMBER, -1L)).Role != CommunityRole.LEADER)
{
if (!Managers.get(CoreClientManager.class).Get(caller).GetRank().has(Rank.ADMIN))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not the leader of " + F.name(c.getName()) + "!"));
return;
}
}
if (Plugin.getLoadedCommunity(newName) != null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "A community already exists with that name!"));
return;
}
if (newName.length() > 15 || Plugin.ALPHA_NUMERIC_PATTERN.matcher(newName).find())
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "A community name cannot be longer than 15 characters and must be alphanumeric!"));
return;
}
if (Arrays.asList(Plugin.BLOCKED_NAMES).contains(newName.toLowerCase()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That name is not allowed!"));
return;
}
Plugin.runAsync(() ->
{
if (Managers.get(Chat.class).getFilteredMessage(caller, newName).contains("*"))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That name is not allowed!"));
}
else
{
if (!c.getMembers().containsKey(caller.getUniqueId()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You have changed the name of " + F.name(c.getName()) + " to " + F.name(newName) + "!"));
}
Plugin.handleNameUpdate(caller, c, newName);
}
});
}
}

View File

@ -0,0 +1,49 @@
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
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.communities.Community;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityRole;
public class CommunityUnInviteCommand extends CommandBase<CommunityManager>
{
public CommunityUnInviteCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "uninvite");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 2)
{
UtilPlayer.message(caller, F.help("/com uninvite <player> <community>", "Revokes a player's invitation to a community you manage", Rank.ALL, ChatColor.AQUA));
return;
}
String player = args[0];
Community c = Plugin.getLoadedCommunity(args[1]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().getOrDefault(caller.getUniqueId(), new CommunityMemberInfo(caller.getName(), caller.getUniqueId(), -1, CommunityRole.MEMBER, -1L)).Role.ordinal() > CommunityRole.COLEADER.ordinal())
{
if (!Managers.get(CoreClientManager.class).Get(caller).GetRank().has(Rank.ADMIN))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not a co-leader of " + F.name(c.getName()) + "!"));
return;
}
}
Plugin.handleUninvite(caller, c, player);
}
}

View File

@ -0,0 +1,27 @@
package mineplex.core.communities.gui;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.Callback;
public class ActionButton extends CommunitiesGUIButton
{
private Callback<ClickType> _onClick;
public ActionButton(ItemStack icon, Callback<ClickType> onClick)
{
super(icon);
_onClick = onClick;
}
@Override
public void update() {}
@Override
public void handleClick(ClickType type)
{
_onClick.run(type);
}
}

View File

@ -0,0 +1,26 @@
package mineplex.core.communities.gui;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.communities.CommunityManager;
public abstract class CommunitiesGUIButton
{
public ItemStack Button = null;
public CommunitiesGUIButton(ItemStack button)
{
Button = button;
}
public static CommunityManager getCommunityManager()
{
return Managers.get(CommunityManager.class);
}
public abstract void update();
public abstract void handleClick(ClickType type);
}

View File

@ -0,0 +1,107 @@
package mineplex.core.communities.gui;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import mineplex.core.Managers;
import mineplex.core.common.util.UtilServer;
import mineplex.core.communities.CommunityManager;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
public abstract class CommunitiesGUIPage implements Listener
{
protected Player Viewer;
protected Inventory Inv;
protected Map<Integer, CommunitiesGUIButton> Buttons = new HashMap<>();
public CommunitiesGUIPage(String name, int rows, Player viewer)
{
Viewer = viewer;
Inv = Bukkit.createInventory(viewer, 9 * rows, name);
}
private void disable()
{
HandlerList.unregisterAll(this);
}
public static CommunityManager getCommunityManager()
{
return Managers.get(CommunityManager.class);
}
public void open()
{
Viewer.openInventory(Inv);
UtilServer.RegisterEvents(this);
}
public void updateButtons(boolean callUpdate)
{
Inv.clear();
Buttons.entrySet().stream().forEach(entry ->
{
if (callUpdate)
{
entry.getValue().update();
}
Inv.setItem(entry.getKey(), entry.getValue().Button);
});
Viewer.updateInventory();
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() == UpdateType.TICK)
{
if (Viewer.getOpenInventory() == null || Viewer.getOpenInventory().getTopInventory() == null || !Viewer.getOpenInventory().getTopInventory().getTitle().equals(Inv.getTitle()))
{
disable();
return;
}
}
if (event.getType() == UpdateType.SEC_05)
{
Buttons.entrySet().forEach(entry ->
{
entry.getValue().update();
Inv.setItem(entry.getKey(), entry.getValue().Button);
});
}
}
@EventHandler
public void handleClick(InventoryClickEvent event)
{
if (event.getClickedInventory() == null || !event.getClickedInventory().getTitle().equals(Inv.getTitle()))
{
return;
}
if (!Viewer.getName().equals(event.getWhoClicked().getName()))
{
return;
}
event.setCancelled(true);
if (!Recharge.Instance.use(Viewer, "Communities Button Click", 500, false, false))
{
return;
}
Integer slot = event.getSlot();
if (!Buttons.containsKey(slot))
{
return;
}
Buttons.get(slot).handleClick(event.getClick());
}
}

View File

@ -0,0 +1,41 @@
package mineplex.core.communities.gui.browser;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilText;
import mineplex.core.communities.Community;
import mineplex.core.communities.gui.CommunitiesGUIButton;
import mineplex.core.communities.gui.community.CommunityMembersPage;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityBrowserButton extends CommunitiesGUIButton
{
private Player _viewer;
private Community _community;
@SuppressWarnings("deprecation")
public CommunityBrowserButton(Player viewer, Community community)
{
super(new ItemBuilder(new ItemStack(community.getFavoriteGame().getMaterial(), 1, community.getFavoriteGame().getMaterialData(), null)).setTitle(C.cGreenB + community.getName()).addLore(UtilText.splitLinesToArray(new String[] {C.cRed, C.cYellow + "Members " + C.cWhite + community.getMembers().size(), C.cYellow + "Favorite Game " + C.cWhite + community.getFavoriteGame().getName(), C.cYellow + "Privacy " + C.cWhite + community.getPrivacySetting().getDisplayText(), C.cYellow + "Description " + C.cWhite + community.getDescription(), C.cBlue, C.cGreen + "Click to view community"}, LineFormat.LORE)).build());
_viewer = viewer;
_community = community;
}
@SuppressWarnings("deprecation")
@Override
public void update()
{
Button = new ItemBuilder(new ItemStack(_community.getFavoriteGame().getMaterial(), 1, _community.getFavoriteGame().getMaterialData(), null)).setTitle(C.cGreenB + _community.getName()).addLore(UtilText.splitLinesToArray(new String[] {C.cRed, C.cYellow + "Members " + C.cWhite + _community.getMembers().size(), C.cYellow + "Favorite Game " + C.cWhite + _community.getFavoriteGame().getName(), C.cYellow + "Privacy " + C.cWhite + _community.getPrivacySetting().getDisplayText(), C.cYellow + "Description " + C.cWhite + _community.getDescription(), C.cBlue, C.cGreen + "Click to view community"}, LineFormat.LORE)).build();
}
@Override
public void handleClick(ClickType type)
{
new CommunityMembersPage(_viewer, _community).open();
}
}

View File

@ -0,0 +1,124 @@
package mineplex.core.communities.gui.browser;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.common.util.C;
import mineplex.core.communities.CommunityBrowserUpdateEvent;
import mineplex.core.communities.CommunityDisbandEvent;
import mineplex.core.communities.gui.ActionButton;
import mineplex.core.communities.gui.CommunitiesGUIPage;
import mineplex.core.communities.gui.overview.CommunityInvitesPage;
import mineplex.core.communities.gui.overview.CommunityOverviewPage;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityBrowserPage extends CommunitiesGUIPage
{
private static final int COMMUNITIES_PER_PAGE = 27;
private int _page = 1;
private List<Integer> _displaying = new ArrayList<>();
//protected PrivacySetting PrivacyFilter = null;
//protected GameDisplay GameFilter = null;
public CommunityBrowserPage(Player viewer)
{
super("Community Browser", 6, viewer);
setup(1, true);
open();
}
private void setup(int page, boolean initial)
{
if (initial)
{
Buttons.clear();
Inv.clear();
}
{
//1
ActionButton communitiesButton = new ActionButton(new ItemBuilder(Material.EMERALD).setTitle(C.cGreenB + "Your Communities").build(), clickType ->
{
new CommunityOverviewPage(Viewer).open();
});
Buttons.put(1, communitiesButton);
Inv.setItem(1, communitiesButton.Button);
//4
ActionButton browserButton = new ActionButton(new ItemBuilder(Material.COMPASS).setTitle(C.cGreenB + "Browse Communities").build(), clickType -> {});
Buttons.put(4, browserButton);
Inv.setItem(4, browserButton.Button);
//7
ActionButton invitesButton = new ActionButton(new ItemBuilder(Material.PAPER).setTitle(C.cGreenB + "Community Invites").build(), clickType ->
{
new CommunityInvitesPage(Viewer);
});
Buttons.put(7, invitesButton);
Inv.setItem(7, invitesButton.Button);
}
{
ActionButton back = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Previous Page").build(), clickType ->
{
if (_page == 1)
{
return;
}
setup(_page - 1, false);
});
ActionButton next = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Next Page").build(), clickType ->
{
setup(_page + 1, false);
});
Buttons.put(45, back);
Inv.setItem(45, back.Button);
Buttons.put(53, next);
Inv.setItem(53, next.Button);
}
int slot = 18;
boolean cleared = false;
_displaying.clear();
for (int i = (page - 1) * COMMUNITIES_PER_PAGE; i < (page - 1) * COMMUNITIES_PER_PAGE + COMMUNITIES_PER_PAGE && i < getCommunityManager().BrowserIds.size(); i++)
{
if (!cleared && !initial)
{
cleared = true;
_page = page;
for (int clear = 18; clear < 45; clear++)
{
Buttons.remove(clear);
Inv.setItem(clear, null);
}
}
CommunityBrowserButton button = new CommunityBrowserButton(Viewer, getCommunityManager().getLoadedCommunity(getCommunityManager().BrowserIds.get(i)));
_displaying.add(getCommunityManager().BrowserIds.get(i));
Buttons.put(slot, button);
Inv.setItem(slot, button.Button);
slot++;
}
Viewer.updateInventory();
}
@EventHandler
public void onBrowserUpdate(CommunityBrowserUpdateEvent event)
{
setup(1, true);
}
@EventHandler
public void onCommunityDisband(CommunityDisbandEvent event)
{
if (_displaying.contains(event.getCommunity().getId()))
{
setup(1, true);
}
}
}

View File

@ -0,0 +1,99 @@
package mineplex.core.communities.gui.community;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilText;
import mineplex.core.communities.Community;
import mineplex.core.communities.Community.PrivacySetting;
import mineplex.core.communities.CommunityRole;
import mineplex.core.communities.gui.CommunitiesGUIButton;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityButton extends CommunitiesGUIButton
{
private Player _viewer;
private Community _community;
public CommunityButton(Player viewer, Community community)
{
super(getDisplay(community, viewer));
_viewer = viewer;
_community = community;
}
private static ItemStack getDisplay(Community community, Player viewer)
{
ItemStack item = new ItemBuilder(Material.REDSTONE_BLOCK).setTitle(C.cGreenB + community.getName()).addLore(UtilText.splitLinesToArray(new String[] {C.cGreen, C.cYellow + "Members " + C.cWhite + community.getMembers().size(), C.cYellow + "Description " + C.cWhite + community.getDescription(), C.cRed, C.cYellow + "Shift-Left Click " + C.cWhite + "Request To Join"}, LineFormat.LORE)).build();
if (community.getMembers().containsKey(viewer.getUniqueId()))
{
ItemBuilder builder = new ItemBuilder(Material.EMERALD_BLOCK).setTitle(C.cGreenB + community.getName()).addLore(UtilText.splitLinesToArray(new String[] {C.cGreen, C.cYellow + "Members " + C.cWhite + community.getMembers().size(), C.cYellow + "Description " + C.cWhite + community.getDescription(), C.cRed, C.cYellow + "Shift-Left Click " + C.cWhite + "Leave Community"}, LineFormat.LORE));
if (community.getMembers().get(viewer.getUniqueId()).Role == CommunityRole.LEADER)
{
builder.addLore(C.cBlue);
builder.addLore(UtilText.splitLineToArray(C.cGray + "Use " + C.cYellow + "/com disband " + community.getName() + C.cGray + " to disband!", LineFormat.LORE));
}
item = builder.build();
}
else if (community.getJoinRequests().containsKey(viewer.getUniqueId()))
{
item = new ItemBuilder(Material.REDSTONE_BLOCK).setTitle(C.cGold + community.getName()).addLore(UtilText.splitLinesToArray(new String[] {C.cGreen, C.cYellow + "Members " + C.cWhite + community.getMembers().size(), C.cYellow + "Description " + C.cWhite + community.getDescription(), C.cRed, C.cYellow + "Shift-Left Click " + C.cWhite + "Cancel Join Request"}, LineFormat.LORE)).build();
}
else if (getCommunityManager().Get(viewer).Invites.contains(community.getId()) || community.getPrivacySetting() == PrivacySetting.OPEN)
{
item = new ItemBuilder(Material.REDSTONE_BLOCK).setTitle(C.cGold + community.getName()).addLore(UtilText.splitLinesToArray(new String[] {C.cGreen, C.cYellow + "Members " + C.cWhite + community.getMembers().size(), C.cYellow + "Description " + C.cWhite + community.getDescription(), C.cRed, C.cYellow + "Shift-Left Click " + C.cWhite + "Join Community"}, LineFormat.LORE)).build();
}
else if (community.getPrivacySetting() == PrivacySetting.PRIVATE)
{
item = new ItemBuilder(Material.REDSTONE_BLOCK).setTitle(C.cGreenB + community.getName()).addLore(UtilText.splitLinesToArray(new String[] {C.cGreen, C.cYellow + "Members " + C.cWhite + community.getMembers().size(), C.cYellow + "Description " + C.cWhite + community.getDescription(), C.cRed, C.cRed + "Closed"}, LineFormat.LORE)).build();
}
return item;
}
@Override
public void update()
{
Button = getDisplay(_community, _viewer);
}
@Override
public void handleClick(ClickType type)
{
if (type == ClickType.SHIFT_LEFT)
{
if (_community.getMembers().containsKey(_viewer.getUniqueId()))
{
if (_community.getMembers().get(_viewer.getUniqueId()).Role == CommunityRole.LEADER)
{
UtilPlayer.message(_viewer, F.main(getCommunityManager().getName(), "You cannot leave " + F.name(_community.getName()) + " without passing on leadership first! If you want to disband your community, type " + F.elem("/com disband " + _community.getName()) + "!"));
return;
}
getCommunityManager().handleLeave(_viewer, _community, _community.getMembers().get(_viewer.getUniqueId()));
}
else if (_community.getJoinRequests().containsKey(_viewer.getUniqueId()))
{
getCommunityManager().handleCloseJoinRequest(_viewer, _community, _community.getJoinRequests().get(_viewer.getUniqueId()), false);
}
else if (getCommunityManager().Get(_viewer).Invites.contains(_community.getId()) || _community.getPrivacySetting() == PrivacySetting.OPEN)
{
getCommunityManager().handleJoin(_viewer, _community, getCommunityManager().Get(_viewer).Invites.contains(_community.getId()));
}
else
{
if (_community.getPrivacySetting() != PrivacySetting.PRIVATE)
{
getCommunityManager().handleJoinRequest(_viewer, _community);
}
}
}
}
}

View File

@ -0,0 +1,47 @@
package mineplex.core.communities.gui.community;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.communities.Community;
import mineplex.core.communities.gui.CommunitiesGUIButton;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityChatReadingButton extends CommunitiesGUIButton
{
private Player _viewer;
private Community _community;
public CommunityChatReadingButton(Player viewer, Community community)
{
super(getDisplay(community, viewer));
_viewer = viewer;
_community = community;
}
private static ItemStack getDisplay(Community community, Player viewer)
{
ItemStack item = new ItemBuilder(Material.BOOK_AND_QUILL).setTitle(C.cGreenB + "Toggle Chat Visibility").build();
return item;
}
@Override
public void update()
{
Button = getDisplay(_community, _viewer);
}
@Override
public void handleClick(ClickType type)
{
if (_community.getMembers().containsKey(_viewer.getUniqueId()))
{
getCommunityManager().handleToggleReadingChat(_viewer, _community);
}
}
}

View File

@ -0,0 +1,50 @@
package mineplex.core.communities.gui.community;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.communities.Community;
import mineplex.core.communities.CommunityJoinRequestInfo;
import mineplex.core.communities.CommunityRole;
import mineplex.core.communities.gui.CommunitiesGUIButton;
public class CommunityJoinRequestButton extends CommunitiesGUIButton
{
private Player _viewer;
private Community _community;
private CommunityJoinRequestInfo _info;
public CommunityJoinRequestButton(Player viewer, Community community, CommunityJoinRequestInfo info)
{
super(info.getRepresentation());
_viewer = viewer;
_community = community;
_info = info;
}
@Override
public void update()
{
Button = _info.getRepresentation();
}
@Override
public void handleClick(ClickType type)
{
if (type == ClickType.LEFT)
{
if (getCommunityManager().Get(_viewer).getRoleIn(_community) != null && getCommunityManager().Get(_viewer).getRoleIn(_community).ordinal() <= CommunityRole.COLEADER.ordinal())
{
getCommunityManager().handleInvite(_viewer, _community, _info.Name);
}
}
if (type == ClickType.SHIFT_RIGHT)
{
if (getCommunityManager().Get(_viewer).getRoleIn(_community) != null && getCommunityManager().Get(_viewer).getRoleIn(_community).ordinal() <= CommunityRole.COLEADER.ordinal())
{
getCommunityManager().handleCloseJoinRequest(_viewer, _community, _info, true);
}
}
}
}

View File

@ -0,0 +1,184 @@
package mineplex.core.communities.gui.community;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.common.util.C;
import mineplex.core.communities.Community;
import mineplex.core.communities.CommunityDisbandEvent;
import mineplex.core.communities.CommunityJoinRequestInfo;
import mineplex.core.communities.CommunityJoinRequestsUpdateEvent;
import mineplex.core.communities.CommunityMemberDataUpdateEvent;
import mineplex.core.communities.CommunityMembershipUpdateEvent;
import mineplex.core.communities.CommunityRole;
import mineplex.core.communities.gui.ActionButton;
import mineplex.core.communities.gui.CommunitiesGUIPage;
import mineplex.core.communities.gui.overview.CommunityOverviewPage;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityJoinRequestsPage extends CommunitiesGUIPage
{
private static final int REQUESTS_PER_PAGE = 27;
private Community _community;
private int _page = 1;
public CommunityJoinRequestsPage(Player viewer, Community community)
{
super(community.getName() + C.cBlack, 6, viewer);
_community = community;
setup(1, true);
open();
}
private void setup(int page, boolean initial)
{
if (initial)
{
Buttons.clear();
Inv.clear();
}
{
//0
ActionButton membersButton = new ActionButton(new ItemBuilder(Material.SKULL_ITEM).setData((short)3).setTitle(C.cGreenB + "Members").build(), clickType ->
{
new CommunityMembersPage(Viewer, _community).open();
});
Buttons.put(0, membersButton);
Inv.setItem(0, membersButton.Button);
//4
CommunityButton communityButton = new CommunityButton(Viewer, _community);
Buttons.put(4, communityButton);
Inv.setItem(4, communityButton.Button);
//8
ActionButton returnButton = new ActionButton(new ItemBuilder(Material.BED).setTitle(C.cGray + "\u21FD Go Back").build(), clickType ->
{
new CommunityOverviewPage(Viewer).open();
});
Buttons.put(8, returnButton);
Inv.setItem(8, returnButton.Button);
//CoLeader+
if (_community.getMembers().containsKey(Viewer.getUniqueId()) && _community.getMembers().get(Viewer.getUniqueId()).Role.ordinal() <= CommunityRole.COLEADER.ordinal())
{
ActionButton requestsButton = new ActionButton(new ItemBuilder(Material.PAPER).setTitle(C.cGreenB + "Join Requests").build(), clickType -> {});
Buttons.put(2, requestsButton);
Inv.setItem(2, requestsButton.Button);
ActionButton settingsButton = new ActionButton(new ItemBuilder(Material.REDSTONE_COMPARATOR).setTitle(C.cGreenB + "Community Settings").build(), clickType ->
{
new CommunitySettingsPage(Viewer, _community);
});
Buttons.put(6, settingsButton);
Inv.setItem(6, settingsButton.Button);
}
else if (_community.getMembers().containsKey(Viewer.getUniqueId()))
{
CommunityChatReadingButton chatButton = new CommunityChatReadingButton(Viewer, _community);
Buttons.put(6, chatButton);
Inv.setItem(6, chatButton.Button);
}
}
{
ActionButton back = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Previous Page").build(), clickType ->
{
if (_page == 1)
{
return;
}
setup(_page - 1, false);
});
ActionButton next = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Next Page").build(), clickType ->
{
setup(_page + 1, false);
});
Buttons.put(45, back);
Inv.setItem(45, back.Button);
Buttons.put(53, next);
Inv.setItem(53, next.Button);
}
List<CommunityJoinRequestInfo> requests = new LinkedList<>();
for (CommunityJoinRequestInfo info : _community.getJoinRequests().values())
{
requests.add(info);
}
requests.sort((info1, info2) ->
{
return info1.Name.compareToIgnoreCase(info2.Name);
});
int slot = 18;
boolean cleared = false;
for (int i = (page - 1) * REQUESTS_PER_PAGE; i < (page - 1) * REQUESTS_PER_PAGE + REQUESTS_PER_PAGE && i < requests.size(); i++)
{
if (!cleared && !initial)
{
cleared = true;
_page = page;
for (int clear = 18; clear < 45; clear++)
{
Buttons.remove(clear);
Inv.setItem(clear, null);
}
}
CommunityJoinRequestButton button = new CommunityJoinRequestButton(Viewer, _community, requests.get(i));
Buttons.put(slot, button);
Inv.setItem(slot, button.Button);
slot++;
}
Viewer.updateInventory();
}
@EventHandler
public void onMembershipUpdate(CommunityMembershipUpdateEvent event)
{
if (event.getCommunity().getId().intValue() != _community.getId().intValue())
{
return;
}
if (_community.getMembers().containsKey(Viewer.getUniqueId()) && _community.getMembers().get(Viewer.getUniqueId()).Role.ordinal() <= CommunityRole.COLEADER.ordinal())
{
setup(1, true);
}
else
{
new CommunityMembersPage(Viewer, _community).open();
}
}
@EventHandler
public void onRequestsUpdate(CommunityJoinRequestsUpdateEvent event)
{
if (event.getCommunity().getId().intValue() != _community.getId().intValue())
{
return;
}
setup(1, true);
}
@EventHandler
public void onCommunityDisband(CommunityDisbandEvent event)
{
if (_community.getId().intValue() == event.getCommunity().getId().intValue())
{
Viewer.closeInventory();
}
}
@EventHandler
public void onMembershipUpdate(CommunityMemberDataUpdateEvent event)
{
if (!event.getPlayer().getUniqueId().toString().equalsIgnoreCase(Viewer.getUniqueId().toString()))
{
return;
}
setup(1, true);
}
}

View File

@ -0,0 +1,80 @@
package mineplex.core.communities.gui.community;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.communities.Community;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityRole;
import mineplex.core.communities.gui.CommunitiesGUIButton;
public class CommunityMemberButton extends CommunitiesGUIButton
{
private Player _viewer;
private Community _community;
private CommunityMemberInfo _info;
public CommunityMemberButton(Player viewer, Community community, CommunityMemberInfo info)
{
super(info.getRepresentation(getCommunityManager().Get(viewer).getRoleIn(community)));
_viewer = viewer;
_community = community;
_info = info;
}
@Override
public void update()
{
Button = _info.getRepresentation(getCommunityManager().Get(_viewer).getRoleIn(_community));
}
@Override
public void handleClick(ClickType type)
{
if (type == ClickType.SHIFT_RIGHT)
{
if (getCommunityManager().Get(_viewer).getRoleIn(_community) != null && getCommunityManager().Get(_viewer).getRoleIn(_community).ordinal() < _info.Role.ordinal())
{
getCommunityManager().handleKick(_viewer, _community, _info);
}
}
if (type == ClickType.LEFT || type == ClickType.SHIFT_LEFT)
{
if (getCommunityManager().Get(_viewer).getRoleIn(_community) != null && getCommunityManager().Get(_viewer).getRoleIn(_community) == CommunityRole.LEADER && _info.Role != CommunityRole.LEADER)
{
if (_info.Role == CommunityRole.MEMBER)
{
getCommunityManager().handleRoleUpdate(_viewer, _community, _info, CommunityRole.COLEADER);
}
if (_info.Role == CommunityRole.COLEADER && type == ClickType.SHIFT_LEFT)
{
if (_info.OwnsCommunity)
{
UtilPlayer.message(_viewer, F.main(getCommunityManager().getName(), F.name(_info.Name) + " can only own one community at a time!"));
return;
}
if (!Rank.valueOf(Managers.get(CoreClientManager.class).loadOfflineClient(_info.UUID).Rank).has(Rank.ETERNAL))
{
UtilPlayer.message(_viewer, F.main(getCommunityManager().getName(), "Only Eternal rank and above can own a community!"));
return;
}
getCommunityManager().handleRoleUpdate(_viewer, _community, _info, CommunityRole.LEADER);
getCommunityManager().handleRoleUpdate(_viewer, _community, _community.getMembers().get(_viewer.getUniqueId()), CommunityRole.COLEADER);
}
}
}
if (type == ClickType.RIGHT)
{
if (getCommunityManager().Get(_viewer).getRoleIn(_community) != null && getCommunityManager().Get(_viewer).getRoleIn(_community) == CommunityRole.LEADER && _info.Role == CommunityRole.COLEADER)
{
getCommunityManager().handleRoleUpdate(_viewer, _community, _info, CommunityRole.MEMBER);
}
}
}
}

View File

@ -0,0 +1,175 @@
package mineplex.core.communities.gui.community;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.common.util.C;
import mineplex.core.communities.Community;
import mineplex.core.communities.CommunityDisbandEvent;
import mineplex.core.communities.CommunityMemberDataUpdateEvent;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityMembershipUpdateEvent;
import mineplex.core.communities.CommunityRole;
import mineplex.core.communities.gui.ActionButton;
import mineplex.core.communities.gui.CommunitiesGUIPage;
import mineplex.core.communities.gui.overview.CommunityOverviewPage;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityMembersPage extends CommunitiesGUIPage
{
private static final int MEMBERS_PER_PAGE = 27;
private Community _community;
private int _page = 1;
public CommunityMembersPage(Player viewer, Community community)
{
super(community.getName() + C.cAqua, 6, viewer);
_community = community;
setup(1, true);
open();
}
private void setup(int page, boolean initial)
{
if (initial)
{
Buttons.clear();
Inv.clear();
}
{
//0
ActionButton membersButton = new ActionButton(new ItemBuilder(Material.SKULL_ITEM).setData((short)3).setTitle(C.cGreenB + "Members").build(), clickType -> {});
Buttons.put(0, membersButton);
Inv.setItem(0, membersButton.Button);
//4
CommunityButton communityButton = new CommunityButton(Viewer, _community);
Buttons.put(4, communityButton);
Inv.setItem(4, communityButton.Button);
//8
ActionButton returnButton = new ActionButton(new ItemBuilder(Material.BED).setTitle(C.cGray + "\u21FD Go Back").build(), clickType ->
{
new CommunityOverviewPage(Viewer).open();
});
Buttons.put(8, returnButton);
Inv.setItem(8, returnButton.Button);
//CoLeader+
if (_community.getMembers().containsKey(Viewer.getUniqueId()) && _community.getMembers().get(Viewer.getUniqueId()).Role.ordinal() <= CommunityRole.COLEADER.ordinal())
{
ActionButton requestsButton = new ActionButton(new ItemBuilder(Material.PAPER).setTitle(C.cGreenB + "Join Requests").build(), clickType ->
{
new CommunityJoinRequestsPage(Viewer, _community).open();
});
Buttons.put(2, requestsButton);
Inv.setItem(2, requestsButton.Button);
ActionButton settingsButton = new ActionButton(new ItemBuilder(Material.REDSTONE_COMPARATOR).setTitle(C.cGreenB + "Community Settings").build(), clickType ->
{
new CommunitySettingsPage(Viewer, _community);
});
Buttons.put(6, settingsButton);
Inv.setItem(6, settingsButton.Button);
}
else if (_community.getMembers().containsKey(Viewer.getUniqueId()))
{
CommunityChatReadingButton chatButton = new CommunityChatReadingButton(Viewer, _community);
Buttons.put(6, chatButton);
Inv.setItem(6, chatButton.Button);
}
}
{
ActionButton back = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Previous Page").build(), clickType ->
{
if (_page == 1)
{
return;
}
setup(_page - 1, false);
});
ActionButton next = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Next Page").build(), clickType ->
{
setup(_page + 1, false);
});
Buttons.put(45, back);
Inv.setItem(45, back.Button);
Buttons.put(53, next);
Inv.setItem(53, next.Button);
}
List<CommunityMemberInfo> members = new LinkedList<>();
for (CommunityMemberInfo info : _community.getMembers().values())
{
members.add(info);
}
members.sort((info1, info2) ->
{
if (info1.isOnline() == info2.isOnline())
{
return info1.Name.compareToIgnoreCase(info2.Name);
}
if (info1.isOnline())
{
return -1;
}
return 1;
});
int slot = 18;
boolean cleared = false;
for (int i = (page - 1) * MEMBERS_PER_PAGE; i < (page - 1) * MEMBERS_PER_PAGE + MEMBERS_PER_PAGE && i < members.size(); i++)
{
if (!cleared && !initial)
{
cleared = true;
_page = page;
for (int clear = 18; clear < 45; clear++)
{
Buttons.remove(clear);
Inv.setItem(clear, null);
}
}
CommunityMemberButton button = new CommunityMemberButton(Viewer, _community, members.get(i));
Buttons.put(slot, button);
Inv.setItem(slot, button.Button);
slot++;
}
Viewer.updateInventory();
}
@EventHandler
public void onMembershipUpdate(CommunityMembershipUpdateEvent event)
{
if (event.getCommunity().getId().intValue() != _community.getId().intValue())
{
return;
}
setup(1, true);
}
@EventHandler
public void onCommunityDisband(CommunityDisbandEvent event)
{
if (_community.getId().intValue() == event.getCommunity().getId().intValue())
{
Viewer.closeInventory();
}
}
@EventHandler
public void onMembershipUpdate(CommunityMemberDataUpdateEvent event)
{
if (!event.getPlayer().getUniqueId().toString().equalsIgnoreCase(Viewer.getUniqueId().toString()))
{
return;
}
setup(1, true);
}
}

View File

@ -0,0 +1,258 @@
package mineplex.core.communities.gui.community;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
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.material.MaterialData;
import mineplex.core.common.util.C;
import mineplex.core.communities.Community;
import mineplex.core.communities.Community.PrivacySetting;
import mineplex.core.communities.CommunityRole;
import mineplex.core.communities.CommunitySetting;
import mineplex.core.communities.gui.CommunitiesGUIButton;
import mineplex.core.game.GameDisplay;
import mineplex.core.itemstack.ItemBuilder;
public class CommunitySettingButton extends CommunitiesGUIButton
{
@SuppressWarnings("serial")
private static final Map<ChatColor, DyeColor> COLOR_MAP = new HashMap<ChatColor, DyeColor>()
{
{
put(ChatColor.AQUA, DyeColor.CYAN);
put(ChatColor.BLACK, DyeColor.BLACK);
put(ChatColor.BLUE, DyeColor.LIGHT_BLUE);
put(ChatColor.DARK_AQUA, DyeColor.CYAN);
put(ChatColor.DARK_BLUE, DyeColor.BLUE);
put(ChatColor.DARK_GRAY, DyeColor.GRAY);
put(ChatColor.DARK_GREEN, DyeColor.GREEN);
put(ChatColor.DARK_PURPLE, DyeColor.PURPLE);
put(ChatColor.DARK_RED, DyeColor.RED);
put(ChatColor.GOLD, DyeColor.YELLOW);
put(ChatColor.GRAY, DyeColor.SILVER);
put(ChatColor.GREEN, DyeColor.LIME);
put(ChatColor.LIGHT_PURPLE, DyeColor.PINK);
put(ChatColor.RED, DyeColor.RED);
put(ChatColor.WHITE, DyeColor.WHITE);
put(ChatColor.YELLOW, DyeColor.YELLOW);
}
};
@SuppressWarnings("serial")
private static final Map<ChatColor, String> COLOR_NAME_MAP = new HashMap<ChatColor, String>()
{
{
put(ChatColor.AQUA, "Aqua");
put(ChatColor.BLACK, "Black");
put(ChatColor.BLUE, "Blue");
put(ChatColor.DARK_AQUA, "Cyan");
put(ChatColor.DARK_BLUE, "Dark Blue");
put(ChatColor.DARK_GRAY, "Dark Gray");
put(ChatColor.DARK_GREEN, "Dark Green");
put(ChatColor.DARK_PURPLE, "Purple");
put(ChatColor.DARK_RED, "Dark Red");
put(ChatColor.GOLD, "Gold");
put(ChatColor.GRAY, "Gray");
put(ChatColor.GREEN, "Green");
put(ChatColor.LIGHT_PURPLE, "Pink");
put(ChatColor.RED, "Red");
put(ChatColor.WHITE, "White");
put(ChatColor.YELLOW, "Yellow");
}
};
private Player _viewer;
private Community _community;
private CommunitySetting _setting;
public CommunitySettingButton(Player viewer, Community community, CommunitySetting setting)
{
super(new ItemBuilder(Material.BARRIER).build());
_viewer = viewer;
_community = community;
_setting = setting;
update();
}
@SuppressWarnings("deprecation")
@Override
public void update()
{
if (_setting == CommunitySetting.FAVORITE_GAME)
{
Button = new ItemBuilder(new ItemStack(_community.getFavoriteGame().getMaterial(), 1, _community.getFavoriteGame().getMaterialData(), null)).setTitle(C.cGreenB + "Favorite Game").addLore(C.cWhite + _community.getFavoriteGame().getName(), C.cRed, C.cYellow + "Left Click " + C.cWhite + "Next Game", C.cYellow + "Right Click " + C.cWhite + "Previous Game").build();
}
else if (_setting == CommunitySetting.PRIVACY)
{
Button = new ItemBuilder(Material.DARK_OAK_DOOR_ITEM).setTitle(C.cGreenB + "Privacy").addLore(C.cWhite + _community.getPrivacySetting().getDisplayText(), C.cRed, C.cYellow + "Left Click " + C.cWhite + "Next Privacy Setting", C.cYellow + "Right Click " + C.cWhite + "Previous Privacy Setting").build();
}
else if (_setting == CommunitySetting.CHAT_DELAY)
{
Button = new ItemBuilder(Material.PAPER).setTitle(C.cGreenB + "Chat Delay").addLore(C.cWhite + (_community.getChatDelay() == 0 ? "No Delay" : _community.getChatDelay() / 1000 + " Second(s)"), C.cRed, C.cYellow + "Left Click " + C.cWhite + "Next Delay Setting", C.cYellow + "Right Click " + C.cWhite + "Previous Delay Setting").build();
}
else if (_setting == CommunitySetting.CHAT_NAME_COLOR)
{
ItemStack base = new MaterialData(Material.WOOL, COLOR_MAP.get(_community.getChatFormatting()[0]).getWoolData()).toItemStack(1);
Button = new ItemBuilder(base).setTitle(C.cGreenB + "Chat Community Color").addLore(C.cWhite + COLOR_NAME_MAP.get(_community.getChatFormatting()[0]), C.cRed, C.cYellow + "Left Click " + C.cWhite + "Next Color", C.cYellow + "Right Click " + C.cWhite + "Previous Color").build();
}
else if (_setting == CommunitySetting.CHAT_PLAYER_COLOR)
{
ItemStack base = new MaterialData(Material.WOOL, COLOR_MAP.get(_community.getChatFormatting()[1]).getWoolData()).toItemStack(1);
Button = new ItemBuilder(base).setTitle(C.cGreenB + "Chat Player Color").addLore(C.cWhite + COLOR_NAME_MAP.get(_community.getChatFormatting()[1]), C.cRed, C.cYellow + "Left Click " + C.cWhite + "Next Color", C.cYellow + "Right Click " + C.cWhite + "Previous Color").build();
}
else if (_setting == CommunitySetting.CHAT_MESSAGE_COLOR)
{
ItemStack base = new MaterialData(Material.WOOL, COLOR_MAP.get(_community.getChatFormatting()[2]).getWoolData()).toItemStack(1);
Button = new ItemBuilder(base).setTitle(C.cGreenB + "Chat Message Color").addLore(C.cWhite + COLOR_NAME_MAP.get(_community.getChatFormatting()[2]), C.cRed, C.cYellow + "Left Click " + C.cWhite + "Next Color", C.cYellow + "Right Click " + C.cWhite + "Previous Color").build();
}
}
@Override
public void handleClick(ClickType type)
{
if (type == ClickType.LEFT)
{
if (getCommunityManager().Get(_viewer).getRoleIn(_community) != null && getCommunityManager().Get(_viewer).getRoleIn(_community).ordinal() <= CommunityRole.COLEADER.ordinal())
{
String[] valueArray = new String[] {};
int index = 0;
if (_setting == CommunitySetting.FAVORITE_GAME)
{
GameDisplay[] games = Arrays.asList(GameDisplay.values()).stream().filter(display -> display.isCommunityFavoriteOption()).toArray(size -> new GameDisplay[size]);
valueArray = new String[games.length];
for (int i = 0; i < games.length; i++)
{
valueArray[i] = games[i].getName();
}
index = Arrays.asList(valueArray).indexOf(_community.getFavoriteGame().getName());
}
else if (_setting == CommunitySetting.PRIVACY)
{
valueArray = new String[] {PrivacySetting.OPEN.toString(), PrivacySetting.RECRUITING.toString(), PrivacySetting.PRIVATE.toString()};
index = Arrays.asList(valueArray).indexOf(_community.getPrivacySetting().toString());
}
else if (_setting == CommunitySetting.CHAT_DELAY)
{
valueArray = new String[] {1000L + "", 3000L + "", 5000L + ""};
index = Arrays.asList(valueArray).indexOf(_community.getChatDelay().toString());
}
else if (_setting == CommunitySetting.CHAT_NAME_COLOR)
{
ChatColor[] colors = COLOR_MAP.keySet().toArray(new ChatColor[COLOR_MAP.size()]);
valueArray = new String[colors.length];
for (int i = 0; i < colors.length; i++)
{
valueArray[i] = colors[i].name();
}
index = Arrays.asList(valueArray).indexOf(_community.getChatFormatting()[0].name());
}
else if (_setting == CommunitySetting.CHAT_PLAYER_COLOR)
{
ChatColor[] colors = COLOR_MAP.keySet().toArray(new ChatColor[COLOR_MAP.size()]);
valueArray = new String[colors.length];
for (int i = 0; i < colors.length; i++)
{
valueArray[i] = colors[i].name();
}
index = Arrays.asList(valueArray).indexOf(_community.getChatFormatting()[1].name());
}
else if (_setting == CommunitySetting.CHAT_MESSAGE_COLOR)
{
ChatColor[] colors = COLOR_MAP.keySet().toArray(new ChatColor[COLOR_MAP.size()]);
valueArray = new String[colors.length];
for (int i = 0; i < colors.length; i++)
{
valueArray[i] = colors[i].name();
}
index = Arrays.asList(valueArray).indexOf(_community.getChatFormatting()[2].name());
}
int newIndex = (index + 1 >= valueArray.length) ? 0 : (index + 1);
getCommunityManager().handleSettingUpdate(_viewer, _community, _setting, valueArray[newIndex]);
}
}
if (type == ClickType.RIGHT)
{
if (getCommunityManager().Get(_viewer).getRoleIn(_community) != null && getCommunityManager().Get(_viewer).getRoleIn(_community).ordinal() <= CommunityRole.COLEADER.ordinal())
{
String[] valueArray = new String[] {};
int index = 0;
if (_setting == CommunitySetting.FAVORITE_GAME)
{
GameDisplay[] games = Arrays.asList(GameDisplay.values()).stream().filter(display -> display.isCommunityFavoriteOption()).toArray(size -> new GameDisplay[size]);
valueArray = new String[games.length];
for (int i = 0; i < games.length; i++)
{
valueArray[i] = games[i].getName();
}
index = Arrays.asList(valueArray).indexOf(_community.getFavoriteGame().getName());
}
else if (_setting == CommunitySetting.PRIVACY)
{
valueArray = new String[] {PrivacySetting.OPEN.toString(), PrivacySetting.RECRUITING.toString(), PrivacySetting.PRIVATE.toString()};
index = Arrays.asList(valueArray).indexOf(_community.getPrivacySetting().toString());
}
else if (_setting == CommunitySetting.CHAT_DELAY)
{
valueArray = new String[] {1000L + "", 3000L + "", 5000L + ""};
index = Arrays.asList(valueArray).indexOf(_community.getChatDelay().toString());
}
else if (_setting == CommunitySetting.CHAT_NAME_COLOR)
{
ChatColor[] colors = COLOR_MAP.keySet().toArray(new ChatColor[COLOR_MAP.size()]);
valueArray = new String[colors.length];
for (int i = 0; i < colors.length; i++)
{
valueArray[i] = colors[i].name();
}
index = Arrays.asList(valueArray).indexOf(_community.getChatFormatting()[0].name());
}
else if (_setting == CommunitySetting.CHAT_PLAYER_COLOR)
{
ChatColor[] colors = COLOR_MAP.keySet().toArray(new ChatColor[COLOR_MAP.size()]);
valueArray = new String[colors.length];
for (int i = 0; i < colors.length; i++)
{
valueArray[i] = colors[i].name();
}
index = Arrays.asList(valueArray).indexOf(_community.getChatFormatting()[1].name());
}
else if (_setting == CommunitySetting.CHAT_MESSAGE_COLOR)
{
ChatColor[] colors = COLOR_MAP.keySet().toArray(new ChatColor[COLOR_MAP.size()]);
valueArray = new String[colors.length];
for (int i = 0; i < colors.length; i++)
{
valueArray[i] = colors[i].name();
}
index = Arrays.asList(valueArray).indexOf(_community.getChatFormatting()[2].name());
}
int newIndex = (index - 1 < 0) ? (valueArray.length - 1) : (index - 1);
getCommunityManager().handleSettingUpdate(_viewer, _community, _setting, valueArray[newIndex]);
}
}
}
}

View File

@ -0,0 +1,149 @@
package mineplex.core.communities.gui.community;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.common.util.C;
import mineplex.core.communities.Community;
import mineplex.core.communities.CommunityDisbandEvent;
import mineplex.core.communities.CommunityMemberDataUpdateEvent;
import mineplex.core.communities.CommunityMembershipUpdateEvent;
import mineplex.core.communities.CommunityRole;
import mineplex.core.communities.CommunitySetting;
import mineplex.core.communities.CommunitySettingUpdateEvent;
import mineplex.core.communities.gui.ActionButton;
import mineplex.core.communities.gui.CommunitiesGUIPage;
import mineplex.core.communities.gui.overview.CommunityOverviewPage;
import mineplex.core.itemstack.ItemBuilder;
public class CommunitySettingsPage extends CommunitiesGUIPage
{
private Community _community;
public CommunitySettingsPage(Player viewer, Community community)
{
super(community.getName() + C.cBlue, 6, viewer);
_community = community;
setup();
open();
}
private void setup()
{
{
//0
ActionButton membersButton = new ActionButton(new ItemBuilder(Material.SKULL_ITEM).setData((short)3).setTitle(C.cGreenB + "Members").build(), clickType ->
{
new CommunityMembersPage(Viewer, _community).open();
});
Buttons.put(0, membersButton);
Inv.setItem(0, membersButton.Button);
//4
CommunityButton communityButton = new CommunityButton(Viewer, _community);
Buttons.put(4, communityButton);
Inv.setItem(4, communityButton.Button);
//8
ActionButton returnButton = new ActionButton(new ItemBuilder(Material.BED).setTitle(C.cGray + "\u21FD Go Back").build(), clickType ->
{
new CommunityOverviewPage(Viewer).open();
});
Buttons.put(8, returnButton);
Inv.setItem(8, returnButton.Button);
//CoLeader+
if (_community.getMembers().containsKey(Viewer.getUniqueId()) && _community.getMembers().get(Viewer.getUniqueId()).Role.ordinal() <= CommunityRole.COLEADER.ordinal())
{
ActionButton requestsButton = new ActionButton(new ItemBuilder(Material.PAPER).setTitle(C.cGreenB + "Join Requests").build(), clickType ->
{
new CommunityJoinRequestsPage(Viewer, _community).open();
});
Buttons.put(2, requestsButton);
Inv.setItem(2, requestsButton.Button);
ActionButton settingsButton = new ActionButton(new ItemBuilder(Material.REDSTONE_COMPARATOR).setTitle(C.cGreenB + "Community Settings").build(), clickType -> {});
Buttons.put(6, settingsButton);
Inv.setItem(6, settingsButton.Button);
}
else if (_community.getMembers().containsKey(Viewer.getUniqueId()))
{
CommunityChatReadingButton chatButton = new CommunityChatReadingButton(Viewer, _community);
Buttons.put(6, chatButton);
Inv.setItem(6, chatButton.Button);
}
}
{
CommunitySettingButton gameButton = new CommunitySettingButton(Viewer, _community, CommunitySetting.FAVORITE_GAME);
Buttons.put(20, gameButton);
Inv.setItem(20, gameButton.Button);
CommunitySettingButton privacyButton = new CommunitySettingButton(Viewer, _community, CommunitySetting.PRIVACY);
Buttons.put(22, privacyButton);
Inv.setItem(22, privacyButton.Button);
CommunityChatReadingButton chatButton = new CommunityChatReadingButton(Viewer, _community);
Buttons.put(24, chatButton);
Inv.setItem(24, chatButton.Button);
CommunitySettingButton delayButton = new CommunitySettingButton(Viewer, _community, CommunitySetting.CHAT_DELAY);
Buttons.put(38, delayButton);
Inv.setItem(38, delayButton.Button);
CommunitySettingButton communityColorButton = new CommunitySettingButton(Viewer, _community, CommunitySetting.CHAT_NAME_COLOR);
Buttons.put(40, communityColorButton);
Inv.setItem(40, communityColorButton.Button);
CommunitySettingButton playerColorButton = new CommunitySettingButton(Viewer, _community, CommunitySetting.CHAT_PLAYER_COLOR);
Buttons.put(41, playerColorButton);
Inv.setItem(41, playerColorButton.Button);
CommunitySettingButton messageColorButton = new CommunitySettingButton(Viewer, _community, CommunitySetting.CHAT_MESSAGE_COLOR);
Buttons.put(42, messageColorButton);
Inv.setItem(42, messageColorButton.Button);
}
Viewer.updateInventory();
}
@EventHandler
public void onMembershipUpdate(CommunityMembershipUpdateEvent event)
{
if (event.getCommunity().getId().intValue() != _community.getId().intValue())
{
return;
}
if (!_community.getMembers().containsKey(Viewer.getUniqueId()) || _community.getMembers().get(Viewer.getUniqueId()).Role.ordinal() > CommunityRole.COLEADER.ordinal())
{
new CommunityMembersPage(Viewer, _community).open();
}
}
@EventHandler
public void onSettingsUpdate(CommunitySettingUpdateEvent event)
{
if (event.getCommunity().getId() != _community.getId())
{
return;
}
setup();
}
@EventHandler
public void onCommunityDisband(CommunityDisbandEvent event)
{
if (_community.getId().intValue() == event.getCommunity().getId().intValue())
{
Viewer.closeInventory();
}
}
@EventHandler
public void onMembershipUpdate(CommunityMemberDataUpdateEvent event)
{
if (!event.getPlayer().getUniqueId().toString().equalsIgnoreCase(Viewer.getUniqueId().toString()))
{
return;
}
setup();
}
}

View File

@ -0,0 +1,118 @@
package mineplex.core.communities.gui.overview;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.common.util.C;
import mineplex.core.communities.CommunityDisbandEvent;
import mineplex.core.communities.CommunityMemberDataUpdateEvent;
import mineplex.core.communities.gui.ActionButton;
import mineplex.core.communities.gui.CommunitiesGUIPage;
import mineplex.core.communities.gui.browser.CommunityBrowserPage;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityInvitesPage extends CommunitiesGUIPage
{
private static final int COMMUNITIES_PER_PAGE = 27;
private int _page = 1;
public CommunityInvitesPage(Player viewer)
{
super("Community Invites", 6, viewer);
setup(1, true);
open();
}
private void setup(int page, boolean initial)
{
if (initial)
{
Buttons.clear();
Inv.clear();
}
{
//1
ActionButton communitiesButton = new ActionButton(new ItemBuilder(Material.EMERALD).setTitle(C.cGreenB + "Your Communities").build(), clickType ->
{
new CommunityOverviewPage(Viewer).open();
});
Buttons.put(1, communitiesButton);
Inv.setItem(1, communitiesButton.Button);
//4
ActionButton browserButton = new ActionButton(new ItemBuilder(Material.COMPASS).setTitle(C.cGreenB + "Browse Communities").build(), clickType ->
{
new CommunityBrowserPage(Viewer).open();
});
Buttons.put(4, browserButton);
Inv.setItem(4, browserButton.Button);
//7
ActionButton invitesButton = new ActionButton(new ItemBuilder(Material.PAPER).setTitle(C.cGreenB + "Community Invites").build(), clickType -> {});
Buttons.put(7, invitesButton);
Inv.setItem(7, invitesButton.Button);
}
{
ActionButton back = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Previous Page").build(), clickType ->
{
if (_page == 1)
{
return;
}
setup(_page - 1, false);
});
ActionButton next = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Next Page").build(), clickType ->
{
setup(_page + 1, false);
});
Buttons.put(45, back);
Inv.setItem(45, back.Button);
Buttons.put(53, next);
Inv.setItem(53, next.Button);
}
int slot = 18;
boolean cleared = false;
for (int i = (page - 1) * COMMUNITIES_PER_PAGE; i < (page - 1) * COMMUNITIES_PER_PAGE + COMMUNITIES_PER_PAGE && i < getCommunityManager().Get(Viewer).Invites.size(); i++)
{
if (!cleared && !initial)
{
cleared = true;
_page = page;
for (int clear = 18; clear < 45; clear++)
{
Buttons.remove(clear);
Inv.setItem(clear, null);
}
}
CommunityVisualizationButton button = new CommunityVisualizationButton(Viewer, getCommunityManager().getLoadedCommunity(getCommunityManager().Get(Viewer).Invites.get(i)), true);
Buttons.put(slot, button);
Inv.setItem(slot, button.Button);
slot++;
}
Viewer.updateInventory();
}
@EventHandler
public void onMembershipUpdate(CommunityMemberDataUpdateEvent event)
{
if (!event.getPlayer().getUniqueId().toString().equalsIgnoreCase(Viewer.getUniqueId().toString()))
{
return;
}
setup(1, true);
}
@EventHandler
public void onCommunityDisband(CommunityDisbandEvent event)
{
if (getCommunityManager().Get(Viewer).Invites.contains(event.getCommunity().getId()))
{
setup(1, true);
}
}
}

View File

@ -0,0 +1,136 @@
package mineplex.core.communities.gui.overview;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.common.util.C;
import mineplex.core.communities.Community;
import mineplex.core.communities.CommunityDisbandEvent;
import mineplex.core.communities.CommunityMemberDataUpdateEvent;
import mineplex.core.communities.gui.ActionButton;
import mineplex.core.communities.gui.CommunitiesGUIPage;
import mineplex.core.communities.gui.browser.CommunityBrowserPage;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityOverviewPage extends CommunitiesGUIPage
{
private static final int COMMUNITIES_PER_PAGE = 27;
private int _page = 1;
public CommunityOverviewPage(Player viewer)
{
super("Your Communities", 6, viewer);
setup(1, true);
open();
}
private void setup(int page, boolean initial)
{
if (initial)
{
Buttons.clear();
Inv.clear();
}
{
//1
ActionButton communitiesButton = new ActionButton(new ItemBuilder(Material.EMERALD).setTitle(C.cGreenB + "Your Communities").build(), clickType -> {});
Buttons.put(1, communitiesButton);
Inv.setItem(1, communitiesButton.Button);
//4
ActionButton browserButton = new ActionButton(new ItemBuilder(Material.COMPASS).setTitle(C.cGreenB + "Browse Communities").build(), clickType ->
{
new CommunityBrowserPage(Viewer).open();
});
Buttons.put(4, browserButton);
Inv.setItem(4, browserButton.Button);
//7
ActionButton invitesButton = new ActionButton(new ItemBuilder(Material.PAPER).setTitle(C.cGreenB + "Community Invites").build(), clickType ->
{
new CommunityInvitesPage(Viewer);
});
Buttons.put(7, invitesButton);
Inv.setItem(7, invitesButton.Button);
}
{
ActionButton back = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Previous Page").build(), clickType ->
{
if (_page == 1)
{
return;
}
setup(_page - 1, false);
});
ActionButton next = new ActionButton(new ItemBuilder(Material.ARROW).setTitle(C.cGreen + "Next Page").build(), clickType ->
{
setup(_page + 1, false);
});
Buttons.put(45, back);
Inv.setItem(45, back.Button);
Buttons.put(53, next);
Inv.setItem(53, next.Button);
}
int slot = 18;
boolean cleared = false;
for (int i = (page - 1) * COMMUNITIES_PER_PAGE; i < (page - 1) * COMMUNITIES_PER_PAGE + COMMUNITIES_PER_PAGE && i < getCommunityManager().Get(Viewer).getTotalCommunities(); i++)
{
if (!cleared && !initial)
{
cleared = true;
_page = page;
for (int clear = 18; clear < 45; clear++)
{
Buttons.remove(clear);
Inv.setItem(clear, null);
}
}
List<Community> coms = Arrays.asList(getCommunityManager().Get(Viewer).getCommunities());
coms.sort((c1, c2) ->
{
if (c1.getMembers().get(Viewer.getUniqueId()).Role == c2.getMembers().get(Viewer.getUniqueId()).Role)
{
return c1.getName().compareTo(c2.getName());
}
if (c1.getMembers().get(Viewer.getUniqueId()).Role.ordinal() < c2.getMembers().get(Viewer.getUniqueId()).Role.ordinal())
{
return -1;
}
return 1;
});
CommunityVisualizationButton button = new CommunityVisualizationButton(Viewer, coms.get(i), false);
Buttons.put(slot, button);
Inv.setItem(slot, button.Button);
slot++;
}
Viewer.updateInventory();
}
@EventHandler
public void onMembershipUpdate(CommunityMemberDataUpdateEvent event)
{
if (!event.getPlayer().getUniqueId().toString().equalsIgnoreCase(Viewer.getUniqueId().toString()))
{
return;
}
setup(1, true);
}
@EventHandler
public void onCommunityDisband(CommunityDisbandEvent event)
{
if (getCommunityManager().Get(Viewer).Invites.contains(event.getCommunity().getId()))
{
setup(1, true);
}
}
}

View File

@ -0,0 +1,61 @@
package mineplex.core.communities.gui.overview;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilText;
import mineplex.core.communities.Community;
import mineplex.core.communities.gui.CommunitiesGUIButton;
import mineplex.core.communities.gui.community.CommunityMembersPage;
import mineplex.core.itemstack.ItemBuilder;
public class CommunityVisualizationButton extends CommunitiesGUIButton
{
private Player _viewer;
private Community _community;
private boolean _invite;
public CommunityVisualizationButton(Player viewer, Community community, boolean invite)
{
super(new ItemBuilder(Material.BARRIER).build());
_viewer = viewer;
_community = community;
_invite = invite;
update();
}
@SuppressWarnings("deprecation")
@Override
public void update()
{
ItemBuilder builder = new ItemBuilder(new ItemStack(_community.getFavoriteGame().getMaterial(), 1, _community.getFavoriteGame().getMaterialData(), null)).setTitle(C.cGreenB + _community.getName()).addLore(UtilText.splitLinesToArray(new String[] {C.cRed, C.cYellow + "Members " + C.cWhite + _community.getMembers().size(), C.cYellow + "Favorite Game " + C.cWhite + _community.getFavoriteGame().getName(), C.cYellow + "Description " + C.cWhite + _community.getDescription()}, LineFormat.LORE));
if (_invite)
{
builder.addLore(UtilText.splitLinesToArray(new String[] {C.cGold, C.cYellow + "Shift-Left Click " + C.cWhite + "Join", C.cYellow + "Shift-Right Click " + C.cWhite + "Decline"}, LineFormat.LORE));
}
builder.addLore(C.cBlue, C.cGreen + "Click to view community");
Button = builder.build();
}
@Override
public void handleClick(ClickType type)
{
if (_invite && type == ClickType.SHIFT_RIGHT)
{
getCommunityManager().handleRejectInvite(_viewer, _community);
}
else if (_invite && type == ClickType.SHIFT_LEFT)
{
getCommunityManager().handleJoin(_viewer, _community, true);
}
else
{
new CommunityMembersPage(_viewer, _community).open();
}
}
}

View File

@ -0,0 +1,50 @@
package mineplex.core.communities.mcs;
import org.bukkit.Material;
import mineplex.core.common.util.C;
public enum MCSTheme
{
CANDYLAND(1, C.cPurple + "Candyland", Material.COOKIE, 1000, "Lobby_MPS_Candyland.zip")
;
private final int _id;
private final String _displayName, _file;
private final Material _displayType;
private final int _cost;
private MCSTheme(int id, String displayName, Material displayType, int cost, String file)
{
_id = id;
_displayName = displayName;
_displayType = displayType;
_cost = cost;
_file = file;
}
public int getId()
{
return _id;
}
public String getDisplayName()
{
return _displayName;
}
public Material getDisplayType()
{
return _displayType;
}
public int getCost()
{
return _cost;
}
public String getFile()
{
return _file;
}
}

View File

@ -0,0 +1,32 @@
package mineplex.core.communities.redis;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityChat extends ServerCommand
{
private String _senderName;
private Integer _communityId;
private String _message;
public CommunityChat(String senderName, Integer communityId, String message)
{
_senderName = senderName;
_communityId = communityId;
_message = message;
}
public String getSenderName()
{
return _senderName;
}
public Integer getCommunityId()
{
return _communityId;
}
public String getMessage()
{
return _message;
}
}

View File

@ -0,0 +1,25 @@
package mineplex.core.communities.redis;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityChatHandler implements CommandCallback
{
private CommunityManager _manager;
public CommunityChatHandler(CommunityManager manager)
{
_manager = manager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof CommunityChat)
{
CommunityChat chat = ((CommunityChat) command);
_manager.handleCommunityChat(chat.getCommunityId(), chat.getSenderName(), chat.getMessage());
}
}
}

View File

@ -0,0 +1,53 @@
package mineplex.core.communities.redis;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityCloseJoinRequest extends ServerCommand
{
private Integer _communityId;
private String _sender;
private String _playerName;
private String _playerUUID;
private Integer _accountId;
private boolean _announce;
public CommunityCloseJoinRequest(Integer communityId, String sender, String playerName, String playerUUID, Integer accountId, boolean announce)
{
_communityId = communityId;
_sender = sender;
_playerName = playerName;
_playerUUID = playerUUID;
_accountId = accountId;
_announce = announce;
}
public Integer getCommunityId()
{
return _communityId;
}
public String getSender()
{
return _sender;
}
public String getPlayerName()
{
return _playerName;
}
public String getPlayerUUID()
{
return _playerUUID;
}
public Integer getAccountId()
{
return _accountId;
}
public boolean shouldAnnounce()
{
return _announce;
}
}

View File

@ -0,0 +1,34 @@
package mineplex.core.communities.redis;
import java.util.UUID;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityCloseJoinRequestHandler implements CommandCallback
{
private CommunityManager _manager;
public CommunityCloseJoinRequestHandler(CommunityManager manager)
{
_manager = manager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof CommunityCloseJoinRequest)
{
CommunityCloseJoinRequest update = ((CommunityCloseJoinRequest) command);
Integer id = update.getCommunityId();
String sender = update.getSender();
UUID uuid = UUID.fromString(update.getPlayerUUID());
String name = update.getPlayerName();
Integer accountId = update.getAccountId();
boolean announce = update.shouldAnnounce();
_manager.handleCommunityCloseJoinRequest(id, sender, name, uuid, accountId, announce);
}
}
}

View File

@ -0,0 +1,25 @@
package mineplex.core.communities.redis;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityCreate extends ServerCommand
{
private String _leaderUUID;
private Integer _communityId;
public CommunityCreate(String leaderUUID, Integer communityId)
{
_leaderUUID = leaderUUID;
_communityId = communityId;
}
public String getLeaderUUID()
{
return _leaderUUID;
}
public Integer getCommunityId()
{
return _communityId;
}
}

View File

@ -0,0 +1,30 @@
package mineplex.core.communities.redis;
import java.util.UUID;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityCreateHandler implements CommandCallback
{
private CommunityManager _manager;
public CommunityCreateHandler(CommunityManager manager)
{
_manager = manager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof CommunityCreate)
{
CommunityCreate update = ((CommunityCreate) command);
UUID leaderUUID = UUID.fromString(update.getLeaderUUID());
Integer communityId = update.getCommunityId();
_manager.handleCommunityCreation(communityId, leaderUUID);
}
}
}

View File

@ -0,0 +1,25 @@
package mineplex.core.communities.redis;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityDisband extends ServerCommand
{
private String _senderName;
private Integer _communityId;
public CommunityDisband(String senderName, Integer communityId)
{
_senderName = senderName;
_communityId = communityId;
}
public String getSenderName()
{
return _senderName;
}
public Integer getCommunityId()
{
return _communityId;
}
}

View File

@ -0,0 +1,30 @@
package mineplex.core.communities.redis;
import java.util.UUID;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityDisbandHandler implements CommandCallback
{
private CommunityManager _manager;
public CommunityDisbandHandler(CommunityManager manager)
{
_manager = manager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof CommunityDisband)
{
CommunityDisband update = ((CommunityDisband) command);
String senderName = update.getSenderName();
Integer communityId = update.getCommunityId();
_manager.handleCommunityDisband(communityId, senderName);
}
}
}

View File

@ -0,0 +1,39 @@
package mineplex.core.communities.redis;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityInvite extends ServerCommand
{
private Integer _communityId;
private String _sender;
private String _playerName;
private String _playerUUID;
public CommunityInvite(Integer communityId, String sender, String playerName, String playerUUID)
{
_communityId = communityId;
_sender = sender;
_playerName = playerName;
_playerUUID = playerUUID;
}
public Integer getCommunityId()
{
return _communityId;
}
public String getSender()
{
return _sender;
}
public String getPlayerName()
{
return _playerName;
}
public String getPlayerUUID()
{
return _playerUUID;
}
}

View File

@ -0,0 +1,32 @@
package mineplex.core.communities.redis;
import java.util.UUID;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityInviteHandler implements CommandCallback
{
private CommunityManager _manager;
public CommunityInviteHandler(CommunityManager manager)
{
_manager = manager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof CommunityInvite)
{
CommunityInvite update = ((CommunityInvite) command);
Integer id = update.getCommunityId();
String sender = update.getSender();
String name = update.getPlayerName();
UUID uuid = UUID.fromString(update.getPlayerUUID());
_manager.handleCommunityInvite(id, sender, name, uuid);
}
}
}

View File

@ -0,0 +1,39 @@
package mineplex.core.communities.redis;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityJoinRequest extends ServerCommand
{
private Integer _communityId;
private String _playerName;
private String _playerUUID;
private Integer _accountId;
public CommunityJoinRequest(Integer communityId, String playerName, String playerUUID, Integer accountId)
{
_communityId = communityId;
_playerName = playerName;
_playerUUID = playerUUID;
_accountId = accountId;
}
public Integer getCommunityId()
{
return _communityId;
}
public String getPlayerName()
{
return _playerName;
}
public String getPlayerUUID()
{
return _playerUUID;
}
public Integer getAccountId()
{
return _accountId;
}
}

View File

@ -0,0 +1,32 @@
package mineplex.core.communities.redis;
import java.util.UUID;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityJoinRequestHandler implements CommandCallback
{
private CommunityManager _manager;
public CommunityJoinRequestHandler(CommunityManager manager)
{
_manager = manager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof CommunityJoinRequest)
{
CommunityJoinRequest update = ((CommunityJoinRequest) command);
Integer id = update.getCommunityId();
UUID uuid = UUID.fromString(update.getPlayerUUID());
String name = update.getPlayerName();
Integer accountId = update.getAccountId();
_manager.handleCommunityJoinRequest(id, name, uuid, accountId);
}
}
}

View File

@ -0,0 +1,46 @@
package mineplex.core.communities.redis;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityUnInvite extends ServerCommand
{
private Integer _communityId;
private String _sender;
private String _playerName;
private String _playerUUID;
private boolean _announce;
public CommunityUnInvite(Integer communityId, String sender, String playerName, String playerUUID, boolean announce)
{
_communityId = communityId;
_sender = sender;
_playerName = playerName;
_playerUUID = playerUUID;
_announce = announce;
}
public Integer getCommunityId()
{
return _communityId;
}
public String getSender()
{
return _sender;
}
public String getPlayerName()
{
return _playerName;
}
public String getPlayerUUID()
{
return _playerUUID;
}
public boolean shouldAnnounce()
{
return _announce;
}
}

View File

@ -0,0 +1,33 @@
package mineplex.core.communities.redis;
import java.util.UUID;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityUnInviteHandler implements CommandCallback
{
private CommunityManager _manager;
public CommunityUnInviteHandler(CommunityManager manager)
{
_manager = manager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof CommunityUnInvite)
{
CommunityUnInvite update = ((CommunityUnInvite) command);
Integer id = update.getCommunityId();
String sender = update.getSender();
String name = update.getPlayerName();
UUID uuid = UUID.fromString(update.getPlayerUUID());
boolean announce = update.shouldAnnounce();
_manager.handleCommunityUninvite(id, sender, name, uuid, announce);
}
}
}

View File

@ -0,0 +1,32 @@
package mineplex.core.communities.redis;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityUpdateMemberChatReading extends ServerCommand
{
private Integer _communityId;
private String _playerUUID;
private boolean _reading;
public CommunityUpdateMemberChatReading(Integer communityId, String playerUUID, boolean reading)
{
_communityId = communityId;
_playerUUID = playerUUID;
_reading = reading;
}
public Integer getCommunityId()
{
return _communityId;
}
public String getPlayerUUID()
{
return _playerUUID;
}
public boolean reading()
{
return _reading;
}
}

View File

@ -0,0 +1,31 @@
package mineplex.core.communities.redis;
import java.util.UUID;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class CommunityUpdateMemberChatReadingHandler implements CommandCallback
{
private CommunityManager _manager;
public CommunityUpdateMemberChatReadingHandler(CommunityManager manager)
{
_manager = manager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof CommunityUpdateMemberChatReading)
{
CommunityUpdateMemberChatReading update = ((CommunityUpdateMemberChatReading) command);
Integer id = update.getCommunityId();
UUID uuid = UUID.fromString(update.getPlayerUUID());
boolean reading = update.reading();
_manager.handleToggleReadingCommunityChat(id, uuid, reading);
}
}
}

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