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

This commit is contained in:
Sam 2017-01-12 18:03:07 +00:00
commit 8d47e80066
357 changed files with 6341 additions and 4028 deletions

View File

@ -23,15 +23,6 @@
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-bundle</artifactId>
</dependency>
<dependency>
<groupId>org.apache.ws.security</groupId>
<artifactId>wss4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.5</version>
</dependency>
</dependencies>
<build>
@ -47,6 +38,36 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>org.apache.commons:commons-pool2</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>commons-logging:commons-logging</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -41,15 +41,6 @@ public class BungeeRotator
public static void main(String args[])
{
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e1)
{
e1.printStackTrace();
}
try
{
FileHandler fileHandler = new FileHandler("rotator.log", true);

View File

@ -0,0 +1,7 @@
package mineplex.core.common;
public class Constants
{
public static final String WEB_ADDRESS = "http://accounts.mineplex.com/";
public static final String WEB_CONFIG_KEY = "webServer";
}

View File

@ -6,6 +6,25 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.EntityBat;
import net.minecraft.server.v1_8_R3.EntityCreature;
import net.minecraft.server.v1_8_R3.EntityEnderDragon;
import net.minecraft.server.v1_8_R3.EntityHuman;
import net.minecraft.server.v1_8_R3.EntityInsentient;
import net.minecraft.server.v1_8_R3.EntityLiving;
import net.minecraft.server.v1_8_R3.EntityTrackerEntry;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.NavigationAbstract;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_8_R3.PathfinderGoal;
import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer;
import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction;
import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround;
import net.minecraft.server.v1_8_R3.PathfinderGoalSelector;
import net.minecraft.server.v1_8_R3.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@ -29,24 +48,6 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.EntityBat;
import net.minecraft.server.v1_8_R3.EntityCreature;
import net.minecraft.server.v1_8_R3.EntityEnderDragon;
import net.minecraft.server.v1_8_R3.EntityHuman;
import net.minecraft.server.v1_8_R3.EntityInsentient;
import net.minecraft.server.v1_8_R3.EntityLiving;
import net.minecraft.server.v1_8_R3.EntityTrackerEntry;
import net.minecraft.server.v1_8_R3.NavigationAbstract;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_8_R3.PathfinderGoal;
import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer;
import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction;
import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround;
import net.minecraft.server.v1_8_R3.PathfinderGoalSelector;
import net.minecraft.server.v1_8_R3.WorldServer;
public class UtilEnt
{
@ -67,7 +68,13 @@ public class UtilEnt
public static void silence(Entity entity, boolean silence)
{
((CraftEntity)entity).getHandle().setSilent(silence);
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) entity).getHandle();
NBTTagCompound tag = new NBTTagCompound();
nmsEntity.c(tag);
tag.setByte("Silent", (byte) ((silence) ? 1 : 0));
nmsEntity.f(tag);
// Not working right now
//((CraftEntity)entity).getHandle().setSilent(silence);
}
public static void ghost(Entity entity, boolean ghost, boolean invisible)
@ -81,7 +88,7 @@ public class UtilEnt
((CraftEntity)entity).getHandle().setInvisible(invisible);
}
public static void Leash(LivingEntity leashed, Entity holder, boolean pull, boolean breakable)
public static void leash(LivingEntity leashed, Entity holder, boolean pull, boolean breakable)
{
leashed.setLeashHolder(holder);
@ -191,12 +198,12 @@ public class UtilEnt
return box.b(box2);
}
public static void Vegetate(Entity entity)
public static void vegetate(Entity entity)
{
Vegetate(entity, false);
vegetate(entity, false);
}
public static void Vegetate(Entity entity, boolean mute)
public static void vegetate(Entity entity, boolean mute)
{
try
{

View File

@ -7,6 +7,7 @@ import net.minecraft.server.v1_8_R3.EnumParticle;
import net.minecraft.server.v1_8_R3.PacketPlayOutWorldParticles;
import org.bukkit.Color;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@ -272,6 +273,8 @@ public class UtilParticle
public static void playParticleFor(Player player, ParticleType type, Location location, Vector offset, float speed, int count, ViewDist dist)
{
if (player.getGameMode() == GameMode.SPECTATOR)
return;
float x = 0;
float y = 0;
float z = 0;
@ -289,6 +292,8 @@ public class UtilParticle
public static void playParticleFor(Player player, ParticleType type, Location location, float offsetX, float offsetY, float offsetZ,
float speed, int count, ViewDist dist)
{
if (player.getGameMode() == GameMode.SPECTATOR)
return;
List<Player> players = new ArrayList<>(UtilServer.getPlayersCollection());
players.removeIf(other -> !other.canSee(player));
PlayParticle(type.particleName, location, offsetX, offsetY, offsetZ, speed, count, dist, players.toArray(new Player[0]));
@ -296,6 +301,8 @@ public class UtilParticle
public static void playParticleFor(Player player, String particle, Location location, Vector offset, float speed, int count, ViewDist dist)
{
if (player.getGameMode() == GameMode.SPECTATOR)
return;
float x = 0;
float y = 0;
float z = 0;
@ -313,6 +320,8 @@ public class UtilParticle
public static void playParticleFor(Player player, String particle, Location location, float offsetX, float offsetY, float offsetZ,
float speed, int count, ViewDist dist)
{
if (player.getGameMode() == GameMode.SPECTATOR)
return;
List<Player> players = new ArrayList<>(UtilServer.getPlayersCollection());
players.removeIf(other -> !other.canSee(player));
PlayParticle(particle, location, offsetX, offsetY, offsetZ, speed, count, dist, players.toArray(new Player[0]));

View File

@ -2,6 +2,7 @@ package mineplex.core.common.util;
import com.google.common.collect.Lists;
import mineplex.core.common.Constants;
import mineplex.core.common.events.PlayerRecieveBroadcastEvent;
import mineplex.serverdata.Region;
@ -18,11 +19,18 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.io.File;
import java.lang.reflect.Field;
import java.util.*;
public class UtilServer
{
private static boolean TEST_OVERRIDE = false;
static {
TEST_OVERRIDE = new File("TEST_OVERRIDE.dat").exists();
}
public static Player[] getPlayers()
{
return getServer().getOnlinePlayers().toArray(new Player[0]);
@ -151,7 +159,12 @@ public class UtilServer
public static boolean isTestServer()
{
return getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
return isTestServer(true);
}
public static boolean isTestServer(boolean bypass)
{
return getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing") || (bypass && TEST_OVERRIDE);
}
public static boolean isDevServer()
@ -197,7 +210,7 @@ public class UtilServer
public static String getWebServerURL()
{
return getPlugin().getConfig().getString("webServer");
return getPlugin().getConfig().getString(Constants.WEB_CONFIG_KEY);
}
public static BukkitTask runAsync(Runnable runnable)

View File

@ -60,6 +60,11 @@
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -7,6 +7,9 @@ import mineplex.core.common.util.NautHashMap;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.lifetimes.Lifetime;
import mineplex.core.lifetimes.Lifetimed;
import mineplex.core.lifetimes.SimpleLifetime;
import mineplex.core.thread.ThreadPool;
import org.bukkit.Bukkit;
@ -27,11 +30,15 @@ import org.bukkit.scheduler.BukkitTask;
* <p>
* This way, we can reflectively create them during {@link #require} when they do not exist, leading to much cleaner code
*/
public abstract class MiniPlugin implements Listener
public abstract class MiniPlugin implements Listener, Lifetimed
{
// As MiniPlugins can technically be disabled at any time, each
// has its own unique Lifetime. If MiniPlugins are declared
// to never be able to be disabled, then a "Singleton" Lifetime
// could be shared between all of them.
private final SimpleLifetime _lifetime = new SimpleLifetime();
protected String _moduleName = "Default";
protected JavaPlugin _plugin;
protected NautHashMap<String, ICommand> _commands;
protected long _initializedTime;
@ -47,8 +54,7 @@ public abstract class MiniPlugin implements Listener
_initializedTime = System.currentTimeMillis();
_commands = new NautHashMap<>();
_lifetime.start();
onEnable();
registerEvents(this);
@ -146,7 +152,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
throw new RuntimeException(exception);
exception.initCause(t);
throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
});
}
@ -163,7 +170,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
throw new RuntimeException(exception);
exception.initCause(t);
throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
}, time);
}
@ -180,7 +188,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
throw new RuntimeException(exception);
exception.initCause(t);
throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
}, time, period);
}
@ -197,7 +206,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
throw new RuntimeException(exception);
exception.initCause(t);
throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
});
}
@ -214,7 +224,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
throw new RuntimeException(exception);
exception.initCause(t);
throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
}, delay);
}
@ -236,7 +247,8 @@ public abstract class MiniPlugin implements Listener
}
catch (Throwable t)
{
throw new RuntimeException(exception);
exception.initCause(t);
throw new RuntimeException("Exception while executing MiniPlugin task", exception);
}
}, delay, period);
}
@ -250,4 +262,10 @@ public abstract class MiniPlugin implements Listener
{
return Managers.require(clazz);
}
@Override
public Lifetime getLifetime()
{
return _lifetime;
}
}

View File

@ -68,12 +68,6 @@ public class CoreClient
return _accountId;
}
public void Delete()
{
_name = null;
_player = null;
}
public void setAccountId(int accountId)
{
_accountId = accountId;
@ -214,4 +208,16 @@ public class CoreClient
return getDisguisedAs();
return getName();
}
@Override
public String toString()
{
return "CoreClient{" +
"_accountId=" + _accountId +
", _name='" + _name + '\'' +
", _uuid=" + _uuid +
", _player=" + _player +
", _rank=" + _rank +
'}';
}
}

View File

@ -8,6 +8,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@ -26,6 +27,7 @@ import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import mineplex.cache.player.PlayerCache;
@ -65,17 +67,19 @@ public class CoreClientManager extends MiniPlugin
private final Rank WHITELIST_BYPASS;
public CoreClientManager(JavaPlugin plugin, String webServer)
private final Set<UUID> _reservedSlots = Sets.newConcurrentHashSet();
public CoreClientManager(JavaPlugin plugin)
{
this(plugin, webServer, Rank.MODERATOR);
this(plugin, Rank.MODERATOR);
}
public CoreClientManager(JavaPlugin plugin, String webServer, Rank whitelistBypass)
public CoreClientManager(JavaPlugin plugin, Rank whitelistBypass)
{
super("Client Manager", plugin);
_plugin = plugin;
_repository = new AccountRepository(plugin, webServer);
_repository = new AccountRepository();
WHITELIST_BYPASS = whitelistBypass;
}
@ -102,11 +106,6 @@ public class CoreClientManager extends MiniPlugin
oldClient = _clientList.put(uuid, newClient);
}
if (oldClient != null)
{
oldClient.Delete();
}
return newClient;
}
@ -259,7 +258,9 @@ public class CoreClientManager extends MiniPlugin
if (uuid == null)
{
uuid = UtilGameProfile.getProfileByName(playerName, false, profile -> {}).get().getId();
uuid = UtilGameProfile.getProfileByName(playerName, false, profile ->
{
}).get().getId();
}
String response = "";
@ -481,8 +482,10 @@ public class CoreClientManager extends MiniPlugin
client.SetPlayer(event.getPlayer());
_reservedSlots.remove(event.getPlayer().getUniqueId());
// Reserved Slot Check
if (Bukkit.getOnlinePlayers().size() >= Bukkit.getServer().getMaxPlayers())
if (Bukkit.getOnlinePlayers().size() + _reservedSlots.size() >= Bukkit.getServer().getMaxPlayers())
{
if (client.GetRank().has(event.getPlayer(), Rank.ULTRA, false))
{
@ -495,6 +498,16 @@ public class CoreClientManager extends MiniPlugin
}
}
public void reserveFor(UUID player)
{
this._reservedSlots.add(player);
}
public void unreserve(UUID uuid)
{
_reservedSlots.remove(uuid);
}
@EventHandler
public void Kick(PlayerKickEvent event)
{

View File

@ -7,6 +7,7 @@ import mineplex.core.common.Rank;
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 org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -28,9 +29,7 @@ public class TestRank extends CommandBase<CoreClientManager>
return;
}
boolean testServer = Plugin.getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
if (!testServer)
if (!UtilServer.isTestServer())
{
UtilPlayer.message(caller, F.main(Plugin.getName(), F.elem("This command can only be used on test servers!")));
return;

View File

@ -4,7 +4,6 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@ -13,22 +12,20 @@ import java.util.stream.Collectors;
import org.apache.commons.dbcp2.BasicDataSource;
import org.bukkit.Bukkit;
import com.google.gson.reflect.TypeToken;
import org.bukkit.plugin.java.JavaPlugin;
import com.google.gson.reflect.TypeToken;
import mineplex.cache.player.PlayerCache;
import mineplex.core.account.ILoginProcessor;
import mineplex.core.account.repository.token.LoginToken;
import mineplex.core.account.repository.token.RankUpdateToken;
import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UtilServer;
import mineplex.core.database.MinecraftRepository;
import mineplex.core.server.remotecall.JsonWebCall;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.DatabaseRunnable;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnBoolean;
import mineplex.serverdata.database.column.ColumnTimestamp;
import mineplex.serverdata.database.column.ColumnVarChar;
public class AccountRepository extends MinecraftRepository
@ -43,13 +40,9 @@ public class AccountRepository extends MinecraftRepository
private static String SELECT_ACCOUNT_UUID_BY_NAME = "SELECT uuid FROM accounts WHERE name = ? ORDER BY lastLogin DESC;";
private static String SELECT_ACCOUNT_ID_BY_UUID = "SELECT id FROM accounts WHERE accounts.uuid = ? LIMIT 1";
private String _webAddress;
public AccountRepository(JavaPlugin plugin, String webAddress)
public AccountRepository()
{
super(DBPool.getAccount());
_webAddress = webAddress;
}
public int login(final List<ILoginProcessor> loginProcessors, final UUID uuid, final String name) throws SQLException
@ -133,7 +126,8 @@ public class AccountRepository extends MinecraftRepository
public void getAccountId(UUID uuid, Callback<Integer> callback)
{
executeQuery(SELECT_ACCOUNT_ID_BY_UUID, resultSet -> {
executeQuery(SELECT_ACCOUNT_ID_BY_UUID, resultSet ->
{
int accountId = -1;
while (resultSet.next()) accountId = resultSet.getInt(1);
callback.run(accountId);
@ -147,12 +141,12 @@ public class AccountRepository extends MinecraftRepository
token.Uuid = uuid.toString();
token.IpAddress = ipAddress;
return new JsonWebCall(_webAddress + "PlayerAccount/Login").ExecuteReturnStream(token);
return handleSyncMSSQLCallStream("PlayerAccount/Login", token);
}
public String getClientByUUID(UUID uuid)
{
return new JsonWebCall(_webAddress + "PlayerAccount/GetAccountByUUID").ExecuteReturnStream(uuid.toString());
return handleSyncMSSQLCallStream("PlayerAccount/GetAccountByUUID", uuid.toString());
}
public UUID getClientUUID(String name)
@ -208,14 +202,10 @@ public class AccountRepository extends MinecraftRepository
executeUpdate(UPDATE_ACCOUNT_RANK, new ColumnVarChar("rank", 100, rank.toString()), new ColumnVarChar("uuid", 100, uuid.toString()));
}
Bukkit.getServer().getScheduler().runTask(getPlugin(), new Runnable()
{
@Override
public void run()
UtilServer.runSync(() ->
{
if (callback != null)
callback.run(response);
}
});
};
@ -224,20 +214,11 @@ public class AccountRepository extends MinecraftRepository
public void matchPlayerName(final Callback<List<String>> callback, final String userName)
{
Thread asyncThread = new Thread(new Runnable()
{
public void run()
{
List<String> tokenList = new JsonWebCall(_webAddress + "PlayerAccount/GetMatches").Execute(new TypeToken<List<String>>(){}.getType(), userName);
callback.run(tokenList);
}
});
asyncThread.start();
handleMSSQLCall("PlayerAccount/GetMatches", userName, new TypeToken<List<String>>(){}.getType(), callback::run);
}
public String getClientByName(String playerName)
{
return new JsonWebCall(_webAddress + "PlayerAccount/GetAccount").ExecuteReturnStream(playerName);
return handleSyncMSSQLCallStream("PlayerAccount/GetAccount", playerName);
}
}

View File

@ -3,11 +3,12 @@ package mineplex.core.antihack.banwave;
import mineplex.core.common.util.Callback;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnLong;
import mineplex.serverdata.database.column.ColumnVarChar;
public class BanWaveRepository extends MinecraftRepository
public class BanWaveRepository extends RepositoryBase
{
private static final String INITIALIZE_PENDING_TABLE = "CREATE TABLE IF NOT EXISTS banwavePending (" +
"accountId INT(11) NOT NULL, " +

View File

@ -6,8 +6,9 @@ import java.sql.SQLException;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
public class AnticheatDatabase extends MinecraftRepository
public class AnticheatDatabase extends RepositoryBase
{
/*
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));

View File

@ -60,7 +60,6 @@ public class AntihackLogger extends MiniPlugin
registerMetadata(new PlayerInfoMetadata());
}
@EventHandler
public void addCommands()
{
if (UtilServer.isTestServer())

View File

@ -28,14 +28,14 @@ public class PartyInfoMetadata extends AnticheatMetadata
@Override
public JsonElement build(UUID player)
{
Party party = require(PartyManager.class).getPlayerParties().get(player);
Party party = require(PartyManager.class).getPartyByPlayer(player);
if (party != null)
{
JsonObject partyData = new JsonObject();
partyData.addProperty(KEY_OWNER, party.getOwner());
partyData.addProperty(KEY_OWNER, party.getOwnerName());
JsonArray members = new JsonArray();
party.getMembers().forEach(m -> members.add(new JsonPrimitive(m)));
party.getMembers().forEach(m -> members.add(new JsonPrimitive(m.getName())));
partyData.add(KEY_MEMBERS, members);

View File

@ -34,13 +34,11 @@ public abstract class PlayerInputActionMenu implements Listener
protected Inventory _currentInventory;
protected String _itemName = "";
protected boolean _searching;
protected Party _party;
public PlayerInputActionMenu(MiniPlugin plugin, Player player, Party party)
public PlayerInputActionMenu(MiniPlugin plugin, Player player)
{
_player = player;
_plugin = plugin;
_party = party;
player.closeInventory();
_plugin.registerEvents(this);
}

View File

@ -11,8 +11,6 @@ import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import static net.minecraft.server.v1_8_R3.PotionBrewer.n;
/**
* A wrapped menu that handles looking for players specifically.
*/
@ -21,9 +19,9 @@ public abstract class PlayerNameMenu extends PlayerInputActionMenu
protected CoreClientManager _clientManager;
public PlayerNameMenu(MiniPlugin plugin, CoreClientManager clientManager, Player player, Party party)
public PlayerNameMenu(MiniPlugin plugin, CoreClientManager clientManager, Player player)
{
super(plugin, player, party);
super(plugin, player);
_clientManager = clientManager;
}

View File

@ -5,12 +5,13 @@ import java.sql.SQLException;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
import org.bukkit.plugin.java.JavaPlugin;
public class BenefitManagerRepository extends MinecraftRepository
public class BenefitManagerRepository extends RepositoryBase
{
private static String CREATE_BENEFIT_TABLE = "CREATE TABLE IF NOT EXISTS rankBenefits (id INT NOT NULL AUTO_INCREMENT, accountId INT, benefit VARCHAR(100), PRIMARY KEY (id), FOREIGN KEY (accountId) REFERENCES accounts(id));";

View File

@ -12,6 +12,7 @@ import mineplex.core.common.Pair;
import mineplex.core.common.util.Callback;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.core.donation.DonationManager;
import mineplex.core.recharge.Recharge;
@ -28,7 +29,7 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
public class BonusRepository extends MinecraftRepository
public class BonusRepository extends RepositoryBase
{
private static String CREATE_BONUS_TABLE = "CREATE TABLE IF NOT EXISTS bonus (accountId INT NOT NULL AUTO_INCREMENT, dailytime TIMESTAMP NULL DEFAULT NULL, ranktime DATE NULL DEFAULT NULL, PRIMARY KEY (accountId), FOREIGN KEY (accountId) REFERENCES accounts(id));";
private BonusManager _manager;

View File

@ -3,13 +3,14 @@ package mineplex.core.boosters.tips;
import mineplex.core.database.MinecraftRepository;
import mineplex.database.routines.CheckAmplifierThank;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import org.bukkit.plugin.java.JavaPlugin;
/**
* @author Shaun Bennett
*/
public class BoosterThankRepository extends MinecraftRepository
public class BoosterThankRepository extends RepositoryBase
{
public BoosterThankRepository(JavaPlugin plugin)
{

View File

@ -9,11 +9,12 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.serverdata.database.DBPool;
import mineplex.core.botspam.SpamText;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
public class BotSpamRepository extends MinecraftRepository
public class BotSpamRepository extends RepositoryBase
{
private static final String GET_SPAM_TEXT = "SELECT * FROM botSpam";
private static final String ADD_SPAM_TEXT = "INSERT INTO botSpam (text, createdBy, enabledBy) VALUES (?, ?, ?)";

View File

@ -5,10 +5,11 @@ import java.util.List;
import mineplex.core.common.Rank;
import mineplex.core.lifetimes.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public interface ICommand
public interface ICommand extends Component
{
void SetCommandCenter(CommandCenter commandCenter);
void Execute(Player caller, String[] args);
@ -21,4 +22,16 @@ public interface ICommand
Rank[] GetSpecificRanks();
List<String> onTabComplete(CommandSender sender, String commandLabel, String[] args);
@Override
default void activate()
{
CommandCenter.Instance.addCommand(this);
}
@Override
default void deactivate()
{
CommandCenter.Instance.removeCommand(this);
}
}

View File

@ -23,11 +23,12 @@ import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.data.PlayerStatus;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnBoolean;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
public class CommunityRepository extends MinecraftRepository
public class CommunityRepository extends RepositoryBase
{
private static final String GET_ALL_COMMUNITIES = "SELECT * FROM communities WHERE region=?;";
private static final String GET_COMMUNITY_BY_ID = "SELECT * FROM communities WHERE id=?;";

View File

@ -1,9 +1,11 @@
package mineplex.core.cosmetic.ui.button.open;
import mineplex.core.cosmetic.ui.page.BalloonsPage;
import org.bukkit.entity.Player;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.cosmetic.ui.page.Menu;
import mineplex.core.gadget.types.Gadget;
import org.bukkit.entity.Player;
public class OpenBalloons extends OpenPageButton
{
@ -16,7 +18,8 @@ public class OpenBalloons extends OpenPageButton
@Override
protected void leftClick(Player player)
{
getMenu().getShop().openPageForPlayer(player, new BalloonsPage(getMenu().getPlugin(), getMenu().getShop(), getMenu().getClientManager(), getMenu().getDonationManager(), "Win Effects", player));
UtilPlayer.message(player, F.main("Balloons", "Coming Soon!"));
//getMenu().getShop().openPageForPlayer(player, new BalloonsPage(getMenu().getPlugin(), getMenu().getShop(), getMenu().getClientManager(), getMenu().getDonationManager(), "Balloons", player));
}
}

View File

@ -31,7 +31,7 @@ public class BalloonsPage extends GadgetPage
{
addGadget(gadget, slot);
if (getPlugin().getGadgetManager().getActive(getPlayer(), GadgetType.BALLOON) == gadget)
if (gadget.isActive(getPlayer()))
addGlow(slot);
slot++;

View File

@ -14,9 +14,11 @@ import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilText;
import mineplex.core.common.util.UtilUI;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.cosmetic.ui.CosmeticShop;
import mineplex.core.cosmetic.ui.button.open.OpenArrowTrails;
import mineplex.core.cosmetic.ui.button.open.OpenBalloons;
import mineplex.core.cosmetic.ui.button.open.OpenCostumes;
import mineplex.core.cosmetic.ui.button.open.OpenDeathAnimations;
import mineplex.core.cosmetic.ui.button.open.OpenDoubleJump;
@ -40,6 +42,11 @@ import mineplex.core.shop.page.ShopPageBase;
public class Menu extends ShopPageBase<CosmeticManager, CosmeticShop>
{
private static final String VISIBILITY_HUB = "Usable in Lobbies";
private static final String VISIBILITY_EVERYWHERE = "Visible Everywhere";
private static final String VISIBILITY_GAMES = "Visible in Games";
public Menu(CosmeticManager plugin, CosmeticShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player)
{
super(plugin, shop, clientManager, donationManager, "Inventory", player);
@ -62,11 +69,11 @@ public class Menu extends ShopPageBase<CosmeticManager, CosmeticShop>
addItem(4, shards);
// Cosmetic Items
// int[] slots = UtilUI.getIndicesFor(12, 2);
int particleSlot = 10;//slots[0];
int arrowSlot = 12;//slots[1];
int jumpSlot = 14;//slots[2];
int deathSlot = 16;//slots[3];
int[] slots = UtilUI.getIndicesFor(15, 1, 5, 1);
/*int particleSlot = 9;//slots[0];
int arrowSlot = 11;//slots[1];
int jumpSlot = 13;//slots[2];
int deathSlot = 15;//slots[3];
int gadgetSlot = 27;//slots[4];
int morphSlot = 29;//slots[5];
int mountSlot = 31;//slots[6];
@ -76,7 +83,12 @@ public class Menu extends ShopPageBase<CosmeticManager, CosmeticShop>
int musicSlot = 47;//slots[10];
int tauntSlot = 49;//slots[11];
int winEffectSlot = 51;
int gameModifierSlot = 53;
int gameModifierSlot = 53;*/
int particleSlot = slots[0], arrowSlot = slots[1], jumpSlot = slots[2],
deathSlot = slots[3], gadgetSlot = slots[4], morphSlot = slots[5],
mountSlot = slots[6], petSlot = slots[7], hatSlot = slots[8],
costumeSlot = slots[9], musicSlot = slots[10], tauntSlot = slots[11],
winEffectSlot = slots[12], gameModifierSlot = slots[13], balloonsSlot = slots[14];
EnumMap<GadgetType, Integer> ownedCount = new EnumMap<GadgetType, Integer>(GadgetType.class);
EnumMap<GadgetType, Integer> maxCount = new EnumMap<GadgetType, Integer>(GadgetType.class);
@ -133,74 +145,79 @@ public class Menu extends ShopPageBase<CosmeticManager, CosmeticShop>
Creature petActive = getPlugin().getPetManager().getPet(getPlayer());
GadgetType type = GadgetType.PARTICLE;
String[] lore = getLore(ownedCount.get(type), maxCount.get(type), "Show everyone how cool you are with swirly particles that follow you when you walk!", "Visible Everywhere", enabled.get(type));
String[] lore = getLore(ownedCount.get(type), maxCount.get(type), "Show everyone how cool you are with swirly particles that follow you when you walk!", VISIBILITY_EVERYWHERE, enabled.get(type));
addButton(particleSlot, new ShopItem(Material.NETHER_STAR, "Particle Effects", lore, 1, false), new OpenParticles(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(particleSlot);
type = GadgetType.ARROW_TRAIL;
lore = getLore(ownedCount.get(type), maxCount.get(type), "Your arrows will now leave particle trails as they soar through the air.", "Visible in Games", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "Your arrows will now leave particle trails as they soar through the air.", VISIBILITY_GAMES, enabled.get(type));
addButton(arrowSlot, new ShopItem(Material.ARROW, "Arrow Effects", lore, 1, false), new OpenArrowTrails(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(arrowSlot);
type = GadgetType.DOUBLE_JUMP;
lore = getLore(ownedCount.get(type), maxCount.get(type), "Demonstrate your parkour prowess with sweet particles when you double jump.", "Visible Everywhere", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "Demonstrate your parkour prowess with sweet particles when you double jump.", VISIBILITY_EVERYWHERE, enabled.get(type));
addButton(jumpSlot, new ShopItem(Material.GOLD_BOOTS, "Double Jump Effects", lore, 1, false), new OpenDoubleJump(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(jumpSlot);
type = GadgetType.DEATH;
lore = getLore(ownedCount.get(type), maxCount.get(type), "Your death will now be mourned with a wonderful particle tribute.", "Visible in Games", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "Your death will now be mourned with a wonderful particle tribute.", VISIBILITY_GAMES, enabled.get(type));
addButton(deathSlot, new ShopItem(Material.SKULL_ITEM, "Death Animations", lore, 1, false), new OpenDeathAnimations(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(deathSlot);
type = GadgetType.ITEM;
lore = getLore(ownedCount.get(type), maxCount.get(type), "All sorts of zany contraptions to use on your friends and foes.", "Usable in Lobbies", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "All sorts of zany contraptions to use on your friends and foes.", VISIBILITY_HUB, enabled.get(type));
addButton(gadgetSlot, new ShopItem(Material.MELON_BLOCK, "Gadgets", lore, 1, false), new OpenGadgets(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(gadgetSlot);
type = GadgetType.MORPH;
lore = getLore(ownedCount.get(type), maxCount.get(type), "Have you ever wanted to be a tiger? Well, you can't be a tiger! That's silly! But you can be many other things!", "Usable in Lobbies", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "Have you ever wanted to be a tiger? Well, you can't be a tiger! That's silly! But you can be many other things!", VISIBILITY_HUB, enabled.get(type));
addButton(morphSlot, new ShopItem(Material.LEATHER, "Morphs", lore, 1, false), new OpenMorphs(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(morphSlot);
lore = getLore(mountOwned, mountMax, "Why walk when you can ride? Summon fancy mounts to help you move in style.", "Usable in Lobbies", mountActive == null ? null : mountActive.getName());
lore = getLore(mountOwned, mountMax, "Why walk when you can ride? Summon fancy mounts to help you move in style.", VISIBILITY_HUB, mountActive == null ? null : mountActive.getName());
addButton(mountSlot, new ShopItem(Material.IRON_BARDING, "Mounts", lore, 1, false), new OpenMounts(this, mountActive));
if (mountActive != null) addGlow(mountSlot);
lore = getLore(petOwned, petMax, "Life on a server can get lonely sometimes. Summon an adorable pet to follow you around and cheer you up!", "Usable in Lobbies", petActive == null ? null : petActive.getCustomName());
lore = getLore(petOwned, petMax, "Life on a server can get lonely sometimes. Summon an adorable pet to follow you around and cheer you up!", VISIBILITY_HUB, petActive == null ? null : petActive.getCustomName());
addButton(petSlot, new ShopItem(Material.BONE, "Pets", lore, 1, false), new OpenPets(this));
if (petActive != null) addGlow(petSlot);
type = GadgetType.HAT;
lore = getLore(ownedCount.get(type), maxCount.get(type), "Hats are in this year. Wear them on your head to impress the ladies.", "Usable in Lobbies", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "Hats are in this year. Wear them on your head to impress the ladies.", VISIBILITY_HUB, enabled.get(type));
addButton(hatSlot, new ShopItem(Material.GOLD_HELMET, "Hats", lore, 1, false), new OpenHats(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(hatSlot);
type = GadgetType.COSTUME;
// Fixes more than 8 costumes being counted, even without the WindUp
lore = getLore((ownedCount.get(type) > 8) ? 8 : ownedCount.get(type), /*maxCount.get(type)*/ 8, "Sometimes going out calls for special clothes! Gain bonus effects for matching outfit.", "Usable in Lobbies", enabled.get(type));
// -4 Fixes more than the real costumes being counted (Happens because of the hub games costumes
lore = getLore(ownedCount.get(type) - 4, maxCount.get(type) - 4, "Sometimes going out calls for special clothes! Gain bonus effects for matching outfit.", VISIBILITY_HUB, enabled.get(type));
addButton(costumeSlot, new ShopItem(Material.DIAMOND_CHESTPLATE, "Costumes", lore, 1, false), new OpenCostumes(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(costumeSlot);
type = GadgetType.MUSIC_DISC;
lore = getLore(ownedCount.get(type), maxCount.get(type), "I JUST WANT TO DANCE WITH YOU!", "Usable in Lobbies", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "I JUST WANT TO DANCE WITH YOU!", VISIBILITY_HUB, enabled.get(type));
addButton(musicSlot, new ShopItem(Material.GREEN_RECORD, "Music", lore, 1, false), new OpenMusic(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(musicSlot);
type = GadgetType.TAUNT;
lore = getLore(ownedCount.get(type), maxCount.get(type), "Taunt your enemies or just show off. Use /taunt to have a good time!", "Visible in Games", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "Taunt your enemies or just show off. Use /taunt to have a good time!", VISIBILITY_GAMES, enabled.get(type));
addButton(tauntSlot, new ShopItem(Material.NAME_TAG, "Taunts", lore, 1, false), new OpenTaunts(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(tauntSlot);
type = GadgetType.WIN_EFFECT;
lore = getLore(ownedCount.get(type), maxCount.get(type), "Winning a game with your friends all good and dandy, but then being able to also show off awesome effects is even more fun!", "Usable in Lobbies", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "Winning a game with your friends all good and dandy, but then being able to also show off awesome effects is even more fun!", VISIBILITY_GAMES, enabled.get(type));
addButton(winEffectSlot, new ShopItem(Material.CAKE, "Win Effects", lore, 1, false), new OpenWinEffect(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(winEffectSlot);
type = GadgetType.GAME_MODIFIER;
lore = getLore(ownedCount.get(type), maxCount.get(type), "Cosmetic effects which changes appearances of objects in game", "Visible in Games", enabled.get(type));
lore = getLore(ownedCount.get(type), maxCount.get(type), "Cosmetic effects which changes appearances of objects in game", VISIBILITY_GAMES, enabled.get(type));
addButton(gameModifierSlot, new ShopItem(Material.TORCH, "Game Modifiers", lore, 1, false), new OpenGameModifiers(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(gameModifierSlot);
type = GadgetType.BALLOON;
lore = getLore(ownedCount.get(type), maxCount.get(type), "Coming Soon...", VISIBILITY_HUB, enabled.get(type));
addButton(balloonsSlot, new ShopItem(Material.LEASH, "Balloons", lore, 1, false), new OpenBalloons(this, enabled.get(type)));
if (enabled.containsKey(type)) addGlow(balloonsSlot);
}
private String[] getLore(int ownedCount, int maxCount, String info, String visibility, Gadget enabled)

View File

@ -14,6 +14,7 @@ import mineplex.core.customdata.CustomData;
import mineplex.core.customdata.CustomDataManager;
import mineplex.core.customdata.PlayerCustomData;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
@ -22,7 +23,7 @@ import mineplex.serverdata.database.column.ColumnVarChar;
* Created by William (WilliamTiger).
* 16/12/15
*/
public class CustomDataRepository extends MinecraftRepository
public class CustomDataRepository extends RepositoryBase
{
private static final String SELECT_KEYS = "SELECT id, name FROM customData;";
private static final String INSERT_KEY = "INSERT INTO customData (name) VALUES (?);";

View File

@ -0,0 +1,131 @@
package mineplex.core.database;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import org.bukkit.scheduler.BukkitTask;
import mineplex.core.common.util.UtilServer;
import mineplex.core.server.remotecall.JsonWebCall;
import mineplex.core.thread.ThreadPool;
import mineplex.core.updater.UpdateType;
import mineplex.core.utils.UtilScheduler;
import mineplex.serverdata.database.DatabaseRunnable;
@Deprecated
public class BasicMSSQLProvider implements MSSQLProvider
{
private final String _webAddress = UtilServer.getWebServerURL();
// Queue for failed processes
private final Object QUEUE_LOCK = new Object();
private Set<DatabaseRunnable> _failedQueue = new HashSet<>();
private final BukkitTask _task;
private volatile boolean _shutdown = false;
public BasicMSSQLProvider()
{
_task = UtilScheduler.runEvery(UpdateType.MIN_01, this::processDatabaseQueue);
}
public <T> T handleSyncMSSQLCall(String uri, Object param, Type responseType)
{
return new JsonWebCall(_webAddress + uri).Execute(responseType, param);
}
public String handleSyncMSSQLCallStream(String uri, Object param)
{
return new JsonWebCall(_webAddress + uri).ExecuteReturnStream(param);
}
public <T> void handleMSSQLCall(String uri, String error, Object param, Class<T> responseType, Consumer<T> consumer)
{
handleDatabaseCall(new DatabaseRunnable(() ->
{
new JsonWebCall(_webAddress + uri).Execute(responseType, consumer::accept, param);
}, error));
}
public <T> void handleMSSQLCall(String uri, Object param, Class<T> responseType, Consumer<T> consumer)
{
handleDatabaseCall(new DatabaseRunnable(() ->
{
new JsonWebCall(_webAddress + uri).Execute(responseType, consumer::accept, param);
}, "Handling MSSQL Call " + uri));
}
public <T> void handleMSSQLCall(String uri, Object param, Type responseType, Consumer<T> consumer)
{
handleDatabaseCall(new DatabaseRunnable(() ->
{
T t = new JsonWebCall(_webAddress + uri).Execute(responseType, param);
consumer.accept(t);
}, "Handling MSSQL Call " + uri));
}
public <T> void handleMSSQLCall(String uri, Object param)
{
handleDatabaseCall(new DatabaseRunnable(() ->
{
new JsonWebCall(_webAddress + uri).Execute(param);
}, "Handling MSSQL Call " + uri));
}
@Override
public void deregister()
{
_shutdown = true;
}
private void handleDatabaseCall(DatabaseRunnable databaseRunnable)
{
ThreadPool.ASYNC.submit(() ->
{
try
{
databaseRunnable.run();
}
catch (Exception exception)
{
processFailedDatabaseCall(databaseRunnable, exception);
}
});
}
private void processFailedDatabaseCall(DatabaseRunnable databaseRunnable, Exception exception)
{
System.err.println(databaseRunnable.getErrorMessage());
exception.printStackTrace();
if (databaseRunnable.getFailedCounts() < 4)
{
databaseRunnable.incrementFailCount();
synchronized (QUEUE_LOCK)
{
_failedQueue.add(databaseRunnable);
}
}
}
private void processDatabaseQueue()
{
Set<DatabaseRunnable> clone;
synchronized (QUEUE_LOCK)
{
clone = new HashSet<>(_failedQueue);
_failedQueue.clear();
}
clone.forEach(this::handleDatabaseCall);
if (_shutdown && _failedQueue.isEmpty())
{
_task.cancel();
}
}
}

View File

@ -0,0 +1,22 @@
package mineplex.core.database;
import java.lang.reflect.Type;
import java.util.function.Consumer;
@Deprecated
public interface MSSQLProvider
{
<T> T handleSyncMSSQLCall(String uri, Object param, Type responseType);
String handleSyncMSSQLCallStream(String uri, Object param);
<T> void handleMSSQLCall(String uri, String error, Object param, Class<T> responseType, Consumer<T> consumer);
<T> void handleMSSQLCall(String uri, Object param, Class<T> responseType, Consumer<T> consumer);
<T> void handleMSSQLCall(String uri, Object param, Type responseType, Consumer<T> consumer);
<T> void handleMSSQLCall(String uri, Object param);
void deregister();
}

View File

@ -1,136 +1,69 @@
package mineplex.core.database;
import java.util.HashSet;
import java.util.Set;
import javax.sql.DataSource;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import javax.rmi.CORBA.Util;
import javax.sql.DataSource;
import mineplex.core.common.util.UtilServer;
import mineplex.core.server.remotecall.AsyncJsonWebCall;
import mineplex.core.server.remotecall.JsonWebCall;
import mineplex.core.thread.ThreadPool;
import mineplex.core.utils.UtilScheduler;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.DatabaseRunnable;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.core.updater.UpdateType;
import org.bukkit.event.Listener;
import org.jooq.DSLContext;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
public abstract class MinecraftRepository extends RepositoryBase implements Listener
{
// Queue for failed processes
private final Object QUEUE_LOCK = new Object();
private Set<DatabaseRunnable> _failedQueue = new HashSet<>();
protected JavaPlugin _plugin; // Plugin responsible for this repository
private final String _webAddress = UtilServer.getWebServerURL();
import mineplex.core.common.util.UtilServer;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
/**
* Constructor
* Do not extend this class unless you are doing MSSQL calls (which you shouldn't be)
*
* @param dataSource - the {@link DataSource} responsible for providing the connection pool to this repository.
* @deprecated don't use mssql thx
*/
@Deprecated
public abstract class MinecraftRepository extends RepositoryBase implements Listener
{
private static AtomicReference<MSSQLProvider> PROVIDER = new AtomicReference<>(new BasicMSSQLProvider());
public static void setMSSQLProvider(MSSQLProvider provider)
{
MSSQLProvider oldProvider = PROVIDER.getAndSet(provider);
oldProvider.deregister();
}
public MinecraftRepository(DataSource dataSource)
{
super(dataSource);
_plugin = UtilServer.getPlugin();
UtilServer.RegisterEvents(this);
UtilScheduler.runEvery(UpdateType.MIN_01, this::processDatabaseQueue);
}
protected DSLContext jooq()
protected <T> T handleSyncMSSQLCall(String uri, Object param, Type responseType)
{
return DSL.using(DBPool.getAccount(), SQLDialect.MYSQL);
return PROVIDER.get().handleSyncMSSQLCall(uri, param, responseType);
}
protected String handleSyncMSSQLCallStream(String uri, Object param)
{
return PROVIDER.get().handleSyncMSSQLCallStream(uri, param);
}
/**
* One day, the stars will align, and we can get rid of this
*/
@Deprecated
protected <T> void handleMSSQLCall(String uri, String error, Object param, Class<T> responseType, Consumer<T> consumer)
{
handleDatabaseCall(new DatabaseRunnable(() ->
{
new JsonWebCall(_webAddress + uri).Execute(responseType, consumer::accept, param);
}, error));
PROVIDER.get().handleMSSQLCall(uri, error, param, responseType, consumer);
}
/**
* One day, the stars will align, and we can get rid of this
*/
@Deprecated
protected <T> void handleAsyncMSSQLCall(String uri, Object param, Class<T> responseType, Consumer<T> consumer)
protected <T> void handleMSSQLCall(String uri, Object param, Class<T> responseType, Consumer<T> consumer)
{
new AsyncJsonWebCall(_webAddress + uri).Execute(responseType, consumer::accept, param);
PROVIDER.get().handleMSSQLCall(uri, param, responseType, consumer);
}
protected <T> void handleMSSQLCall(String uri, Object param, Type responseType, Consumer<T> consumer)
{
PROVIDER.get().handleMSSQLCall(uri, param, responseType, consumer);
}
/**
* One day, the stars will align, and we can get rid of this
*/
@Deprecated
protected <T> void handleAsyncMSSQLCall(String uri, Object param)
{
new AsyncJsonWebCall(_webAddress + uri).Execute(param);
}
private void handleDatabaseCall(DatabaseRunnable databaseRunnable)
{
ThreadPool.ASYNC.submit(() ->
{
try
{
databaseRunnable.run();
}
catch (Exception exception)
{
processFailedDatabaseCall(databaseRunnable, exception);
}
});
}
private void processFailedDatabaseCall(DatabaseRunnable databaseRunnable, Exception exception)
{
System.err.println(databaseRunnable.getErrorMessage());
exception.printStackTrace();
if (databaseRunnable.getFailedCounts() < 4)
{
databaseRunnable.incrementFailCount();
synchronized (QUEUE_LOCK)
{
_failedQueue.add(databaseRunnable);
}
}
}
private void processDatabaseQueue()
{
Set<DatabaseRunnable> clone;
synchronized (QUEUE_LOCK)
{
clone = new HashSet<>(_failedQueue);
_failedQueue.clear();
}
clone.forEach(this::handleDatabaseCall);
}
public JavaPlugin getPlugin()
{
return _plugin;
PROVIDER.get().handleMSSQLCall(uri, param);
}
}

View File

@ -11,13 +11,8 @@ import mineplex.core.database.MinecraftRepository;
import mineplex.core.donation.repository.token.GemRewardToken;
import mineplex.core.donation.repository.token.PurchaseToken;
import mineplex.core.donation.repository.token.UnknownPurchaseToken;
import mineplex.core.server.remotecall.AsyncJsonWebCall;
import mineplex.core.server.remotecall.JsonWebCall;
import mineplex.core.server.util.TransactionResponse;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.DatabaseRunnable;
import org.bukkit.plugin.java.JavaPlugin;
public class DonationRepository extends MinecraftRepository
{

View File

@ -9,10 +9,12 @@ import java.util.LinkedList;
import java.util.List;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnLong;
@ -22,7 +24,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import com.google.common.collect.Lists;
public class EloRepository extends MinecraftRepository
public class EloRepository extends RepositoryBase
{
private static String INSERT_ELO = "INSERT INTO eloRating (accountId, gameType, elo) VALUES (?, ?, ?);";
@ -43,7 +45,7 @@ public class EloRepository extends MinecraftRepository
public boolean saveElo(int accountId, int gameType, int oldElo, int elo) throws SQLException
{
List<Boolean> ret = Lists.newArrayList();
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> {
UtilServer.runAsync(() -> {
boolean updateSucceeded = false;
// If we're increasing in elo we verify the server version matches the database version (prevent d/c and double wins with concurrent matches)
@ -86,7 +88,7 @@ public class EloRepository extends MinecraftRepository
public void getStrikeExpiry(int accountId, Callback<Long> call)
{
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeQuery(GRAB_STRIKE_EXPIRY, resultSet -> {
UtilServer.runAsync(() -> executeQuery(GRAB_STRIKE_EXPIRY, resultSet -> {
boolean called = false;
while (resultSet.next())
{
@ -103,7 +105,7 @@ public class EloRepository extends MinecraftRepository
public void getBanExpiryAsync(int accountId, Callback<Long> call)
{
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeQuery(GRAB_BAN_EXPIRY, resultSet -> {
UtilServer.runAsync(() -> executeQuery(GRAB_BAN_EXPIRY, resultSet -> {
boolean called = false;
while (resultSet.next())
{
@ -136,7 +138,7 @@ public class EloRepository extends MinecraftRepository
public void getStrikes(int accountId, Callback<Integer> call)
{
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeQuery(GRAB_STRIKES, resultSet -> {
UtilServer.runAsync(() -> executeQuery(GRAB_STRIKES, resultSet -> {
boolean called = false;
while (resultSet.next())
{
@ -189,13 +191,13 @@ public class EloRepository extends MinecraftRepository
long strikesExpire = System.currentTimeMillis() + UtilTime.convert(1, TimeUnit.DAYS, TimeUnit.MILLISECONDS);
int newStrikes = Math.min(strikes + 1, 8);
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeUpdate(UPDATE_BAN, new ColumnInt("accountId", accountId), new ColumnInt("strikes", newStrikes), new ColumnLong("strikesExpire", strikesExpire), new ColumnLong("banEnd", banEnd)));
UtilServer.runAsync(() -> executeUpdate(UPDATE_BAN, new ColumnInt("accountId", accountId), new ColumnInt("strikes", newStrikes), new ColumnLong("strikesExpire", strikesExpire), new ColumnLong("banEnd", banEnd)));
});
}
public void resetStrikes(int accountId)
{
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeUpdate(DELETE_STRIKES, new ColumnInt("accountId", accountId)));
UtilServer.runAsync(() -> executeUpdate(DELETE_STRIKES, new ColumnInt("accountId", accountId)));
}
public void getTopElo(int limit, Callback<List<TopEloData>> callback)
@ -255,6 +257,6 @@ public class EloRepository extends MinecraftRepository
}
}
}
}.runTaskAsynchronously(_plugin);
}.runTaskAsynchronously(UtilServer.getPlugin());
}
}

View File

@ -8,11 +8,12 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.util.Callback;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
public class FacebookRepository extends MinecraftRepository
public class FacebookRepository extends RepositoryBase
{
private static final String GET_CODE = "SELECT code, activated FROM facebook WHERE code = ?";
private static final String ACTIVATE_CODE = "UPDATE facebook SET activated = 1, accountId = ?, activationTime = NOW() WHERE code = ?";

View File

@ -15,6 +15,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.util.NautHashMap;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnVarChar;
import mineplex.core.friend.FriendStatusType;
@ -24,7 +25,7 @@ import mineplex.serverdata.data.PlayerStatus;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ServerManager;
public class FriendRepository extends MinecraftRepository
public class FriendRepository extends RepositoryBase
{
private static String CREATE_FRIEND_TABLE = "CREATE TABLE IF NOT EXISTS accountFriend (id INT NOT NULL AUTO_INCREMENT, uuidSource VARCHAR(100), uuidTarget VARCHAR(100), status VARCHAR(100), PRIMARY KEY (id), UNIQUE INDEX uuidIndex (uuidSource, uuidTarget));";
private static String RETRIEVE_MULTIPLE_FRIEND_RECORDS = "SELECT uuidSource, tA.Name, status, tA.lastLogin, now(), uuidTarget FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget WHERE uuidSource IN ";

View File

@ -34,6 +34,7 @@ import mineplex.core.friend.data.FriendData;
import mineplex.core.friend.data.FriendStatus;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.itemstack.ItemLayout;
import mineplex.core.portal.Intent;
import mineplex.core.shop.item.IButton;
public class FriendsGUI implements Listener
@ -302,7 +303,7 @@ public class FriendsGUI implements Listener
@Override
public void onClick(Player player, ClickType clickType)
{
_plugin.getPortal().sendPlayerToServer(player, serverName);
_plugin.getPortal().sendPlayerToServer(player, serverName, Intent.PLAYER_REQUEST);
}
});
}

View File

@ -57,6 +57,7 @@ import mineplex.core.gadget.gadgets.arrowtrail.shadow.ArrowTrailShadow;
import mineplex.core.gadget.gadgets.arrowtrail.titan.ArrowTrailTitan;
import mineplex.core.gadget.gadgets.arrowtrail.vampire.ArrowTrailBlood;
import mineplex.core.gadget.gadgets.arrowtrail.wisdom.ArrowTrailEnchant;
import mineplex.core.gadget.gadgets.balloons.BalloonType;
import mineplex.core.gadget.gadgets.death.candycane.DeathCandyCane;
import mineplex.core.gadget.gadgets.death.christmas.DeathPresentDanger;
import mineplex.core.gadget.gadgets.death.cupidslove.DeathCupidsBrokenHeart;
@ -198,6 +199,7 @@ import mineplex.core.gadget.set.suits.SetFreezeSuit;
import mineplex.core.gadget.set.suits.SetRaveSuit;
import mineplex.core.gadget.set.suits.SetSpaceSuit;
import mineplex.core.gadget.types.ArrowEffectGadget;
import mineplex.core.gadget.types.BalloonGadget;
import mineplex.core.gadget.types.DeathEffectGadget;
import mineplex.core.gadget.types.DoubleJumpEffectGadget;
import mineplex.core.gadget.types.Gadget;
@ -502,7 +504,7 @@ public class GadgetManager extends MiniPlugin
// Game Modifiers
// MineStrike
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.P250_Muertos, -2));
/*addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.P250_Muertos, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.CZ75_Auto_Tigris, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Desert_Eagle_Blaze, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Nova_Koi, -2));
@ -513,6 +515,7 @@ public class GadgetManager extends MiniPlugin
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.AWP_Asiimov, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Knife_M9_Bayonette_Fade, -2));
addGadget(new GameModifierMineStrikeSkin(this, ));
//Blue only
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.P2000_Fire_Elemental, -2));
@ -523,7 +526,11 @@ public class GadgetManager extends MiniPlugin
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Glock_18_Fade, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.Galil_AR_Eco, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.AK_47_Vulcan, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.SG553_Pulse, -2));
addGadget(new GameModifierMineStrikeSkin(this, MineStrikeSkin.SG553_Pulse, -2));*/
for (MineStrikeSkin mineStrikeSkin : MineStrikeSkin.values())
{
addGadget(new GameModifierMineStrikeSkin(this, mineStrikeSkin, -2));
}
// Survival Games
@ -532,8 +539,12 @@ public class GadgetManager extends MiniPlugin
addGadget(new KitGameModifier(this, kitModifier));
}*/
// ONLY NEXT WEEK!
// Balloons
//addGadget(new BabyCowBalloon(this));
/*for (BalloonType balloonType : BalloonType.values())
{
addGadget(new BalloonItem(this, balloonType));
}*/
// TAUNTS!!!
addGadget(new EternalTaunt(this));
@ -710,6 +721,20 @@ public class GadgetManager extends MiniPlugin
return null;
}
public BalloonGadget getBalloonGadget(BalloonType balloonType)
{
for (Gadget gadget : getGadgets(GadgetType.BALLOON))
{
if (gadget instanceof BalloonGadget)
{
BalloonGadget balloonGadget = (BalloonGadget) gadget;
if (balloonGadget.getBalloonType().equals(balloonType))
return balloonGadget;
}
}
return null;
}
// Disallows two armor gadgets in same slot.
public void removeOutfit(Player player, ArmorSlot slot)
{
@ -1322,4 +1347,5 @@ public class GadgetManager extends MiniPlugin
taunt.start(player);
}
}

View File

@ -22,7 +22,7 @@ public class UnlockCosmeticsCommand extends CommandBase<GadgetManager>
public UnlockCosmeticsCommand(GadgetManager plugin)
{
super(plugin, Rank.JNR_DEV, "unlockCosmetics");
super(plugin, Rank.SNR_MODERATOR, "unlockCosmetics");
_plugin = plugin;
}

View File

@ -1,52 +0,0 @@
package mineplex.core.gadget.gadgets.balloons;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.types.BalloonGadget;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.*;
public class BabyCowBalloon extends BalloonGadget
{
private ArmorStand _entityStand, _playerStand;
private Entity _balloonEntity;
public BabyCowBalloon(GadgetManager manager)
{
super(manager, "Baby Cow Balloon", new String[]{"placeholder"}, 0, Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.COW));
}
@Override
public void enableCustom(Player player, boolean message)
{
if (!canSpawnBalloon(player))
{
// TODO MESSAGE
return;
}
addPlayerBalloon(player);
_entityStand = player.getWorld().spawn(player.getLocation(), ArmorStand.class);
_entityStand.setGravity(false);
_entityStand.setVisible(false);
Cow babyCow = player.getWorld().spawn(player.getLocation(), Cow.class);
babyCow.setBaby();
_balloonEntity = babyCow;
_entityStand.setPassenger(babyCow);
Location balloonLocation = player.getLocation().add(_random.nextDouble(), getNewHeight(player), _random.nextDouble());
_entityStand.teleport(balloonLocation);
babyCow.setLeashHolder(player);
// TODO UPDATE BALLOONS
}
@Override
public void disableCustom(Player player, boolean message)
{
_entityStand.remove();
_balloonEntity.remove();
removePlayerBalloon(player);
// TODO UPDATE PLAYER HEIGHT
}
}

View File

@ -0,0 +1,92 @@
package mineplex.core.gadget.gadgets.balloons;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.types.BalloonGadget;
public class BalloonItem extends BalloonGadget
{
private BalloonType _balloonType;
private Map<UUID, List<Entity>> _entities = new HashMap<>();
public BalloonItem(GadgetManager manager, BalloonType balloonType)
{
super(manager, balloonType.getName(), balloonType.getLore(), balloonType.getCost(),
balloonType.getDisplayItem().getType(),
balloonType.getDisplayItem().getData().getData(), balloonType,
balloonType.getEntityType());
setDisplayItem(balloonType.getDisplayItem());
_balloonType = balloonType;
}
@Override
public Entity[] spawnEntity(Player player)
{
Entity[] ents = new Entity[2];
if (_balloonType.getEntityType().equals(EntityType.ARMOR_STAND))
{
Zombie zombie = player.getWorld().spawn(player.getLocation(), Zombie.class);
zombie.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 1, false, false));
zombie.getEquipment().setHelmet(_balloonType.getDisplayItem());
UtilEnt.silence(zombie, true);
UtilEnt.vegetate(zombie);
addEntity(player, zombie);
ents[0] = zombie;
return ents;
}
else if (_balloonType.equals(BalloonType.BABY_ZOMBIE))
{
Zombie zombie = player.getWorld().spawn(player.getLocation(), Zombie.class);
zombie.setBaby(true);
UtilEnt.vegetate(zombie);
addEntity(player, zombie);
ents[0] = zombie;
return ents;
}
Entity entity = player.getWorld().spawnEntity(player.getLocation(), _balloonType.getEntityType());
if (_balloonType.isBaby() && entity instanceof Ageable)
((Ageable) entity).setBaby();
UtilEnt.vegetate(entity);
addEntity(player, entity);
ents[0] = entity;
return ents;
}
private void addEntity(Player player, Entity entity)
{
_entities.computeIfAbsent(player.getUniqueId(), list -> new ArrayList<>());
List<Entity> entities = _entities.get(player.getUniqueId());
entities.add(entity);
_entities.put(player.getUniqueId(), entities);
}
@Override
public void removeEntities(Player player)
{
for (Entity entity : _entities.get(player.getUniqueId()))
{
entity.remove();
}
_entities.remove(player.getUniqueId());
}
}

View File

@ -0,0 +1,95 @@
package mineplex.core.gadget.gadgets.balloons;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilText;
public enum BalloonType
{
// BABY
BABY_COW (EntityType.COW, true, "Baby Cow Balloon", 0, new ItemStack(Material.COOKED_BEEF)),
BABY_PIG (EntityType.PIG, true, "Baby Pig Balloon", 0, new ItemStack(Material.GRILLED_PORK)),
BABY_ZOMBIE (EntityType.ZOMBIE, true, "Baby Zombie Balloon", 0, new ItemStack(Material.ROTTEN_FLESH)),
BABY_MUSHROOM(EntityType.MUSHROOM_COW, true, "Baby Mushroom Cow Balloon", 0, new ItemStack(Material.MUSHROOM_SOUP)),
BABY_OCELOT (EntityType.OCELOT, true, "Baby Ocelot Balloon", 0, new ItemStack(Material.COOKED_FISH)),
BABY_WOLF (EntityType.WOLF, true, "Baby Wolf Balloon", 0, new ItemStack(Material.BONE)),
BABY_SHEEP (EntityType.SHEEP, true, "Baby Sheep Balloon", 0, new ItemStack(Material.WOOL)),
BABY_VILLAGER(EntityType.VILLAGER, true, "Baby Villager Balloon", 0, new ItemStack(Material.EMERALD)),
BABY_SLIME (EntityType.SLIME, true, "Baby Slime Balloon", 0, new ItemStack(Material.SLIME_BALL)),
// NOT BABY
SQUID (EntityType.SQUID, "Squid Balloon", 0, new ItemStack(Material.INK_SACK)),
BAT (EntityType.BAT, "Bat Balloon", 0, new ItemStack(Material.JACK_O_LANTERN)),
SILVERFISH(EntityType.SILVERFISH, "Silverfish Balloon", 0, new ItemStack(Material.getMaterial(97))),
GUARDIAN (EntityType.GUARDIAN, "Guardian Balloon", 0, new ItemStack(Material.PRISMARINE_SHARD)),
// BLOCK
/*DRAGON_EGG (new ItemStack(Material.DRAGON_EGG), false, "Dragon Egg Balloon", UtilText.splitLinesToArray(new String[]{"Placeholder"}, LineFormat.LORE), 0),
DIAMOND_BLOCK(new ItemStack(Material.DIAMOND_BLOCK), false, "Diamond Block Balloon", UtilText.splitLinesToArray(new String[]{"Placeholder"}, LineFormat.LORE), 0),
IRON_BLOCK (new ItemStack(Material.IRON_BLOCK), false, "Iron Block Balloon", UtilText.splitLinesToArray(new String[]{"Placeholder"}, LineFormat.LORE), 0),
GOLD_BLOCK (new ItemStack(Material.GOLD_BLOCK), false, "Gold Block Balloon", UtilText.splitLinesToArray(new String[]{"Placeholder"}, LineFormat.LORE), 0),*/
EMERALD_BLOCK(new ItemStack(Material.EMERALD_BLOCK), false, "Emerald Block Balloon", 0);
private EntityType _entityType;
private boolean _isBaby;
private String _name;
private String[] _lore;
private int _cost;
private ItemStack _displayItem;
BalloonType(EntityType entityType, String name, int cost, ItemStack displayItem)
{
this(entityType, false, name, cost, displayItem);
}
BalloonType(EntityType entityType, boolean isBaby, String name, int cost, ItemStack displayItem)
{
_entityType = entityType;
_isBaby = isBaby;
_name = name;
_cost = cost;
_displayItem = displayItem;
}
BalloonType(ItemStack block, boolean isBaby, String name, int cost)
{
this(EntityType.ARMOR_STAND, isBaby, name, cost, block);
}
public EntityType getEntityType()
{
return _entityType;
}
public boolean isBaby()
{
return _isBaby;
}
public String getName()
{
return _name;
}
public String[] getLore()
{
return UtilText.splitLinesToArray(new String[]{C.cGray + "A floating " + getName() + " that appears above your head!",
"",
C.cWhite + "Click to activate, click again to remove. You can have up to 10 balloons active at a time."}, LineFormat.LORE);
}
public int getCost()
{
return _cost;
}
public ItemStack getDisplayItem()
{
return _displayItem;
}
}

View File

@ -51,7 +51,7 @@ public class GameModifierMineStrikeSkin extends GameModifierGadget
*/
public GameModifierMineStrikeSkin(GadgetManager manager, MineStrikeSkin skin, int cost)
{
this(manager, skin, new String[]{""}, cost);
this(manager, skin, new String[]{skin.getWeaponName()}, cost);
}
/**

View File

@ -8,8 +8,10 @@ public enum MineStrikeSkin
P250_Muertos( "P250", "P250 Muertos", Material.INK_SACK, (byte) 3),
CZ75_Auto_Tigris( "CZ75-Auto", "CZ75-Auto Tigris", Material.CLAY_BRICK, (byte) 0),
Desert_Eagle_Blaze( "Desert Eagle", "Desert Eagle Blaze", Material.NETHER_STALK, (byte) 0),
Desert_Eagle_Golden_Gun( "Desert Eagle", "Golden Gun", Material.GLOWSTONE_DUST, (byte) 0),
Nova_Koi( "Nova", "Nova Koi", Material.INK_SACK, (byte) 14),
XM1014_Tranquility( "XM1014", "XM1014 Tranquility", Material.DIAMOND, (byte) 0),
XM1014_Pig_Gun( "XM1014", "XM1014 Pig Gun", Material.LEATHER, (byte) 0),
PP_Bizon_Streak( "PP Bizon", "PP-Bizon Streak", Material.INK_SACK, (byte) 4),
P90_Asiimov( "P90", "P90 Asiimov", Material.INK_SACK, (byte) 0),
SSG_08_Blood_in_the_Water( "SSG 08", "SSG 08 Blood in the Water", Material.INK_SACK, (byte) 12),
@ -17,13 +19,19 @@ public enum MineStrikeSkin
P2000_Fire_Elemental( "P2000", "P2000 Fire Elemental", Material.INK_SACK, (byte) 6),
FAMAS_Pulse( "FAMAS", "FAMAS Pulse", Material.CLAY_BALL, (byte) 0),
M4A4_Howl( "M4A4", "M4A4 Howl", Material.INK_SACK, (byte) 11),
//M4A4_Enderman( "M4A4", "Enderman M4", )
Steyr_AUG_Torque( "Steyr AUG", "Steyr AUG Torque", Material.BLAZE_ROD, (byte) 0),
Glock_18_Fade( "Glock 18", "Glock 18 Fade", Material.INK_SACK, (byte) 9),
Galil_AR_Eco( "Galil AR", "Galil AR Eco", Material.INK_SACK, (byte) 10),
AK_47_Vulcan( "AK-47", "AK-47 Vulcan", Material.INK_SACK, (byte) 7),
AK_47_Guardian( "AK-47", "Guardian AK", Material.PRISMARINE_SHARD, (byte) 0),
SG553_Pulse( "SG553", "SG553 Pulse", Material.INK_SACK, (byte) 5),
Knife_M9_Bayonette_Fade( "Knife", "M9 Bayonette Fade", Material.DIAMOND_SWORD, (byte) 0);
Knife_M9_Bayonette_Fade( "Knife", "M9 Bayonette Fade", Material.DIAMOND_SWORD, (byte) 0),
Knife_Counter_Terrorist_Sword("Knife", "Counter Terrorist Sword", Material.STICK, (byte) 0),
Knife_Terrorist_Sword( "Knife", "Terrorist Sword", Material.FEATHER, (byte) 0),
Knife_M9_Bayonette_Glass( "Knife", "Glass M9 Bayonette", Material.QUARTZ, (byte) 0);

View File

@ -51,7 +51,7 @@ public class ItemFootball extends ItemGadget
FallingBlock ball = player.getWorld().spawnFallingBlock(player.getLocation().add(0, 1, 0), Material.SKULL, (byte) 3);
Bat bat = player.getWorld().spawn(player.getLocation(), Bat.class);
UtilEnt.Vegetate(bat);
UtilEnt.vegetate(bat);
UtilEnt.ghost(bat, true, true);
UtilEnt.silence(bat, true);

View File

@ -134,7 +134,7 @@ public class WinEffectHalloween extends WinEffectGadget
skeleton.setCustomNameVisible(true);
skeleton.getEquipment().setHelmet(new ItemStack(Material.JACK_O_LANTERN));
UtilEnt.ghost(skeleton, true, false);
UtilEnt.Vegetate(skeleton);
UtilEnt.vegetate(skeleton);
for (int i = 0; i < 15; i++)
{
playFirework(skeleton.getLocation().clone().add(0, 2, 0), i, true);

View File

@ -1,64 +1,138 @@
package mineplex.core.gadget.types;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import mineplex.core.gadget.GadgetManager;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.balloons.BalloonType;
import mineplex.core.gadget.util.BalloonData;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
public abstract class BalloonGadget extends Gadget
{
protected static final Map<UUID, List<BalloonGadget>> PLAYER_BALLOONS = new HashMap<>();
private static final Map<UUID, Map<EntityType, BalloonData>> PLAYER_BALLOONS = new HashMap<>();
protected final Random _random;
private EntityType _balloon;
private BalloonType _balloonType;
public BalloonGadget(GadgetManager manager, String name, String[] desc, int cost, Material material, byte data, String... altNames)
public BalloonGadget(GadgetManager manager, String name, String[] desc, int cost, Material material, byte data, BalloonType balloonType, EntityType balloon, String... altNames)
{
super(manager, GadgetType.BALLOON, name, desc, cost, material, data, 1, altNames);
_random = new Random();
_balloon = balloon;
_balloonType = balloonType;
}
protected boolean canSpawnBalloon(Player player)
@Override
public void enableCustom(Player player, boolean message)
{
boolean add = addPlayerBalloon(player);
if (add)
{
_active.add(player);
if (message)
{
UtilPlayer.message(player, F.main("Gadget", "You spawned a " + F.elem(getName()) + "!"));
}
}
else
{
Manager.removeActive(player, this);
UtilPlayer.message(player, F.main("Gadget", "You cannot have more than " + F.count("10") + " balloons!"));
}
}
@Override
public void disableCustom(Player player, boolean message)
{
if (!_active.remove(player))
return;
removePlayerBalloon(player);
if (message)
UtilPlayer.message(player, F.main("Gadget", "You despawned a " + F.elem(getName())) + "!");
}
private boolean addPlayerBalloon(Player player)
{
if (!canSpawnBalloon(player))
return false;
PLAYER_BALLOONS.computeIfAbsent(player.getUniqueId(), map -> new HashMap<>());
BalloonData balloonData;
Entity[] ents = spawnEntity(player);
if (ents[1] == null)
balloonData = new BalloonData(player, ents[0]);
else if (!_balloon.equals(EntityType.ARMOR_STAND))
balloonData = new BalloonData(player, ents[0], ents[1]);
else
{
balloonData = new BalloonData(player, ents[0]);
balloonData.setLeash(ents[1]);
}
PLAYER_BALLOONS.get(player.getUniqueId()).put(_balloon, balloonData);
return true;
}
private void removePlayerBalloon(Player player)
{
if (PLAYER_BALLOONS.containsKey(player.getUniqueId()))
{
List<BalloonGadget> balloonGadgets = PLAYER_BALLOONS.get(player.getUniqueId());
if (PLAYER_BALLOONS.get(player.getUniqueId()).containsKey(_balloon))
{
removeEntities(player);
PLAYER_BALLOONS.get(player.getUniqueId()).remove(_balloon);
}
}
}
protected abstract Entity[] spawnEntity(Player player);
protected abstract void removeEntities(Player player);
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
for (Map.Entry<UUID, Map<EntityType, BalloonData>> entry : PLAYER_BALLOONS.entrySet())
{
for (BalloonData balloonData : entry.getValue().values())
{
balloonData.update();
}
}
}
private boolean canSpawnBalloon(Player player)
{
if (PLAYER_BALLOONS.containsKey(player.getUniqueId()))
{
Map<EntityType, BalloonData> balloonGadgets = PLAYER_BALLOONS.get(player.getUniqueId());
return balloonGadgets.size() < 10;
}
return true;
}
protected void addPlayerBalloon(Player player)
public BalloonType getBalloonType()
{
if (canSpawnBalloon(player))
{
PLAYER_BALLOONS.computeIfAbsent(player.getUniqueId(), list -> new ArrayList<>());
List<BalloonGadget> balloonGadgets = PLAYER_BALLOONS.get(player.getUniqueId());
balloonGadgets.add(this);
PLAYER_BALLOONS.put(player.getUniqueId(), balloonGadgets);
}
return _balloonType;
}
protected void removePlayerBalloon(Player player)
public static int getBalloons(Player player)
{
List<BalloonGadget> balloonGadgets = PLAYER_BALLOONS.computeIfPresent(player.getUniqueId(), (uuid, list) -> list);
if (balloonGadgets.contains(this))
{
balloonGadgets.remove(this);
return ((PLAYER_BALLOONS.containsKey(player.getUniqueId())) ? PLAYER_BALLOONS.get(player.getUniqueId()).size() : 0);
}
if (balloonGadgets.size() >= 1)
PLAYER_BALLOONS.put(player.getUniqueId(), balloonGadgets);
else
PLAYER_BALLOONS.remove(player.getUniqueId());
}
protected double getNewHeight(Player player)
{
List<BalloonGadget> balloonGadgets = PLAYER_BALLOONS.computeIfPresent(player.getUniqueId(), (uuid, list) -> list);
if (balloonGadgets != null)
return balloonGadgets.size() * _random.nextDouble() * (_random.nextInt(1) + 2);
return 3;
}
}

View File

@ -0,0 +1,133 @@
package mineplex.core.gadget.util;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
public class BalloonData
{
/**
* Makes the balloons fly around the player
* Copied from {@link mineplex.core.gadget.gadgets.particle.ParticleFairyData}
*/
private Player _player;
private Entity _balloon, _passenger, _leash;
private Location _balloonLoc, _target;
private Vector _direction;
private double _speed;
private long _idleTime;
public BalloonData(Player player, Entity balloon)
{
_player = player;
_balloon = balloon;
_balloonLoc = player.getEyeLocation();
_target = getNewTarget();
_speed = 0.2;
_idleTime = 0;
_direction = new Vector(1, 0, 0);
((LivingEntity) _balloon).setLeashHolder(_player);
}
// This exists for a possible widder balloon that could be added later
public BalloonData(Player player, Entity balloon, Entity passenger)
{
_player = player;
_balloon = balloon;
_passenger = passenger;
_balloonLoc = player.getEyeLocation();
_target = getNewTarget();
_speed = 0.2;
_idleTime = 0;
_direction = new Vector(1, 0, 0);
((LivingEntity) _balloon).setLeashHolder(_player);
}
public void update()
{
if (_leash == null)
{
if (!((LivingEntity) _balloon).isLeashed())
((LivingEntity) _balloon).setLeashHolder(_player);
}
else
{
if (!((LivingEntity) _leash).isLeashed())
((LivingEntity) _leash).setLeashHolder(_player);
}
//Update Target
if (UtilMath.offset(_player.getEyeLocation(), _target) > 3 || UtilMath.offset(_balloonLoc, _target) < 1)
_target = getNewTarget();
//Pause?
if (Math.random() > 0.98)
_idleTime = System.currentTimeMillis() + (long)(Math.random() * 3000);
//Speed
if (UtilMath.offset(_player.getEyeLocation(), _balloonLoc) < 3)
{
if (_idleTime > System.currentTimeMillis())
{
_speed = Math.max(0, _speed - 0.005);
}
else
{
_speed = Math.min(0.15, _speed + 0.005);
}
}
else
{
_idleTime = 0;
_speed = Math.min(0.15 + UtilMath.offset(_player.getEyeLocation(), _balloonLoc) * 0.05, _speed + 0.02);
}
//Modify Direction
_direction.add(UtilAlg.getTrajectory(_balloonLoc, _target).multiply(0.15));
if (_direction.length() < 1)
_speed = _speed * _direction.length();
UtilAlg.Normalize(_direction);
//Move
if (UtilMath.offset(_balloonLoc, _target) > 0.1)
_balloonLoc.add(_direction.clone().multiply(_speed));
_balloon.teleport(_balloonLoc);
_balloon.setVelocity(new Vector(0, .25, 0));
if (_passenger != null)
{
_passenger.teleport(_balloonLoc);
_balloon.setPassenger(_passenger);
}
if (_leash != null)
{
_leash.teleport(_balloon.getLocation().add(0, 1.5, 0));
}
}
private Location getNewTarget()
{
return _player.getEyeLocation().add(Math.random() * 6 - 3, Math.random() * 7.5, Math.random() * 6 - 3);
}
public Entity getBalloon()
{
return _balloon;
}
public void setLeash(Entity leashedEntity)
{
_leash = leashedEntity;
((LivingEntity) _leash).setLeashHolder(_player);
}
}

View File

@ -97,6 +97,8 @@ public enum GameDisplay
QuiverPayload("One in the Quiver Payload", Material.ARROW, (byte)0, GameCategory.ARCADE, 64, false),
StrikeGames("Strike Games", Material.DIAMOND_LEGGINGS, (byte) 0, GameCategory.SURVIVAL, 66, false),
Event("Mineplex Event", Material.CAKE, (byte)0, GameCategory.EVENT, 999, false),
Brawl("Brawl", Material.DIAMOND, (byte) 0, GameCategory.EVENT, 998, false);

View File

@ -12,12 +12,13 @@ import mineplex.core.database.MinecraftRepository;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
import mineplex.serverdata.Region;
public class GiveawayRepository extends MinecraftRepository
public class GiveawayRepository extends RepositoryBase
{
private static final String INSERT_GIVEAWAY = "INSERT INTO Account.accountGiveaway (giveawayId, accountId, cooldownId, region, serverName, time, uuid) VALUES (?, ?, ?, ?, ?, now(), ?)";
private static final String LOAD_GIVEAWAY = "SELECT id, name, prettyName, header, message, max, notifyNetwork, notifyCooldown, canWinTwice FROM Account.giveaway WHERE enabled = TRUE";

View File

@ -5,12 +5,13 @@ import java.sql.SQLException;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnVarChar;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
public class IgnoreRepository extends MinecraftRepository
public class IgnoreRepository extends RepositoryBase
{
private static String ADD_IGNORE_RECORD = "INSERT INTO accountIgnore (uuidIgnorer, uuidIgnored) SELECT fA.uuid AS uuidIgnorer, tA.uuid AS uuidIgnored FROM accounts as fA LEFT JOIN accounts AS tA ON tA.name = ? WHERE fA.name = ?;";
private static String DELETE_IGNORE_RECORD = "DELETE aF FROM accountIgnore AS aF INNER JOIN accounts as fA ON aF.uuidIgnorer = fA.uuid INNER JOIN accounts AS tA ON aF.uuidIgnored = tA.uuid WHERE fA.name = ? AND tA.name = ?;";

View File

@ -3,9 +3,10 @@ package mineplex.core.incognito.repository;
import mineplex.core.database.MinecraftRepository;
import mineplex.core.incognito.IncognitoManager;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
public class IncognitoRepository extends MinecraftRepository
public class IncognitoRepository extends RepositoryBase
{
private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS incognitoStaff (accountId INT NOT NULL, status TINYINT(1) DEFAULT '0', PRIMARY KEY (accountId));";
private static final String INSERT_STATUS = "INSERT INTO incognitoStaff (accountId, status) VALUES (?, ?);";

View File

@ -10,13 +10,14 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.util.NautHashMap;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
import mineplex.core.inventory.ClientInventory;
import mineplex.core.inventory.ClientItem;
public class InventoryRepository extends MinecraftRepository
public class InventoryRepository extends RepositoryBase
{
private static String CREATE_INVENTORY_TABLE = "CREATE TABLE IF NOT EXISTS items (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(100), rarity INT, PRIMARY KEY (id), INDEX mameIndex (name));";
private static String CREATE_INVENTORY_RELATION_TABLE = "CREATE TABLE IF NOT EXISTS accountInventory (id INT NOT NULL AUTO_INCREMENT, accountId INT NOT NULL, itemId INT NOT NULL, count INT NOT NULL, PRIMARY KEY (id), FOREIGN KEY (accountId) REFERENCES accounts(id), FOREIGN KEY (itemId) REFERENCES items(id), UNIQUE INDEX accountItemIndex (accountId, itemId));";

View File

@ -2,6 +2,7 @@ package mineplex.core.leaderboard;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
@ -15,7 +16,7 @@ import org.bukkit.plugin.java.JavaPlugin;
* @author MrTwiggy
*
*/
public class StatEventsRepository extends MinecraftRepository
public class StatEventsRepository extends RepositoryBase
{
// Insert or update stat events query

View File

@ -0,0 +1,21 @@
package mineplex.core.lifetimes;
/**
* A Component defines behavior that can exist within a Lifetime. Components
* should have no impact upon the game while not active.
*/
public interface Component
{
/**
* Activates the Component, performing any sort of required initialization.
* Components may be activated and deactivated multiple times, however a component
* will not be activated more than once without subsequent calls to deactivate.
*/
void activate();
/**
* Deactivates the Component, disabling any sort of functionality it provides
* and performing clean up. A Component may be subsequently reactivated.
*/
void deactivate();
}

View File

@ -0,0 +1,29 @@
package mineplex.core.lifetimes;
/**
* A Lifetime represents a duration for which a collection of Components
* will be active. While Lifetime does contain a method for registering
* instantiated Components, individual Lifetimes may have unique
* strategies for creating Components and activating them. Lifetime
* doesn't provide any guarantee of Component activation or deactivation
* order. Implementations of Lifetime, however, may.
* <p />
* Lifetime doesn't provide mechanisms for beginning or ending a Lifetime.
* This is provided by the various implementations of Lifetime, as it varies
* between the implementations and is functionality that most consumers of
* Lifetimes will not need.
*/
public interface Lifetime
{
/**
* Registers the provided component with this Lifetime. If the Lifetime
* is currently active, then the Component will be immediately activated.
* @param component the component to register
*/
void register(Component component);
/**
* Gets whether the Lifetime is currently active.
* @return true if the Lifetime is active
*/
boolean isActive();
}

View File

@ -0,0 +1,19 @@
package mineplex.core.lifetimes;
/**
* Represents an object that is associated with a specific lifetime.
* Multiple Lifetimed objects may be associated with the same Lifetime.
* As a roughly generalized explanation, any time functionality should
* be enabled(whether its a command, listener, etc.) it should be registered
* as a Component of a Lifetime. Any object wishing to enable functionality
* that is associated with this Lifetimed object should do so with the Lifetime
* returned by {@link #getLifetime()}.
*/
public interface Lifetimed
{
/**
* Gets the Lifetime associated with this Lifetimed object.
* @return non-null Lifetime
*/
Lifetime getLifetime();
}

View File

@ -0,0 +1,54 @@
package mineplex.core.lifetimes;
import mineplex.core.common.util.UtilServer;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
/**
* A convenience class for Components that are a Listener. ListenerComponent
* can either be used as a wrapper class for a specific Listener, or can be
* extended by another Component to provide event registration.
*/
public class ListenerComponent implements Component, Listener
{
private final Listener _listener;
/**
* Creates a ListenerComponent that registers the provided Listener when
* activated and unregisters it when deactivated. The newly created
* ListenerComponent will not be registered as a Listener. When a
* ListenerComponent is created with this constructor, it is effectively
* a wrapper to bind a Listener to a specific lifetime.
*
* @param listener non-null listener to wrap
* @throws IllegalArgumentException if listener is null
*/
public ListenerComponent(Listener listener) throws IllegalArgumentException
{
Validate.notNull(listener);
_listener = listener;
}
/**
* Creates a ListenerComponent that registers itself when activated and
* unregisters itself when deactivated.
*/
public ListenerComponent()
{
_listener = this;
}
@Override
public void activate()
{
Bukkit.getPluginManager().registerEvents(_listener, UtilServer.getPlugin());
}
@Override
public void deactivate()
{
HandlerList.unregisterAll(_listener);
}
}

View File

@ -0,0 +1,7 @@
package mineplex.core.lifetimes;
public interface PhasedComponent<T> extends Component
{
void setPhase(T phase);
}

View File

@ -0,0 +1,289 @@
package mineplex.core.lifetimes;
import com.google.common.base.Preconditions;
import mineplex.core.common.util.UtilServer;
import org.apache.commons.lang.Validate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* A PhasedLifetime is a lifetime that is composed of several
* smaller lifetimes, referred to as phases. This class is provided
* in order to support a system in which Components may exist within multiple
* Lifetimes. PhasedLifetime is not thread-safe.
* <p />
* Registering a Component will register it for the entirety of this Lifetime,
* unless registered with {@link #register(Component, Iterable)}. Special behavior
* is provided for instances of {@link PhasedComponent}. See {@link #register(Component,
* Iterable)} for more information. Components registered using {@link
* #register(Component)} are registered for the entire duration of the Lifetime.
*/
public class PhasedLifetime<T> implements Lifetime
{
private final Map<T, List<RegisteredComponent>> _phases = new HashMap<>();
private final List<Component> _global = new ArrayList<>();
private boolean _active = false;
private T _current;
/**
* Registers the Component for all phases within the provided Iterable,
* and creates a Lifetime that is active during all those phases, and
* therefore identical to when the provided Component is active. If a change
* occurs from a Phase that the Component is active in to another phase that
* the component is active in, it will not be disabled. When this
* Lifetime ends, all Lifetimes created by this Lifetime also end, as all
* phases are considered over.
* <p />
* If the Component is an instance of PhasedComponent, then any phase change
* in which one of the phases is within the provided Iterable of phases will
* result in an invocation of {@link PhasedComponent#setPhase(Object)}. This
* should not be used as a mechanism to detect when the component is being
* disabled, but rather as a means to provide specific behavior when that
* phase change occurs. If a phase change drastically changes the behavior
* of a Component such that not all functionality is active for some phases
* that a Component is registered for, you should consider refactoring that
* Component into two separate Components.
* <p />
* As an example, assume that we have a PhasedLifetime with phases A-F,
* and a PhasedComponent is registered for phases A, B, and E. The chain
* of events would be as followed(italic indicates an event call to the
* PhasedComponent, an activation, or deactivation).
* <ul>
* <li>Lifetime started with a value of A</li>
* <li><i>Component is activated</i></li>
* <li><i>setPhase is called with a value of A</i></li>
* <li>Phase is set to B</li>
* <li><i>setPhase is called with a value of B</i></li>
* <li>Phase is set to C</li>
* <li><i>setPhase is called with a value of C</i></li>
* <li><i>Component is deactivated</i></li>
* <li>Phase is set to D</li>
* <li>Phase is set to E</li>
* <li><i>Component is activated</i></li>
* <li><i>setPhase is called with a value of E</i></li>
* <li>Phase is set to F</li>
* <li><i>setPhase is called with a value of F</i></li>
* <li><i>Component is deactivated</i></li>
* <li>Lifetime ends</li>
* </ul>
* <p />
* If phases contains no elements, then the Component will not be
* registered.
* @param component non-null Component being registered
* @param phases non-null Iterable of phases to register the Component for
* @return a Lifetime corresponding to when the Component is active
* @throws IllegalArgumentException if component or phases is null
*/
public Lifetime register(Component component, Iterable<T> phases) throws IllegalArgumentException {
Validate.notNull(component, "Component cannot be null");
Validate.notNull(phases, "Phases cannot be null");
RegisteredComponent rComponent = new RegisteredComponent(component);
for (T phase : phases)
{
_phases.computeIfAbsent(phase, (p) -> new ArrayList<>()).add(rComponent);
if (Objects.equals(phase, _current))
{
rComponent.start();
if (component instanceof PhasedComponent)
{
((PhasedComponent<T>) component).setPhase(phase);
}
}
}
return rComponent;
}
/**
* Starts the Lifetime, activating all components that are active for
* the entire lifetime, and then activating all components that are part
* of the provided phase.
* @param phase non-null phase to start
* @throws IllegalArgumentException if phase is null
* @throws IllegalStateException if the Lifetime is currently active
*/
public void start(T phase) throws IllegalArgumentException, IllegalStateException
{
Validate.notNull(phase, "phase cannot be null");
Preconditions.checkState(!_active, "Lifetime already started");
_active = true;
_global.forEach(PhasedLifetime::active);
setPhase(phase);
}
/**
* Ends the Lifetime, deactivating all components in the current phase
* and then deactivating all components that are active for the entire Lifetime.
* A Lifetime may be subsequently reactivated after it has ended.
* @throws IllegalStateException if the lifetime isn't active
*/
public void end() throws IllegalStateException
{
Preconditions.checkState(_active, "Lifetime not active");
List<RegisteredComponent> toDisable = _phases.get(getPhase());
if (toDisable != null)
{
toDisable.forEach(RegisteredComponent::end);
}
_global.forEach(PhasedLifetime::deactive);
_active = false;
_current = null;
}
/**
* Sets the current phase to the provided value, activating components
* that are active in the phase and not currently active, and deactiving
* components that were previously active and are not registered for the
* provided phase.
* @param phase non-null
* @throws IllegalStateException if the Lifetime isn't active
* @throws IllegalArgumentException if the phase equals the current phase
* or is null
*/
public void setPhase(T phase) throws IllegalStateException, IllegalArgumentException
{
Preconditions.checkState(_active, "Lifetime not active");
Validate.isTrue(!Objects.equals(phase, _current), "Can't set the phase to the current phase");
Validate.notNull(phase, "the phase cannot be null");
T oldPhase = getPhase();
_current = phase;
List<RegisteredComponent> old = _phases.get(oldPhase);
List<RegisteredComponent> nextPhase = _phases.get(phase);
for (Component c : _global)
{
if (c instanceof PhasedComponent)
{
((PhasedComponent<T>) c).setPhase(phase);
}
}
// Disable components that were active in the last phase but not in the next phase.
if (old != null)
{
List<RegisteredComponent> toDisable = new ArrayList<>();
toDisable.addAll(old);
// Components that are in the next phase shouldn't be disabled.
if (nextPhase != null)
{
toDisable.removeAll(nextPhase);
}
// Ensure that all old ones get a setPhase call before disabling them.
for (RegisteredComponent r : toDisable)
{
if (r.getComponent() instanceof PhasedComponent)
{
((PhasedComponent<T>) r.getComponent()).setPhase(phase);
}
}
toDisable.forEach(RegisteredComponent::end);
}
if (nextPhase != null)
{
// New but not old
List<RegisteredComponent> toActivate = new ArrayList<>();
toActivate.addAll(nextPhase);
// Ensure that all components from last phase don't end up getting activated again.
if (old != null)
{
toActivate.removeAll(old);
}
// Start all the new ones
toActivate.forEach(RegisteredComponent::start);
// Give every remaining component a call to setPhase
for (RegisteredComponent r : nextPhase)
{
if (r.getComponent() instanceof PhasedComponent)
{
((PhasedComponent<T>) r.getComponent()).setPhase(phase);
}
}
}
}
private static void active(Component component)
{
try
{
component.activate();
} catch (Exception e)
{
e.printStackTrace();
UtilServer.getPlugin().getLogger().severe("Failed to activate component: " + component);
}
}
private static void deactive(Component component)
{
try
{
component.deactivate();
} catch (Exception e)
{
e.printStackTrace();
UtilServer.getPlugin().getLogger().severe("Failed to deactivate component: " + component);
}
}
/**
* Gets the current Phase. If this PhasedLifetime isn't active then
* the current phase is null.
* @return the current phase, null if not active
*/
public T getPhase()
{
return _current;
}
/**
* {@inheritDoc}
* If the Component is an instance of PhasedComponent, it will receive
* notifications of phase changes prior to any components registered
* with specific phases. Global components will also be deactivated last.
* @param component the component to register
*/
@Override
public void register(Component component)
{
_global.add(component);
if (this.isActive())
{
component.activate();
}
}
@Override
public boolean isActive()
{
return _active;
}
private static class RegisteredComponent extends SimpleLifetime implements Lifetime {
private Component _component;
public RegisteredComponent(Component component)
{
this._component = component;
}
public Component getComponent()
{
return _component;
}
@Override
public void start() throws IllegalStateException
{
PhasedLifetime.active(_component);
super.start();
}
@Override
public void end() throws IllegalStateException
{
super.end();
PhasedLifetime.deactive(_component);
}
}
}

View File

@ -0,0 +1,96 @@
package mineplex.core.lifetimes;
import mineplex.core.common.util.UtilServer;
import org.apache.commons.lang3.Validate;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
/**
* A Lifetime that is not thread-safe and is essentially a list of Components.
* All components are activated in the order that they are registered. All
* components are deactivated in the reverse order that they are registered.
* Components may not be registered during invocations of start or end. If a
* Component throws an exception during activation it will be logged, however the
* Component will still only be disabled once all other Components are disabled.
*/
public class SimpleLifetime implements Lifetime
{
protected final List<Component> _components = new ArrayList<>();
protected boolean _active = false;
@Override
public void register(Component component)
{
this._components.add(component);
if (this.isActive())
{
try
{
component.activate();
} catch (Exception e)
{
e.printStackTrace();
UtilServer.getPlugin().getLogger().severe("Failed to active component: " + component);
}
}
}
@Override
public boolean isActive()
{
return _active;
}
/**
* Starts the SimpleLifetime, activating all components in the order that
* they were registered. A SimpleLifetime may be started multiple times,
* so long that every invocation of start after the first is preceded by
* an invocation of {@link #end()}. If a Component throws an exception
* during activation the exception will be logged, however no specific
* error-handling mechanism is provided. The Component will still be
* considered active and will be deactivated with all other Components.
* @throws IllegalStateException if currently active
*/
public void start() throws IllegalStateException
{
Validate.isTrue(!_active);
_active = true;
for (Component component : _components)
{
try
{
component.activate();
} catch (Exception e)
{
e.printStackTrace();
UtilServer.getPlugin().getLogger().severe("Failed to active component: " + component);
}
}
}
/**
* Deactivates all components in the reverse order that they were registered.
* Any exception thrown by a Component while being deactivated will be logged,
* however no exception handling mechanism is provided.
* @throws IllegalStateException if not currently active
*/
public void end() throws IllegalStateException
{
Validate.isTrue(_active);
_active = false;
ListIterator<Component> reverseIterator = _components.listIterator(_components.size());
while (reverseIterator.hasPrevious())
{
Component component = reverseIterator.previous();
try
{
component.deactivate();
} catch (Exception e)
{
e.printStackTrace();
UtilServer.getPlugin().getLogger().severe("Failed to deactivate component: " + component);
}
}
}
}

View File

@ -86,7 +86,7 @@ public class DisplaySlot
}
else
{
UtilEnt.Vegetate(e, true);
UtilEnt.vegetate(e, true);
UtilEnt.ghost(e, true, false);
}
_pastedEntities.add(e);

View File

@ -0,0 +1,28 @@
package mineplex.core.menu.builtin;
import java.util.function.Supplier;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniPlugin;
import mineplex.core.menu.Button;
import mineplex.core.menu.Menu;
public abstract class ButtonOpenAnvilInput<T extends MiniPlugin> extends Button<T>
{
private final Supplier<Menu<T>> _menuSupplier;
public ButtonOpenAnvilInput(T plugin, ItemStack item, Supplier<Menu<T>> menu)
{
super(item, plugin);
_menuSupplier = menu;
}
@Override
public void onClick(Player player, ClickType clickType)
{
_menuSupplier.get().open(player);
}
}

View File

@ -0,0 +1,28 @@
package mineplex.core.menu.builtin;
import java.util.function.Supplier;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniPlugin;
import mineplex.core.menu.Button;
import mineplex.core.menu.Menu;
public class ButtonOpenInventory<T extends MiniPlugin> extends Button<T>
{
private final Supplier<Menu<T>> _menuSupplier;
public ButtonOpenInventory(ItemStack item, T plugin, Supplier<Menu<T>> menu)
{
super(item, plugin);
_menuSupplier = menu;
}
@Override
public void onClick(Player player, ClickType clickType)
{
_menuSupplier.get().open(player);
}
}

View File

@ -44,7 +44,7 @@ public class DragonData extends MountData
//Spawn Dragon
Dragon = rider.getWorld().spawn(rider.getLocation(), EnderDragon.class);
UtilEnt.Vegetate(Dragon);
UtilEnt.vegetate(Dragon);
UtilEnt.ghost(Dragon, true, false);
rider.getWorld().playSound(rider.getLocation(), Sound.ENDERDRAGON_GROWL, 20f, 1f);

View File

@ -341,7 +341,7 @@ public class NpcManager extends MiniPlugin
if (npc.getDatabaseRecord().getRadius() == 0)
{
UtilEnt.Vegetate(entity);
UtilEnt.vegetate(entity);
UtilEnt.silence(entity, true);
UtilEnt.ghost(entity, true, false);
@ -604,7 +604,7 @@ public class NpcManager extends MiniPlugin
if (npc.getDatabaseRecord().getRadius() == 0)
{
UtilEnt.Vegetate(entity);
UtilEnt.vegetate(entity);
UtilEnt.ghost(entity, true, false);
}
}

View File

@ -1,27 +1,59 @@
package mineplex.core.party;
import java.util.UUID;
/**
* Serializable invite data
*/
public class InviteData
{
private final String _inviterName;
private final UUID _inviterUUID;
private final UUID _partyUUID;
private final String _serverName;
private String _invitedTo;
private String _serverFrom;
public InviteData(String invitedTo, String serverFrom)
public InviteData(String inviterName, UUID inviterUUID, UUID partyUUID, String serverName)
{
_invitedTo = invitedTo;
_serverFrom = serverFrom;
_inviterName = inviterName;
_inviterUUID = inviterUUID;
_partyUUID = partyUUID;
_serverName = serverName;
}
public String getInvitedTo()
public String getInviterName()
{
return _invitedTo;
return _inviterName;
}
public String getServerFrom()
public UUID getInviterUUID()
{
return _serverFrom;
return _inviterUUID;
}
public UUID getPartyUUID()
{
return _partyUUID;
}
public String getServerName()
{
return _serverName;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InviteData that = (InviteData) o;
return _partyUUID.equals(that._partyUUID);
}
@Override
public int hashCode()
{
return _partyUUID.hashCode();
}
}

View File

@ -16,7 +16,6 @@ public enum Lang
SUCCESS_SERVER_CONNECT("Sending you and your party to {0}..."),
INVITE_SUCCESS_PLAYER("Successfully invited {0} to the party."),
SUCCESS_INVITE("{0} has invited {1} to the party."),
INVITE_RECEIVED("You have been invited to {0}''s party! You have 60 seconds to reply."),
INVITE_ACCEPT("{0} has joined the party."),
INVITE_DENY("{0} declined your invite."),
INVITE_EXPIRED("{0} did not respond in time."),

View File

@ -1,163 +1,114 @@
package mineplex.core.party;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import mineplex.core.common.util.UtilServer;
import mineplex.core.party.constants.PartyRemoveReason;
import mineplex.core.party.event.PartyTransferOwnerEvent;
import mineplex.core.party.event.PartyTransferOwnerEvent.TransferReason;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile;
import mineplex.core.Managers;
import mineplex.core.common.util.UtilServer;
import mineplex.core.party.constants.PartyRemoveReason;
import mineplex.core.party.rediscommands.PartyTransferRequest;
import mineplex.core.utils.UtilGameProfile;
/**
* The main object for Parites.
*/
public class Party
public class Party implements Listener
{
/**
* This is controls whether or not the owner is currently in the menu, and kicking members
*/
private transient boolean _ownerKickMode = false;
/**
* Asserts if this party has already been put into teams in order to prevent the Arcade from reassigning teams
*/
private transient boolean _alreadyTeamed = false;
/**
* The maximum amount of players a party can have.
*/
private static final int PARTY_MAX_SIZE = 16;
/**
* Partners that have already been placed
*/
private transient final List<UUID> _teamed;
private final PartyManager _partyManager = Managers.require(PartyManager.class);
/**
* The current leader of this party
* The unique ID assigned to this party
*/
private String _owner;
private UUID _uniqueId = UUID.randomUUID();
/**
* The names of all current party members
* Metadata related to the current owner of this party, stored in serializable form for transferring
*/
private List<String> _members;
private GameProfile _owner;
/**
* The UUIDS of all current party members
*/
private List<UUID> _membersByUUID;
/**
* All current pending invites
*/
private Map<String, Long> _invites;
private List<Player> _members = Lists.newArrayList();
/**
* This party's max size
*/
private int _size;
private int _size = PARTY_MAX_SIZE;
/**
* Team preferences
*/
private Map<UUID, Map<String, String>> _preferences;
private List<UUID> _pendingUnrankedMembers = new ArrayList<>();
private List<UUID> _pendingMembers = new ArrayList<>();
/**
* Empty constructor for GSON
*/
public Party()
public Party(PartyTransferRequest request)
{
_teamed = Lists.newArrayList();
_uniqueId = request.getPartyUUID();
_owner = request.getOwnerGameProfile();
_pendingMembers.addAll(request.getAllMembers());
_pendingUnrankedMembers.addAll(request.getUnrankedMembers());
_partyManager.runSyncLater(() ->
{
// No one joined :(
for (UUID uuid : _pendingUnrankedMembers)
{
_partyManager.getClientManager().unreserve(uuid);
}
for (UUID uuid : _pendingMembers)
{
_partyManager.removePendingJoin(uuid);
}
// No one joined :(
if (_pendingMembers.size() == request.getAllMembers().size())
{
_partyManager.removeParty(Party.this);
}
}, 20 * 10L);
}
/**
* Creates a new fresh party instance
* Creates a new party instance
*
* @param owner The owner / leader of the party.
*/
public Party(String owner)
public Party(Player owner)
{
_owner = owner;
_members = Lists.newArrayList();
_invites = Maps.newHashMap();
_owner = UtilGameProfile.getGameProfile(owner);
_members.add(owner);
_teamed = Lists.newArrayList();
_membersByUUID = Lists.newArrayList();
_preferences = Maps.newHashMap();
_membersByUUID.add(Bukkit.getPlayerExact(owner).getUniqueId());
}
public String getOwner()
public String getOwnerName()
{
return _owner.getName();
}
public GameProfile getOwner()
{
return _owner;
}
/**
* Get the current members by their IGN
*
* @return The list of named party members
*/
public List<String> getMembers()
public Optional<Player> getOwnerAsPlayer()
{
return _members;
return Optional.ofNullable(Bukkit.getPlayer(_owner.getId()));
}
public Map<String, Long> getInvites()
public UUID getUniqueId()
{
return _invites;
}
/**
* An alternate method to get the owner of the party.
* While this does not have any difference to using {@code getOwner}, it may serve a purpose in the future, should we wish to allow
* donators to name their party something custom.
*
* @return This party's name
*/
public String getName()
{
return _owner;
}
/**
* Gets the players preferred teammate for a game
*
* @param player The player's UUID
* @return His team preference
*/
public String getPartner(UUID player, String game)
{
Map<String, String> prefs = _preferences.get(player);
if (prefs == null)
{
prefs = Maps.newHashMap();
_preferences.put(player, prefs);
return null;
}
return prefs.get(game);
}
/**
* Set a player's partner preference
*
* @param player The player
* @param game The name of the game
* @param partner The name of his partner
*/
public void setPartner(Player player, String game, String partner)
{
Map<String, String> prefs = _preferences.getOrDefault(player.getUniqueId(), Maps.newHashMap());
prefs.put(game, partner);
_preferences.put(player.getUniqueId(), prefs);
return this._uniqueId;
}
/**
@ -167,9 +118,7 @@ public class Party
*/
public void sendMessage(String message)
{
// Todo actually figure out why one of the members is no longer online
// probably some desync between players and something
_members.stream().map(Bukkit::getPlayer).filter(Objects::nonNull).forEach(player -> player.sendMessage(message));
getMembers().forEach(player -> player.sendMessage(message));
}
public int getSize()
@ -178,160 +127,65 @@ public class Party
}
/**
* Set's this party's size cap base off the current players rank
* Set's the new owner for this party instance
*
* @param owner The new owner's name
*/
public void setSize()
public void setOwner(Player owner)
{
_size = PARTY_MAX_SIZE;
_owner = UtilGameProfile.getGameProfile(owner);
}
/**
* Called when a player is added to the party.
*
* @param player The name of the player
*/
public void onPlayerAdd(String player)
public boolean isMember(Player player)
{
return _members.contains(player);
}
public void addMember(Player player)
{
_invites.remove(player);
if (_members.contains(player))
{
return;
}
_members.add(player);
Lang.ADD_MEMBER.send(this, player);
getMembers().forEach(s ->
{
Player player1 = Bukkit.getPlayer(s);
player1.playSound(player1.getLocation(), Sound.NOTE_PLING, 1.0F, 10.0F);
});
_pendingMembers.remove(player.getUniqueId());
_pendingUnrankedMembers.remove(player.getUniqueId());
Lang.ADD_MEMBER.send(this, player.getName());
getMembers().forEach(player1 -> player1.playSound(player1.getLocation(), Sound.NOTE_PLING, 1.0F, 10.0F));
}
/**
* Called when a member of the party is removed
*
* @param player The name of the player
* @param reason The reason for his removal.
*/
public void onPlayerRemove(String player, PartyRemoveReason reason)
public List<Player> getMembers()
{
if(reason == PartyRemoveReason.DISBANDED)
{
Player bukkitPlayer = Bukkit.getPlayerExact(player);
Lang.DISBANDED.send(bukkitPlayer);
bukkitPlayer.closeInventory();
return;
return Collections.unmodifiableList(_members);
}
public boolean isOwner(Player caller)
{
return caller.getUniqueId().equals(this._owner.getId());
}
public void clear()
{
_owner = null;
_members.clear();
UtilServer.Unregister(this);
}
public void removeMember(Player player)
{
_members.remove(player);
if (_members.size() <= 0)
{
return;
}
if(reason == PartyRemoveReason.LEFT)
{
if(player.equalsIgnoreCase(_owner) && _members.size() > 1)
{
_owner = _members.get(0);
Lang.TRANSFER_OWNER.send(this, player, _owner);
PartyTransferOwnerEvent event = new PartyTransferOwnerEvent(this, _owner, player, TransferReason.LEFT);
UtilServer.getServer().getPluginManager().callEvent(event);
return;
}
Lang.REMOVE_PLAYER.send(this, player);
return;
}
System.out.println("Removing member: " + player.getName() + " "+ player.getUniqueId() + " owner is " + _owner.getId());
if(reason == PartyRemoveReason.OTHER)
if (player.getUniqueId().equals(_owner.getId()) && _members.size() > 0)
{
return;
}
if(reason == PartyRemoveReason.KICKED)
{
Lang.REMOVE_PLAYER_KICK.send(this, player);
}
}
/**
* Gets the current state of whether or not the owner is kicking people in the UI.
*
* @return <code>true</code> if the owner is kicking people
*/
public boolean isOwnerKickMode()
{
return _ownerKickMode;
}
/**
* Set's the current state of kicking players
*
* @param ownerKickMode <code>true</code> if the owner is kicking people
*/
public void setOwnerKickMode(boolean ownerKickMode)
{
_ownerKickMode = ownerKickMode;
}
/**
* Set's the new owner for this party instance
*
* @param owner The new owner's name
*/
public void setOwner(String owner)
{
_owner = owner;
}
/**
* Get a list of all members in the party by their UUID
*
* @return A list of members by UUID
*/
public List<UUID> getMembersByUUID()
{
return _membersByUUID;
}
public boolean alreadyTeamed()
{
return _alreadyTeamed;
}
public void setAlreadyTeamed(boolean alreadyTeamed)
{
_alreadyTeamed = alreadyTeamed;
}
/**
* Check to see if this party contains a certain player name
* This is case-insensitive
*
* @param name The players name
* @return <code>true</code> If the player is in the party
*/
public boolean contains(String name)
{
for (UUID member : _membersByUUID)
{
if (Bukkit.getPlayer(member).getName().equalsIgnoreCase(name))
{
return true;
}
}
return false;
}
public boolean isAlreadyTeamed(UUID uuid)
{
return _teamed.contains(uuid);
}
public void setTeamed(Player... players)
{
for (Player player : players)
{
_teamed.add(player.getUniqueId());
_owner = UtilGameProfile.getGameProfile(_members.get(0));
Lang.TRANSFER_OWNER.send(this, player.getName(), _owner.getName());
}
}
}

View File

@ -1,167 +0,0 @@
package mineplex.core.party;
import mineplex.core.common.Rank;
import mineplex.core.menu.Menu;
import mineplex.core.party.constants.PartyRemoveReason;
import mineplex.core.party.event.PartyMemberKickGUIEvent;
import mineplex.core.party.event.PartySendToServerEvent;
import mineplex.core.party.event.PartyTransferOwnerEvent;
import mineplex.core.portal.ServerTransferEvent;
import mineplex.serverdata.data.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
/**
* Event handler for Parties
*/
public class PartyEventListener implements Listener
{
private final PartyManager _plugin;
public PartyEventListener(PartyManager plugin)
{
_plugin = plugin;
_plugin.getPluginManager().registerEvents(this, plugin.getPlugin());
}
@EventHandler
public void onJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();
String partyName = _plugin.getInviteManager().getPartyWaiting(player.getUniqueId());
if (partyName == null)
{
return;
}
Party party = _plugin.getParty(partyName);
Player bukkitPlayer = Bukkit.getPlayerExact(partyName);
if (party == null)
{
party = new Party(partyName);
if (bukkitPlayer != null && _plugin.getClientManager().Get(bukkitPlayer).GetRank().has(Rank.ULTRA))
{
party.setSize();
} else
{
party.setSize();
}
_plugin.addParty(party);
}
_plugin.getInviteManager().cancelTask(player.getUniqueId());
_plugin.getMethodManager().addToParty(Bukkit.getPlayerExact(partyName), party);
_plugin.getMethodManager().addToParty(player, party);
_plugin.getInviteManager().removeFromWaiting(player.getUniqueId());
}
@EventHandler
public void onQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
Party party = _plugin.getParty(player);
_plugin.getInviteManager().removeAll(player.getUniqueId());
if (party == null)
{
return;
}
PartyRemoveReason reason = PartyRemoveReason.LEFT;
if(_plugin.getJoinManager().isTransferring(player))
{
reason = PartyRemoveReason.OTHER;
}
_plugin.getMethodManager().removeFromParty(player, reason);
}
@EventHandler
public void onTransferOwner(PartyTransferOwnerEvent event)
{
_plugin.getMethodManager().transferOwner(event.getNewOwner(), event.getOldOwner());
}
@EventHandler
public void onKick(PartyMemberKickGUIEvent event)
{
Player clicked = Bukkit.getPlayerExact(event.getPlayerClicked());
Lang.REMOVED.send(clicked);
_plugin.getMethodManager().removeFromParty(clicked, PartyRemoveReason.KICKED);
Menu.get(event.getOwner().getUniqueId()).resetAndUpdate();
}
@EventHandler
public void onTransfer(ServerTransferEvent event)
{
Player player = event.getPlayer();
Party party = _plugin.getParty(player);
if (party == null)
{
return;
}
if(event.isDraggedByParty())
{
return;
}
event.setParty(party);
event.setCancel(true);
if (!party.getOwner().equalsIgnoreCase(player.getName()))
{
Lang.NOT_OWNER_SERVER.send(player);
return;
}
String server = event.getServer();
if(server.equalsIgnoreCase("Lobby"))
{
return;
}
_plugin.getJoinManager().requestServerJoin(event.getServer(), party);
}
@EventHandler
public void onSend(PartySendToServerEvent event)
{
Party party = event.getParty();
MinecraftServer server = event.getMinecraftServer();
_plugin.getRedisManager().sendPartyInfo(server.getName(), party);
}
@EventHandler
public void onClick(PlayerInteractEvent event)
{
if(event.hasItem() && event.getItem().getType() == Material.NAME_TAG)
{
event.setCancelled(true);
event.getPlayer().chat("/party");
}
}
}

View File

@ -1,38 +1,56 @@
package mineplex.core.party;
import com.google.common.collect.Maps;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.party.command.PartyCommand;
import mineplex.core.party.manager.PartyInviteManager;
import mineplex.core.party.manager.PartyJoinManager;
import mineplex.core.party.manager.PartyMethodManager;
import mineplex.core.party.manager.PartyRedisManager;
import mineplex.core.portal.Portal;
import mineplex.core.preferences.PreferencesManager;
import mineplex.serverdata.Region;
import mineplex.serverdata.Utility;
import mineplex.serverdata.servers.ServerManager;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import com.google.common.collect.Maps;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.jsonchat.ChildJsonMessage;
import mineplex.core.common.jsonchat.ClickEvent;
import mineplex.core.common.jsonchat.HoverEvent;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.menu.Menu;
import mineplex.core.party.command.PartyCommand;
import mineplex.core.party.constants.PartyRemoveReason;
import mineplex.core.party.manager.PartyInviteManager;
import mineplex.core.party.manager.PartyJoinManager;
import mineplex.core.party.manager.PartyRedisManager;
import mineplex.core.party.rediscommands.PartyCrossServerInviteAccept;
import mineplex.core.party.rediscommands.PartyCrossServerInviteCommand;
import mineplex.core.party.rediscommands.PartyCrossServerInviteDeny;
import mineplex.core.portal.Portal;
import mineplex.core.preferences.Preference;
import mineplex.core.preferences.PreferencesManager;
import mineplex.serverdata.Region;
import mineplex.serverdata.commands.ServerCommandManager;
public class PartyManager extends MiniPlugin
{
/**
* The item given to a player in his hotbar to manage the Parties via the new UI.
*/
public static final ItemStack INTERFACE_ITEM = new ItemBuilder(Material.NAME_TAG).setTitle(C.cGreen + "Parties").build();
public static final ItemStack INTERFACE_ITEM = new ItemBuilder(Material.NAME_TAG)
.setTitle(C.cGreen + "Parties")
.build();
/**
* The slow to which it goes in.
* The slot to which it goes in.
*/
public static final int INTERFACE_SLOT = 5;
@ -43,66 +61,71 @@ public class PartyManager extends MiniPlugin
private final PartyRedisManager _redisManager;
private final PartyInviteManager _inviteManager;
private final PartyJoinManager _joinManager;
private final PartyMethodManager _methodManager;
/**
* This local instance's name
*/
private final String _serverName;
/**
* A map of player's in parties server wide.
*/
private final Map<UUID, Party> _players = Maps.newHashMap();
private final Map<UUID, Party> _partiesById = new HashMap<>();
private final Map<UUID, Party> _partiesByPlayer = new HashMap<>();
/**
* A map of owner (name) -> party server wide
*/
private final Map<String, Party> _parties = Maps.newHashMap();
private final Region _region;
/**
* Maps UUID of player to UUID of party that they're supposed to join
*/
private final Map<UUID, UUID> _pendingJoinMap = new HashMap<>();
public PartyManager(JavaPlugin plugin, Portal portal, CoreClientManager clientManager, PreferencesManager preferenceManager)
public PartyManager()
{
super("Parties", plugin);
_portal = portal;
_clientManager = clientManager;
_preferencesManager = preferenceManager;
super("Parties");
_portal = require(Portal.class);
_clientManager = require(CoreClientManager.class);
_preferencesManager = require(PreferencesManager.class);
_serverName = _plugin.getConfig().getString("serverstatus.name");
_serverName = UtilServer.getServerName();
_redisManager = new PartyRedisManager(this, _serverName,
Utility.generatePool(ServerManager.getMasterConnection()),
Utility.generatePool(ServerManager.getSlaveConnection()));
_redisManager = new PartyRedisManager(this, _serverName);
_inviteManager = new PartyInviteManager(this, _redisManager);
_inviteManager = new PartyInviteManager(this);
_joinManager = new PartyJoinManager(this);
_methodManager = new PartyMethodManager(this);
addCommand(new PartyCommand(this));
new PartyEventListener(this);
_region = !new File("eu.dat").exists() ? Region.US : Region.EU;
}
public Party getParty(String party)
@Deprecated
public void putIntoPendingJoin(UUID player, UUID party)
{
return _parties.get(party);
_pendingJoinMap.put(player, party);
}
public Party getParty(Player player)
@Override
public void addCommands()
{
return _players.get(player.getUniqueId());
addCommand(new PartyCommand(this));
}
public Party getPartyByPlayer(UUID playerId)
{
return _partiesByPlayer.get(playerId);
}
public Party getPartyById(UUID playerId)
{
return _partiesById.get(playerId);
}
public Party getPartyByPlayer(Player player)
{
return _partiesByPlayer.get(player.getUniqueId());
}
public void addParty(Party party)
{
_parties.put(party.getName(), party);
}
public void removeParty(Party party)
{
_parties.remove(party.getName());
_partiesById.put(party.getUniqueId(), party);
}
public Portal getPortal()
@ -135,29 +158,425 @@ public class PartyManager extends MiniPlugin
return _serverName;
}
public PartyJoinManager getJoinManager()
{
return _joinManager;
}
public PartyMethodManager getMethodManager()
{
return _methodManager;
}
public Map<UUID, Party> getPlayerParties()
{
return _players;
}
public Map<String, Party> getParties()
{
return _parties;
}
public Region getRegion()
{
return _region;
}
public void denyInviteBySender(Player caller, String senderName)
{
PartyInviteManager inviteManager = getInviteManager();
if (!inviteManager.hasInviteFrom(caller, senderName))
{
UtilPlayer.message(caller, F.main("Party", "You do not have a pending invite to " + F.elem(senderName) + "'s party."));
return;
}
InviteData invite = inviteManager.getInviteBySender(caller.getName(), senderName);
inviteManager.removeInvite(caller, senderName);
if (invite.getServerName().equals(_serverName))
{
Player senderPlayer = Bukkit.getPlayerExact(senderName);
if (senderPlayer == null)
{
UtilPlayer.message(caller, F.main("Party", "You have denied your invite to " + F.elem(senderName) + "'s party, but it seems that " + F.elem(senderName) + " is no longer in this server"));
return;
}
Party partyBySender = getPartyByPlayer(senderPlayer);
if (partyBySender == null)
{
// todo send cancelled invitation msg when party is disbanded
UtilPlayer.message(caller, F.main("Party", "You have denied your invite to " + F.elem(senderPlayer.getName()) + "'s party, but it seems that " + F.elem(senderPlayer.getName()) + " has disbanded his party as well"));
return;
}
UtilPlayer.message(caller, F.main("Party", "You have denied your invite to " + F.elem(senderPlayer.getName()) + "'s party"));
UtilPlayer.message(senderPlayer, F.main("Party", F.elem(caller.getName()) + " has denied your invite"));
}
else
{
Player senderPlayer = Bukkit.getPlayerExact(senderName);
if (senderPlayer != null)
{
UtilPlayer.message(caller, F.main("Party", "You have denied your invite to " + F.elem(senderPlayer.getName()) + "'s party, but it seems that " + F.elem(senderPlayer.getName()) + " has joined you in this server"));
return;
}
UtilPlayer.message(caller, F.main("Party", "You have denied your invite to " + F.elem(senderName) + "'s party"));
ServerCommandManager.getInstance().publishCommand(new PartyCrossServerInviteDeny(
caller.getName(),
caller.getUniqueId(),
invite.getInviterName(),
invite.getInviterUUID(),
invite.getPartyUUID()
));
}
}
public void acceptInviteBySender(Player caller, String senderName)
{
if (getPartyByPlayer(caller) != null)
{
caller.sendMessage(F.main("Party", "Please leave your party before accepting another invite!"));
return;
}
PartyInviteManager inviteManager = getInviteManager();
if (!inviteManager.hasInviteFrom(caller, senderName))
{
UtilPlayer.message(caller, F.main("Party", "You do not have a pending invite to " + F.elem(senderName) + "'s party."));
return;
}
InviteData invite = inviteManager.getInviteBySender(caller.getName(), senderName);
inviteManager.removeInvite(caller, senderName);
if (invite.getServerName().equals(_serverName))
{
Player senderPlayer = Bukkit.getPlayerExact(senderName);
if (senderPlayer == null)
{
UtilPlayer.message(caller, F.main("Party", "It seems that " + F.elem(senderName) + " is no longer in this server"));
return;
}
Party partyBySender = getPartyByPlayer(senderPlayer);
if (partyBySender == null)
{
// todo send cancelled invitation msg when party is disbanded
UtilPlayer.message(caller, F.main("Party", "It seems that " + F.elem(senderName) + " has disbanded his party. Shucks!"));
return;
}
addToParty(caller, partyBySender);
}
else
{
Player senderPlayer = Bukkit.getPlayerExact(senderName);
if (senderPlayer != null)
{
// todo maybe auto create party (if there are no new desync issues)
UtilPlayer.message(caller, F.main("Party", "Strange. It seems that " + F.elem(senderName) + " has preemptively joined you in this server. They'll need to resend an invitation"));
return;
}
UtilPlayer.message(caller, F.main("Party", "Please wait while I attempt to locate " + F.elem(invite.getInviterName()) + "..."));
ServerCommandManager.getInstance().publishCommand(new PartyCrossServerInviteAccept(
caller.getName(),
caller.getUniqueId(),
invite.getInviterName(),
invite.getInviterUUID(),
invite.getPartyUUID()
));
runSyncLater(() ->
{
if (!caller.isOnline())
{
return;
}
UtilPlayer.message(caller, F.main("Party", "Uh oh. It looks like " + F.elem(invite.getInviterName()) + " has left the network - I couldn't find them!"));
}, 20 * 5L);
}
}
/**
* @param caller The player who initiated the request
* @param target The player's target
*/
public void invite(Player caller, String target)
{
if (target.equalsIgnoreCase(caller.getName()))
{
caller.sendMessage(F.main("Party", "You cannot invite yourself!"));
return;
}
Player possible = Bukkit.getPlayerExact(target);
Party party = getPartyByPlayer(caller);
// preemptively create party - it might be a slight inconvenience but it saves a lot of untangling work
if (party == null)
{
UtilPlayer.message(caller, F.main("Party", "You don't seem to have a party, so I've created a new one for you!"));
party = new Party(caller);
_partiesById.put(party.getUniqueId(), party);
addToParty(caller, party);
}
if (!party.getOwnerName().equalsIgnoreCase(caller.getName()))
{
party.sendMessage(F.main("Party", F.elem(caller.getName()) + " has suggested " + F.elem(target) + " be invited"));
party.getOwnerAsPlayer().ifPresent(owner ->
{
ChildJsonMessage message = new ChildJsonMessage("").extra(F.main("Party", "Click "));
message.add(F.link("Invite " + target))
.hover(HoverEvent.SHOW_TEXT, C.cGreen + "Clicking this will invite " + C.cYellow + target + C.cGreen + " to the party")
.click(ClickEvent.RUN_COMMAND, "/party gui invite " + target);
message.add(C.mBody + " to invite them");
message.sendToPlayer(owner);
});
return;
}
if (party.getMembers().size() >= party.getSize())
{
Lang.PARTY_FULL.send(caller);
return;
}
if (possible != null && party.isMember(possible))
{
Lang.ALREADY_MEMBER.send(caller, target);
return;
}
if (getInviteManager().getInviteBySender(target, caller.getName()) != null)
{
Lang.ALREADY_INVITED.send(caller, target);
return;
}
if (possible != null && !getPreferencesManager().get(possible).isActive(Preference.PARTY_REQUESTS))
{
UtilPlayer.message(caller, F.main("Party", F.name(target) + " is not accepting invites at this time."));
return;
}
//Same Server
if (possible != null)
{
Lang.SUCCESS_INVITE.send(party, caller.getName(), target);
getInviteManager().inviteTo(possible.getName(), possible.getUniqueId(), caller.getName(), caller.getUniqueId(), party.getUniqueId(), getServerName());
}
else
{
findAndInvite(caller, target, party);
}
}
/**
* Initiates inviting a player who is no on the same server
*/
private void findAndInvite(Player caller, String target, Party destParty)
{
Map<String, BukkitTask> pendingInvites = getRedisManager().getPendingFindResponse().computeIfAbsent(caller.getUniqueId(), key -> new HashMap<>());
if (!pendingInvites.containsKey(target))
{
caller.sendMessage(F.main("Party", "Attempting to invite " + F.elem(target) + "..."));
pendingInvites.put(target, runSyncLater(new BukkitRunnable()
{
@Override
public void run()
{
if (!pendingInvites.containsKey(target))
{
return;
}
pendingInvites.remove(target);
if (!caller.isOnline())
{
return;
}
Player targetPlayer = Bukkit.getPlayerExact(target);
if (targetPlayer != null)
{
UtilPlayer.message(caller, F.main("Party", "Huh. We couldn't find " + F.elem(target) + ", but it seems they've joined you in your server"));
return;
}
caller.sendMessage(F.main("Party", "Could not locate " + F.elem(target) + "."));
}
}, 20L * 5));
ServerCommandManager.getInstance().publishCommand(new PartyCrossServerInviteCommand(caller, target, destParty));
}
else
{
caller.sendMessage(F.main("Party", "Please wait until the previous invite has completed"));
}
}
public Party getPendingParty(Player player)
{
UUID partyUUID = _pendingJoinMap.get(player.getUniqueId());
if (partyUUID == null) return null;
for (Party party : _partiesById.values())
{
if (party.getUniqueId().equals(partyUUID))
return party;
}
return null;
}
public boolean hasPendingJoin(Player player)
{
return _pendingJoinMap.containsKey(player.getUniqueId());
}
public void removePendingJoin(Player player)
{
_pendingJoinMap.remove(player.getUniqueId());
}
public void removePendingJoin(UUID player)
{
_pendingJoinMap.remove(player);
}
/**
* Kicks a player from the callers party
*
* @param caller The player who initiated the request
* @param target The player's target
*/
public void kickPlayer(Player caller, String target)
{
Party party = getPartyByPlayer(caller);
if (party == null)
{
Lang.NO_PARTY.send(caller);
return;
}
if (!party.isOwner(caller))
{
Lang.NOT_OWNER.send(caller);
return;
}
Player playerTarget = Bukkit.getPlayerExact(target);
if (playerTarget == null)
{
Lang.NOT_MEMBER.send(caller, target);
return;
}
if (!party.isMember(playerTarget))
{
Lang.NOT_MEMBER.send(caller, target);
return;
}
removeFromParty(playerTarget, PartyRemoveReason.KICKED);
}
public void addToParty(Player player, Party party)
{
_partiesByPlayer.put(player.getUniqueId(), party);
party.addMember(player);
}
/**
* Leaves the players current party if he is in one
*
* @param caller The player who wishes to leave his party
*/
public void leaveParty(Player caller)
{
Party party = getPartyByPlayer(caller);
if (party == null)
{
Lang.NO_PARTY.send(caller);
return;
}
removeFromParty(caller, PartyRemoveReason.LEFT);
Lang.LEFT.send(caller);
}
public void removeFromParty(Player player, PartyRemoveReason reason)
{
Party party = _partiesByPlayer.remove(player.getUniqueId());
if (party == null)
{
return;
}
if (player.getOpenInventory() != null)
{
if (Menu.get(player.getUniqueId()) != null)
{
player.closeInventory();
Menu.remove(player.getUniqueId());
}
}
switch (reason)
{
case KICKED:
Lang.REMOVE_PLAYER_KICK.send(party, player.getName());
break;
case LEFT:
Lang.REMOVE_PLAYER.send(party, player.getName());
break;
case OTHER:
break;
case DISBANDED:
break;
case DISBANDED_BY_OWNER:
break;
}
party.removeMember(player);
if (party.getMembers().size() == 0)
{
removeParty(party);
}
}
/**
* Disbands a player's current party
*
* @param caller The player who wishes to disband his party
*/
public void disband(Player caller)
{
Party party = getPartyByPlayer(caller);
if (party == null)
{
Lang.NO_PARTY.send(caller);
return;
}
if (!party.isOwner(caller))
{
Lang.NOT_OWNER.send(caller);
return;
}
caller.sendMessage(F.main("Party", "You have disbanded your party."));
Lang.DISBANDED_BY_OWNER.send(party);
removeParty(party);
}
public void removeParty(Party party)
{
_joinManager.removePendingJoin(party);
_partiesById.remove(party.getUniqueId());
_partiesByPlayer.entrySet().removeIf(ent -> ent.getValue().equals(party));
party.clear();
}
public void giveItemIfNotExists(Player player)
{
if (!UtilItem.isSimilar(player.getInventory().getItem(INTERFACE_SLOT), INTERFACE_ITEM, UtilItem.ItemAttribute.NAME, UtilItem.ItemAttribute.MATERIAL))
{
player.getInventory().setItem(PartyManager.INTERFACE_SLOT, PartyManager.INTERFACE_ITEM);
}
}
}

View File

@ -0,0 +1,159 @@
package mineplex.core.party.command;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
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.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.core.party.command.cli.PartyAcceptCommand;
import mineplex.core.party.command.cli.PartyDenyCommand;
import mineplex.core.party.command.cli.PartyDisbandCommand;
import mineplex.core.party.command.cli.PartyHelpCommand;
import mineplex.core.party.command.cli.PartyInviteCommand;
import mineplex.core.party.command.cli.PartyInvitesCommand;
import mineplex.core.party.command.cli.PartyKickCommand;
import mineplex.core.party.command.cli.PartyLeaveCommand;
import mineplex.core.party.command.cli.PartyTransferOwnerCommand;
public class PartyCLICommand extends MultiCommandBase<PartyManager>
{
public PartyCLICommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "cli", "c");
AddCommand(new PartyAcceptCommand(plugin));
AddCommand(new PartyDenyCommand(plugin));
AddCommand(new PartyDisbandCommand(plugin));
AddCommand(new PartyInviteCommand(plugin));
AddCommand(new PartyInvitesCommand(plugin));
AddCommand(new PartyKickCommand(plugin));
AddCommand(new PartyLeaveCommand(plugin));
AddCommand(new PartyTransferOwnerCommand(plugin));
AddCommand(new PartyHelpCommand(plugin));
}
@Override
protected void Help(Player caller, String[] args)
{
Party party = Plugin.getPartyByPlayer(caller);
if (args.length > 0)
{
UtilPlayer.message(caller, F.main("Party", "That is not a valid command! Try " + F.elem("/party help") + "!"));
return;
}
if (party == null)
{
UtilPlayer.message(caller, F.main("Party", "You're not in a party! Try " + F.elem("/party help") + "!"));
return;
}
ComponentBuilder builder = new ComponentBuilder("")
.append("[", ComponentBuilder.FormatRetention.NONE)
.bold(true)
.color(ChatColor.AQUA)
.append("?", ComponentBuilder.FormatRetention.NONE)
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Click to view Party Help").create()))
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/z help"))
.append("]", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.AQUA)
.bold(true)
.append("===========", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.AQUA)
.bold(true)
.strikethrough(true)
.append("[", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.AQUA)
.bold(true)
.append("Your Party", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.WHITE)
.bold(true)
.append("]", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.AQUA)
.bold(true)
.append("==============", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.AQUA)
.bold(true)
.strikethrough(true)
.append("\n\n", ComponentBuilder.FormatRetention.NONE);
builder.append("Leader")
.color(party.getOwnerAsPlayer() == null ? ChatColor.GRAY : ChatColor.LIGHT_PURPLE)
.bold(true)
.append(" ", ComponentBuilder.FormatRetention.NONE)
.append(party.getOwnerName())
.append("\n");
for (Player member : party.getMembers())
{
if (member.getUniqueId().equals(party.getOwner().getId()))
continue;
builder.append("Member")
.color(ChatColor.DARK_PURPLE)
.bold(true)
.append(" ", ComponentBuilder.FormatRetention.NONE)
.append(member.getName());
if (party.isOwner(caller))
{
builder.append(" ", ComponentBuilder.FormatRetention.NONE)
.append("", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.RED)
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Kick " + member.getName() + " from your party").color(ChatColor.RED).create()))
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/z cli kick " + member.getName()))
.append(" ", ComponentBuilder.FormatRetention.NONE)
.append("", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.GOLD)
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Transfer party to " + member.getName()).color(ChatColor.GOLD).create()))
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/z cli tr " + member.getName()));
}
builder.append("\n", ComponentBuilder.FormatRetention.NONE);
}
builder.append("\n", ComponentBuilder.FormatRetention.NONE);
builder.append("Toggle GUI")
.color(ChatColor.GREEN)
.bold(true)
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Switch to the chest GUI instead of chat").color(ChatColor.GREEN).create()))
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/z t"))
.append(" - ", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.GRAY)
.append("Leave")
.color(ChatColor.RED)
.bold(true)
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Leave your party").color(ChatColor.RED).create()))
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/z cli leave"));
if (party.isOwner(caller))
{
builder
.append(" - ")
.color(ChatColor.GRAY)
.append("Disband")
.color(ChatColor.DARK_RED)
.bold(true)
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Disband your party").color(ChatColor.DARK_RED).create()))
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/z cli disband"));
}
builder.append("\n", ComponentBuilder.FormatRetention.NONE)
.append("======================================")
.color(ChatColor.AQUA)
.bold(true)
.strikethrough(true);
caller.spigot().sendMessage(builder.create());
}
}

View File

@ -1,95 +1,54 @@
package mineplex.core.party.command;
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.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.core.party.ui.menus.PartyInvitesMenu;
import mineplex.core.party.ui.menus.PartyMainMenu;
import mineplex.core.party.ui.menus.PartyOwnerMenu;
import mineplex.core.party.ui.menus.PartyViewMenu;
import java.util.Arrays;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
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.party.PartyManager;
import mineplex.core.preferences.Preference;
import mineplex.core.preferences.PreferencesManager;
/**
* Command handler for party commands
*/
public class PartyCommand extends CommandBase<PartyManager>
public class PartyCommand extends MultiCommandBase<PartyManager>
{
private final String[] HELP = {
F.main("Party", "Party Commands (Click the command!)"),
help("", "Brings up the Party GUI"),
help("<player>", "Send an invitation to a player."),
help("leave", "Leave your current party."),
C.cBlue + "Party> " + C.cWhite + "#<message> " + C.cGray + "- Send a message to your party.",
C.cGreenB + "All party functions have been moved to the GUI!",
C.cGreenB + "Click the NameTag in your hotbar to get started!"
};
private final PreferencesManager _preferencesManager = Managers.require(PreferencesManager.class);
public PartyCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "party", "z", "partyaccept", "partydeny", "openinvitesmenu", "partyinvite");
super(plugin, Rank.ALL, "party", "z");
AddCommand(new PartyGuiCommand(plugin));
AddCommand(new PartyCLICommand(plugin));
AddCommand(new PartyToggleCommand(plugin));
}
@Override
public void Execute(Player caller, String[] args)
protected void Help(Player caller, String[] args)
{
if (args.length == 0)
if (args.length > 0)
{
if(_aliasUsed.equalsIgnoreCase("openinvitesmenu"))
if (!args[0].equalsIgnoreCase("cli") && !args[0].equalsIgnoreCase("gui"))
{
new PartyInvitesMenu(Plugin).open(caller);
return;
String[] newArgs = new String[args.length + 1];
System.arraycopy(args, 0, newArgs, 1, args.length);
newArgs[0] = _preferencesManager.get(caller).isActive(Preference.PARTY_DISPLAY_INVENTORY_UI) ? "gui" : "cli";
args = newArgs;
}
Party party = Plugin.getParty(caller);
if (party == null)
{
new PartyMainMenu(Plugin).open(caller);
return;
}
if (party.getOwner().equalsIgnoreCase(caller.getName()))
else
{
new PartyOwnerMenu(party, Plugin).open(caller);
return;
String[] newArgs = new String[1];
newArgs[0] = _preferencesManager.get(caller).isActive(Preference.PARTY_DISPLAY_INVENTORY_UI) ? "gui" : "cli";
args = newArgs;
}
Execute(caller, args);
}
new PartyViewMenu(party, Plugin).open(caller);
return;
}
if(args.length == 1)
{
String arg = args[0];
if (_aliasUsed.equalsIgnoreCase("partyaccept"))
{
Plugin.getMethodManager().respondToInvite(caller, arg, true);
return;
}
if (_aliasUsed.equalsIgnoreCase("partydeny"))
{
Plugin.getMethodManager().respondToInvite(caller, arg, false);
return;
}
if(_aliasUsed.equalsIgnoreCase("partyinvite"))
{
Plugin.getMethodManager().invite(caller, arg);
return;
}
if(arg.equalsIgnoreCase("leave")) {
Plugin.getMethodManager().leaveParty(caller);
return;
}
Plugin.getMethodManager().invite(caller, arg);
return;
}
caller.sendMessage(HELP);
}
private String help(String command, String description)
{
return C.cBlue + "Party> " + C.cWhite + "/party " + command + C.cGray + " - " + description;
}
}

View File

@ -0,0 +1,56 @@
package mineplex.core.party.command;
import org.bukkit.entity.Player;
import mineplex.core.command.MultiCommandBase;
import mineplex.core.common.Rank;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.core.party.command.gui.PartyGUIAcceptInviteCommand;
import mineplex.core.party.command.gui.PartyGUIDenyInviteCommand;
import mineplex.core.party.command.gui.PartyGUIInviteCommand;
import mineplex.core.party.command.gui.PartyGUILeaveCommand;
import mineplex.core.party.command.gui.PartyOpenInviteMenuCommand;
import mineplex.core.party.ui.menus.PartyMainMenu;
import mineplex.core.party.ui.menus.PartyOwnerMenu;
import mineplex.core.party.ui.menus.PartyViewMenu;
public class PartyGuiCommand extends MultiCommandBase<PartyManager>
{
public PartyGuiCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "gui", "g");
AddCommand(new PartyOpenInviteMenuCommand(plugin));
AddCommand(new PartyGUIAcceptInviteCommand(plugin));
AddCommand(new PartyGUIDenyInviteCommand(plugin));
AddCommand(new PartyGUIInviteCommand(plugin));
AddCommand(new PartyGUILeaveCommand(plugin));
}
// a hacky method for a hacky original system
@Override
protected void Help(Player caller, String[] args)
{
if (args.length == 0)
{
Party party = Plugin.getPartyByPlayer(caller);
if (party == null)
{
new PartyMainMenu(Plugin).open(caller);
}
else if (party.getOwnerName().equalsIgnoreCase(caller.getName()))
{
new PartyOwnerMenu(party, Plugin).open(caller);
}
else
{
new PartyViewMenu(party, Plugin).open(caller);
}
}
else if (args.length == 1)
{
Plugin.invite(caller, args[0]);
}
}
}

View File

@ -0,0 +1,37 @@
package mineplex.core.party.command;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
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;
import mineplex.core.party.PartyManager;
import mineplex.core.preferences.Preference;
import mineplex.core.preferences.PreferencesManager;
public class PartyToggleCommand extends CommandBase<PartyManager>
{
private final PreferencesManager _preferencesManager = Managers.require(PreferencesManager.class);
public PartyToggleCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "toggle", "t");
}
@Override
public void Execute(Player caller, String[] args)
{
_preferencesManager.get(caller).toggle(Preference.PARTY_DISPLAY_INVENTORY_UI);
if (_preferencesManager.get(caller).isActive(Preference.PARTY_DISPLAY_INVENTORY_UI))
{
UtilPlayer.message(caller, F.main("Party", "The Party GUI is now " + C.cGreen + "enabled" + C.mBody + "!"));
}
else
{
UtilPlayer.message(caller, F.main("Party", "The Party GUI is now " + C.cRed + "disabled" + C.mBody + "!"));
}
}
}

View File

@ -1,167 +0,0 @@
package mineplex.core.party.command;
import com.google.common.collect.Maps;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.game.GameDisplay;
import mineplex.core.party.Lang;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.Map;
import java.util.UUID;
/**
* Unused for now.
*/
public class TeamPreferenceCommand extends CommandBase<PartyManager>
{
private static final String[] ARGS = {
"teampref",
"teamprefs",
"teamp",
"tprefs",
"teampreferences"
};
private final String ACCEPT = "accept";
private final String DENY = "deny";
private final String ACCEPT_COMMAND = "/teamprefs accept ";
private final String DENY_COMMAND = "/teamprefs deny ";
private final String HEADER = "Partners";
//Player, Partner, GameName
private Map<UUID, Map<String, String>> INVITES = Maps.newHashMap();
public TeamPreferenceCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, ARGS);
}
@Override
public void Execute(Player player, String[] args)
{
if (args.length < 2)
{
Lang.PARTNER_USAGE.sendHeader(player, HEADER);
return;
}
String arg = args[0];
if (arg.equalsIgnoreCase(ACCEPT) || arg.equalsIgnoreCase(DENY))
{
Party party = Plugin.getParty(player);
if (party == null)
{
Lang.NO_PARTY.send(player);
return;
}
String inviter = args[1];
boolean accept = arg.equalsIgnoreCase(ACCEPT);
Player inviterPlayer = Bukkit.getPlayerExact(inviter);
if (inviterPlayer == null)
{
Lang.PARTNER_NOT_ONLINE.sendHeader(player, HEADER, inviter);
return;
}
Map<String, String> sent = INVITES.get(inviterPlayer.getUniqueId());
if (sent == null || sent.isEmpty())
{
Lang.PARTNER_PLAYER_NOT_REQUESTED.sendHeader(player, HEADER, inviter);
return;
}
if (sent.get(player.getName()) == null)
{
Lang.PARTNER_PLAYER_NOT_REQUESTED.sendHeader(player, HEADER, inviter);
return;
}
String gameName = sent.remove(player.getName());
if (!accept)
{
Lang.PARTNER_REQUEST_DENIED_PLAYER.send(player, inviterPlayer.getName(), gameName);
Lang.PARTNER_REQUEST_DENIED_SENDER.send(inviterPlayer, player.getName(), gameName);
return;
}
Lang.PARTNER_REQUEST_ACCEPT_PLAYER.send(player, inviterPlayer.getName(), gameName);
Lang.PARTNER_REQUEST_ACCEPT_SENDER.send(inviterPlayer, player.getName(), gameName);
party.setPartner(player, gameName, inviterPlayer.getName());
party.setPartner(inviterPlayer, gameName, player.getName());
return;
}
Player target = Bukkit.getPlayerExact(arg);
String gameName = "";
String[] game = new String[args.length - 2];
System.arraycopy(args, 2, game, 0, game.length);
for (String s : game)
{
gameName += s + " ";
}
gameName = gameName.trim();
GameDisplay gameDisplay = GameDisplay.matchName(gameName);
if (gameDisplay == null)
{
Lang.PARTNER_NO_GAME.sendHeader(player, HEADER, gameName);
return;
}
gameName = gameDisplay.getName();
if (alreadyInvited(player, gameName, target.getName()))
{
Lang.PARTNER_ALREADY_INVITED.sendHeader(player, HEADER, target.getName(), gameName);
return;
}
sendRequest(player, gameName, target);
}
private void sendRequest(Player player, String game, Player partner)
{
invite(player, game, partner);
String gameName = C.cGreen + (game);
String playerName = C.cGreen + (player.getName());
String partnerName = C.cGreen + (partner.getName());
String acceptCommand = ACCEPT_COMMAND + player.getName();
String declineCommand = DENY_COMMAND + player.getName();
String acceptText = Lang.PARTNER_HOVER_TEXT_ACCEPT.toString(playerName, gameName);
String declineText = Lang.PARTNER_HOVER_TEXT_DENY.toString(playerName, gameName);
Lang.PARTNER_REQUEST_SENT.sendHeader(player, HEADER, partnerName, gameName);
Lang.PARTNER_REQUEST_RECEIVED.sendHeader(partner, HEADER, playerName, gameName);
UtilPlayer.sendAcceptOrDeny(partner, HEADER, acceptCommand, acceptText, declineCommand, declineText, null, null);
}
private boolean alreadyInvited(Player player, String game, String partner)
{
Map<String, String> sent = INVITES.get(player.getUniqueId());
return !(sent == null || sent.isEmpty()) && sent.get(partner).equalsIgnoreCase(game);
}
private void invite(Player player, String game, Player partner)
{
Map<String, String> sent = INVITES.getOrDefault(player.getUniqueId(), Maps.newHashMap());
sent.put(partner.getName(), game);
INVITES.put(player.getUniqueId(), sent);
}
}

View File

@ -0,0 +1,30 @@
package mineplex.core.party.command.cli;
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.party.Party;
import mineplex.core.party.PartyManager;
public class PartyAcceptCommand extends CommandBase<PartyManager>
{
public PartyAcceptCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "accept", "a");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 0)
{
UtilPlayer.message(caller, F.main("Party", "Oops. You didn't specify whose invite you're accepting!"));
return;
}
Plugin.acceptInviteBySender(caller, args[0]);
}
}

View File

@ -0,0 +1,21 @@
package mineplex.core.party.command.cli;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.party.PartyManager;
public class PartyBlockCommand extends CommandBase<PartyManager>
{
public PartyBlockCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "block", "b");
}
@Override
public void Execute(Player caller, String[] args)
{
}
}

View File

@ -0,0 +1,28 @@
package mineplex.core.party.command.cli;
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.party.PartyManager;
public class PartyDenyCommand extends CommandBase<PartyManager>
{
public PartyDenyCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "deny", "d");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 0)
{
UtilPlayer.message(caller, F.main("Party", "Oops. You didn't specify whose invite you're denying!"));
return;
}
Plugin.denyInviteBySender(caller, args[0]);
}
}

View File

@ -0,0 +1,21 @@
package mineplex.core.party.command.cli;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.party.PartyManager;
public class PartyDisbandCommand extends CommandBase<PartyManager>
{
public PartyDisbandCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "disband", "db");
}
@Override
public void Execute(Player caller, String[] args)
{
Plugin.disband(caller);
}
}

View File

@ -0,0 +1,34 @@
package mineplex.core.party.command.cli;
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.party.PartyManager;
public class PartyHelpCommand extends CommandBase<PartyManager>
{
public PartyHelpCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "help", "h");
}
@Override
public void Execute(Player caller, String[] args)
{
UtilPlayer.message(caller, F.main("Party", "Parties Help"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [help/h]") + " - Shows this help dialog"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [invite/i] [player]") + " - Invite [player] to your party"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [invites/is] (page)") + " - List your current pending invitations"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [kick/k] [player]") + " - Kick [player] from your party"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [accept/a] [player]") + " - Accept your invitation to [player]'s party"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [deny/d] [player]") + " - Deny your invitation to [player]'s party"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [leave/l]") + " - Leave your current party"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [disband/db]") + " - Disband your current party"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [transfer/tr] [player]") + " - Transfers ownership of the party to another player"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [gui/g]") + " - Opens the party GUI"));
UtilPlayer.message(caller, F.main("Party", F.elem("/party [toggle/t]") + " - Toggles between the GUI and the chat"));
}
}

View File

@ -0,0 +1,28 @@
package mineplex.core.party.command.cli;
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.party.PartyManager;
public class PartyInviteCommand extends CommandBase<PartyManager>
{
public PartyInviteCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "invite", "i");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 0)
{
UtilPlayer.message(caller, F.main("Party", "Oops. You didn't specify who to invite!"));
return;
}
Plugin.invite(caller, args[0]);
}
}

View File

@ -0,0 +1,200 @@
package mineplex.core.party.command.cli;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import org.apache.commons.lang.StringUtils;
import org.bukkit.entity.Player;
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;
import mineplex.core.party.InviteData;
import mineplex.core.party.PartyManager;
public class PartyInvitesCommand extends CommandBase<PartyManager>
{
private static int boostCount = 0;
public PartyInvitesCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "invites", "is");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 2 && args[0].equals("boost"))
{
boostCount = Integer.parseInt(args[1]);
return;
}
List<InviteData> invites = Plugin.getInviteManager().getAllInvites(caller);
invites.sort(Comparator.comparing(InviteData::getInviterName));
if (boostCount != 0)
{
invites = new ArrayList<>();
for (int i = 0; i < boostCount; i++)
{
invites.add(new InviteData("Player" + i, UUID.randomUUID(), UUID.randomUUID(), "Server" + i));
}
}
if (invites == null || invites.isEmpty())
{
UtilPlayer.message(caller, F.main("Party", "You have no pending invites!"));
return;
}
int totalPages = (int) Math.ceil(invites.size() / 8.0);
int page = 0;
if (args.length != 0)
{
try
{
page = Integer.parseInt(args[0]);
}
catch (NumberFormatException ex)
{
UtilPlayer.message(caller, F.main("Party", F.elem(args[0]) + " is not a number!"));
return;
}
page = page - 1;
if (page < 0)
{
UtilPlayer.message(caller, F.main("Party", "Page numbers must be greater than zero!"));
return;
}
else if (page >= totalPages)
{
UtilPlayer.message(caller, F.main("Party", "You only have " + F.elem(totalPages) + " pages of invites, that number is too big!"));
return;
}
}
String header = "[" +
ChatColor.RESET + C.cWhite + C.Bold + "Party Invites (" + (page + 1) + "/" + totalPages + ")" +
ChatColor.RESET + C.cAqua + C.Strike + "]";
int headerChars = ChatColor.stripColor(header).length();
int numEqualsInHeader = (50 - headerChars) / 2;
header = C.cAqua + C.Strike + StringUtils.repeat("=", numEqualsInHeader) + header + StringUtils.repeat("=", numEqualsInHeader);
caller.sendMessage(header);
int start = page * 8;
List<InviteData> subList = start < invites.size() ? invites.subList(start, Math.min(invites.size(), start + 8)) : Collections.emptyList();
for (InviteData data : subList)
{
BaseComponent[] hover = new ComponentBuilder("")
.append("Server: ")
.color(ChatColor.YELLOW)
.append(data.getServerName(), ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.WHITE)
.create();
ComponentBuilder builder = new ComponentBuilder("")
.append("Accept")
.color(ChatColor.GREEN)
.bold(true)
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Click to accept this invite").color(ChatColor.GREEN).create()))
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/party cli a " + data.getInviterName()))
.append(" - ", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.WHITE)
.append("Deny")
.color(ChatColor.RED)
.bold(true)
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Click to deny this invite").color(ChatColor.RED).create()))
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/party cli d " + data.getInviterName()))
.append(" - ", ComponentBuilder.FormatRetention.NONE)
.color(ChatColor.WHITE)
.append(data.getInviterName() + " invited you to their party")
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover))
.color(ChatColor.GRAY);
caller.spigot().sendMessage(builder.create());
}
int chars = ChatColor.stripColor(header).length();
int numEquals = (chars - 5) / 2; // 5 chars: " < > "
ComponentBuilder pageSwitch = new ComponentBuilder("")
.append(StringUtils.repeat("=", numEquals) + "[")
.strikethrough(true)
.color(ChatColor.AQUA)
.append(" ", ComponentBuilder.FormatRetention.NONE)
.append("<", ComponentBuilder.FormatRetention.NONE)
.bold(true);
if (page > 0)
{
BaseComponent[] prev = new ComponentBuilder("")
.append("Go to page " + page)
.color(ChatColor.GREEN)
.create();
pageSwitch
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/party is " + (page)))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, prev));
}
else
{
pageSwitch
.color(ChatColor.GRAY);
}
pageSwitch.append(" ", ComponentBuilder.FormatRetention.NONE)
.append(">", ComponentBuilder.FormatRetention.NONE)
.bold(true);
if (page + 1 < totalPages)
{
BaseComponent[] next = new ComponentBuilder("")
.append("Go to page " + (page + 2))
.color(ChatColor.GREEN)
.create();
pageSwitch
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/party is " + (page + 2)))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, next));
}
else
{
pageSwitch
.color(ChatColor.GRAY);
}
pageSwitch
.append(" ", ComponentBuilder.FormatRetention.NONE)
.append("]" + StringUtils.repeat("=", numEquals), ComponentBuilder.FormatRetention.NONE)
.strikethrough(true)
.color(ChatColor.AQUA);
caller.spigot().sendMessage(pageSwitch.create());
}
}

View File

@ -0,0 +1,29 @@
package mineplex.core.party.command.cli;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
public class PartyKickCommand extends CommandBase<PartyManager>
{
public PartyKickCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "kick", "k");
}
@Override
public void Execute(Player caller, String[] args)
{
Party party = Plugin.getPartyByPlayer(caller);
if (party != null)
{
if (party.getOwnerName().equals(caller.getName()))
{
Plugin.kickPlayer(caller, args[0]);
}
}
}
}

View File

@ -0,0 +1,21 @@
package mineplex.core.party.command.cli;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.party.PartyManager;
public class PartyLeaveCommand extends CommandBase<PartyManager>
{
public PartyLeaveCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "leave", "l");
}
@Override
public void Execute(Player caller, String[] args)
{
Plugin.leaveParty(caller);
}
}

View File

@ -0,0 +1,60 @@
package mineplex.core.party.command.cli;
import org.bukkit.Bukkit;
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.party.Lang;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
public class PartyTransferOwnerCommand extends CommandBase<PartyManager>
{
public PartyTransferOwnerCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "transfer", "tr");
}
@Override
public void Execute(Player caller, String[] args)
{
Party playerParty = Plugin.getPartyByPlayer(caller);
if (playerParty == null)
{
UtilPlayer.message(caller, F.main("Party", "Oops. You're not in a party!"));
return;
}
if (!playerParty.getOwner().getId().equals(caller.getUniqueId()))
{
UtilPlayer.message(caller, F.main("Party", "Oops. You're not the owner of the party!"));
return;
}
if (args.length == 0)
{
UtilPlayer.message(caller, F.main("Party", "Oops. You didn't specify who you're transferring the party to!"));
return;
}
Player player = Bukkit.getPlayer(args[0]);
if (player == null)
{
UtilPlayer.message(caller, F.main("Party", "Could not find " + F.elem(args[0]) + "!"));
return;
}
if (!playerParty.isMember(player))
{
UtilPlayer.message(caller, F.main("Party", "Oops. " + F.elem(player.getName())+ " is not in your party!"));
return;
}
playerParty.setOwner(player);
Lang.TRANSFER_OWNER.send(playerParty, caller.getName(), player.getName());
}
}

View File

@ -0,0 +1,29 @@
package mineplex.core.party.command.gui;
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.party.PartyManager;
public class PartyGUIAcceptInviteCommand extends CommandBase<PartyManager>
{
public PartyGUIAcceptInviteCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "partyaccept", "accept", "a");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 0)
{
UtilPlayer.message(caller, F.main("Party", "Oops. You didn't specify whose invite you're accepting!"));
return;
}
Plugin.acceptInviteBySender(caller, args[0]);
}
}

View File

@ -0,0 +1,28 @@
package mineplex.core.party.command.gui;
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.party.PartyManager;
public class PartyGUIDenyInviteCommand extends CommandBase<PartyManager>
{
public PartyGUIDenyInviteCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "partydeny", "deny", "d");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 0)
{
UtilPlayer.message(caller, F.main("Party", "Oops. You didn't specify whose invite you're denying!"));
return;
}
Plugin.denyInviteBySender(caller, args[0]);
}
}

View File

@ -0,0 +1,29 @@
package mineplex.core.party.command.gui;
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.party.Party;
import mineplex.core.party.PartyManager;
public class PartyGUIInviteCommand extends CommandBase<PartyManager>
{
public PartyGUIInviteCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "partyinvite", "invite", "i");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 0)
{
UtilPlayer.message(caller, F.main("Party", "Oops. You didn't specify who to invite!"));
return;
}
Plugin.invite(caller, args[0]);
}
}

View File

@ -0,0 +1,23 @@
package mineplex.core.party.command.gui;
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.party.PartyManager;
public class PartyGUILeaveCommand extends CommandBase<PartyManager>
{
public PartyGUILeaveCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "leave", "l");
}
@Override
public void Execute(Player caller, String[] args)
{
Plugin.leaveParty(caller);
}
}

View File

@ -0,0 +1,22 @@
package mineplex.core.party.command.gui;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.party.PartyManager;
import mineplex.core.party.ui.menus.PartyInvitesMenu;
public class PartyOpenInviteMenuCommand extends CommandBase<PartyManager>
{
public PartyOpenInviteMenuCommand(PartyManager plugin)
{
super(plugin, Rank.ALL, "openinvitesmenu", "invitesmenu", "im", "invites", "is");
}
@Override
public void Execute(Player caller, String[] args)
{
new PartyInvitesMenu(Plugin).open(caller);
}
}

View File

@ -1,27 +0,0 @@
package mineplex.core.party.constants;
import mineplex.core.common.util.F;
/**
*
*/
public enum InviteResponse
{
ACCEPTED("{0} has joined the party!"),
DENIED("{0} has declined joining your party."),
EXPIRED("{0} did not respond in time.");
private String _message;
InviteResponse(String message)
{
_message = message;
}
public String format(String target)
{
return _message.replace("{0}", F.name(target));
}
}

View File

@ -1,26 +0,0 @@
package mineplex.core.party.constants;
import mineplex.core.common.util.F;
/**
*
*/
public enum JoinResponseReason
{
CANNOT_JOIN_FULL(F.main("Party", "Your party cannot join full servers!")),
SUCCESS("");
private String _message;
JoinResponseReason(String message)
{
_message = message;
}
public String getMessage()
{
return _message;
}
}

View File

@ -1,37 +0,0 @@
package mineplex.core.party.event;
import mineplex.core.party.Party;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* An event called when a server receives a PartyPacket containing the information about a party
*/
public class PartyDataReceivedEvent extends Event
{
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Party _party;
public PartyDataReceivedEvent(Party party)
{
_party = party;
}
public Party getParty()
{
return _party;
}
@Override
public HandlerList getHandlers()
{
return HANDLER_LIST;
}
public static HandlerList getHandlerList()
{
return HANDLER_LIST;
}
}

View File

@ -1,51 +0,0 @@
package mineplex.core.party.event;
import mineplex.core.party.Party;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* This event is called when an owner clicks a PartyMemberIcon while having Kick mode activated.
*/
public class PartyMemberKickGUIEvent extends Event
{
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Party _party;
private final String _playerClicked;
private final Player _owner;
public PartyMemberKickGUIEvent(Party party, String playerClicked, Player owner)
{
_party = party;
_playerClicked = playerClicked;
_owner = owner;
}
public String getPlayerClicked()
{
return _playerClicked;
}
public Player getOwner()
{
return _owner;
}
public Party getParty()
{
return _party;
}
@Override
public HandlerList getHandlers()
{
return HANDLER_LIST;
}
public static HandlerList getHandlerList()
{
return HANDLER_LIST;
}
}

View File

@ -1,44 +0,0 @@
package mineplex.core.party.event;
import mineplex.core.party.Party;
import mineplex.serverdata.data.MinecraftServer;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
*
*/
public class PartySendToServerEvent extends Event
{
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Party _party;
private final MinecraftServer _minecraftServer;
public PartySendToServerEvent(Party party, MinecraftServer minecraftServer)
{
_party = party;
_minecraftServer = minecraftServer;
}
public Party getParty()
{
return _party;
}
@Override
public HandlerList getHandlers()
{
return HANDLER_LIST;
}
public static HandlerList getHandlerList()
{
return HANDLER_LIST;
}
public MinecraftServer getMinecraftServer()
{
return _minecraftServer;
}
}

View File

@ -1,65 +0,0 @@
package mineplex.core.party.event;
import mineplex.core.party.Party;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* An event called when an owner leaves a party
*/
public class PartyTransferOwnerEvent extends Event
{
public enum TransferReason
{
LEFT,
TRANSFER;
}
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Party _party;
private final String _newOwner;
private final String _oldOwner;
private final TransferReason _reason;
public PartyTransferOwnerEvent(Party party, String newOwner, String oldOwner, TransferReason reason)
{
_party = party;
_newOwner = newOwner;
_oldOwner = oldOwner;
_reason = reason;
}
public String getNewOwner()
{
return _newOwner;
}
public String getOldOwner()
{
return _oldOwner;
}
public TransferReason getReason()
{
return _reason;
}
public Party getParty()
{
return _party;
}
@Override
public HandlerList getHandlers()
{
return HANDLER_LIST;
}
public static HandlerList getHandlerList()
{
return HANDLER_LIST;
}
}

View File

@ -1,358 +1,247 @@
package mineplex.core.party.manager;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.party.InviteData;
import mineplex.core.party.Lang;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.core.party.constants.InviteResponse;
import mineplex.core.party.redis.RedisMessageType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ClickEvent.Action;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import org.spigotmc.CaseInsensitiveMap;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.party.InviteData;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
/**
*
* This class manages invites to parties
*/
public class PartyInviteManager
{
// Map of Player Name (invitee) to invites (inviter)
private final Map<String, Set<InviteData>> _activeInvites = new CaseInsensitiveMap<>();
private final Map<UUID, List<InviteData>> _activeInvites = Maps.newHashMap();
private final Map<UUID, String> _invitedBy = Maps.newHashMap();
private final Map<UUID, String> _awaitingJoin = Maps.newHashMap();
private final Map<UUID, String> _players = Maps.newHashMap();
private final Map<UUID, BukkitTask> _tasks = Maps.newHashMap();
private final Map<UUID, BukkitTask> _tasks = new HashMap<>();
private final PartyManager _plugin;
private final PartyRedisManager _partyRedisManager;
public PartyInviteManager(PartyManager plugin, PartyRedisManager partyRedisManager)
public PartyInviteManager(PartyManager plugin)
{
_plugin = plugin;
_partyRedisManager = partyRedisManager;
}
public InviteData getInviteBySender(String invitee, String sender)
{
Set<InviteData> map = _activeInvites.get(invitee);
if (map == null) return null;
for (InviteData inviteData : map)
{
if (inviteData.getInviterName().equalsIgnoreCase(sender))
{
return inviteData;
}
}
return null;
}
/**
* Responds to an invite, regardless of the server
* Checks if a caller has an invite by a sender's name
*
* @param player The player calling
* @param party The party
* @param accept Whether or not the player accepted the invite
* @param caller
* @param sender
* @return
*/
public void respondToInvite(Player player, String party, boolean accept)
public boolean hasInviteFrom(Player caller, String sender)
{
Player possible = Bukkit.getPlayerExact(party);
InviteData data = remove(party, player.getUniqueId());
_players.remove(player.getUniqueId());
cancelTask(player.getUniqueId());
if(possible != null)
{
Party newParty = _plugin.getParty(party);
if(!accept)
{
String message = C.mHead + "Party> " + C.mBody + InviteResponse.DENIED.format(player.getName());
if (newParty == null)
{
possible.sendMessage(message);
return;
}
newParty.sendMessage(message);
return;
}
if (newParty == null)
{
newParty = new Party(possible.getName());
if(_plugin.getClientManager().Get(possible).GetRank().has(Rank.ULTRA))
{
newParty.setSize();
} else
{
newParty.setSize();
}
_plugin.addParty(newParty);
_plugin.getMethodManager().addToParty(possible.getUniqueId(), newParty);
}
_plugin.getMethodManager().addToParty(player.getUniqueId(), newParty);
return;
}
String serverFrom = data.getServerFrom();
if(accept)
{
_plugin.getPortal().sendPlayerToServer(player, serverFrom);
}
_partyRedisManager.publish(serverFrom, RedisMessageType.INVITE_PLAYER_RESPONSE, party,
player.getName(), player.getUniqueId().toString(), accept ? InviteResponse.ACCEPTED.name() : InviteResponse.DENIED.name());
return getInviteBySender(caller.getName(), sender) != null;
}
/**
* Handles a received response via redis
* Checks if a caller has an invite by a party id
*
* @param sender The player sending the request
* @param target The player target
* @param serverFrom The server initiating the request
* @param caller
* @param partyId
* @return
*/
public void handleInviteRequest(String sender, String target, String serverFrom)
public boolean hasInviteTo(String caller, UUID partyId)
{
Player player = Bukkit.getPlayerExact(target);
if (player == null)
Set<InviteData> map = _activeInvites.get(caller);
if (map == null) return false;
for (InviteData inviteData : map)
{
//Shouldn't happen, as a "findPLayer" packet will be sent out first.
return;
if (inviteData.getPartyUUID().equals(partyId))
{
return true;
}
_players.put(player.getUniqueId(), player.getName());
inviteTo(player.getUniqueId(), sender, sender, serverFrom);
Lang.INVITE_RECEIVED.send(player, sender);
sendAcceptOrDeny(player, sender);
player.playSound(player.getLocation(), Sound.NOTE_PLING, 1.0F, 1.0F);
}
return false;
}
/**
* Handles the response returned via redis when an invite is handled cross server
* Remove a player's invite to a party by id
*
* @param sender The player sender
* @param target The player target
* @param targetUUID The player targets UUID
* @param response The response to this invite
* @param caller
* @param partyId
* @return
*/
public void handleInviteResponse(String sender, String target, UUID targetUUID, InviteResponse response)
public InviteData removeInviteTo(String caller, UUID partyId)
{
remove(sender, targetUUID);
Player player = Bukkit.getPlayer(sender);
if (player == null)
{
return;
}
String message = F.main("Party", response.format(target));
Set<InviteData> map = _activeInvites.get(caller);
Party party = _plugin.getParty(sender);
String partyName = sender;
if(party != null)
if (map == null) return null;
Iterator<InviteData> itr = map.iterator();
while (itr.hasNext())
{
partyName = party.getName();
InviteData ent = itr.next();
if (ent.getPartyUUID().equals(partyId))
{
itr.remove();
return ent;
}
}
switch (response)
{
case ACCEPTED:
addToPendingJoin(targetUUID, partyName);
break;
case EXPIRED:
case DENIED:
if (party == null)
{
player.sendMessage(message);
return;
return null;
}
party.sendMessage(message);
break;
/**
* Remove a player's invite to a certain party
*/
public InviteData removeInvite(Player invitee, String inviter)
{
Set<InviteData> map = _activeInvites.get(invitee.getName());
if (map == null) return null;
Iterator<InviteData> itr = map.iterator();
while (itr.hasNext())
{
InviteData ent = itr.next();
if (ent.getInviterName().equalsIgnoreCase(inviter))
{
itr.remove();
return ent;
}
}
return null;
}
/**
* Remove all references tied with this player
*
* @param player The player's UUID
*/
public void removeAll(UUID player)
public void removeAll(Player player)
{
_players.remove(player);
_invitedBy.remove(player);
_activeInvites.remove(player);
}
/**
* Get the name of the party who is awaiting this player to join
*
* @param player The player's UUID
* @return The name of the awaiting party.
*/
public String getPartyWaiting(UUID player)
{
return _awaitingJoin.get(player);
}
/**
* Remove the party reference that invited this player
*
* @param player The player's UUID
*/
public void removeFromWaiting(UUID player)
{
_awaitingJoin.remove(player);
}
/**
* Add a player to the active invites map
*
* @param player The player who has been invited
* @param party The party name
*/
public void inviteTo(UUID player, String invitedBy, String party, String server)
{
addToInvite(player, invitedBy, party, server);
_tasks.put(player, new BukkitRunnable()
{
@Override
public void run()
{
if (!isInvitedTo(player, party))
{
cancel();
return;
}
InviteData data = remove(party, player);
Player possible = Bukkit.getPlayer(player);
String playerName = _players.remove(player);
if (possible != null)
{
playerName = possible.getName();
possible.sendMessage(F.main("Party", "Your invite to " + F.name(party) + "'s party has expired"));
}
sendExpired(data.getServerFrom(), party, playerName, player);
}
}.runTaskLater(_plugin.getPlugin(), 20 * 60));
}
/**
* Checks to see if a player is invited to a specific party
*
* @param player The player who we want to check against
* @param party The name of the party to check
* @return <code>true</code> if the player has an invite to the specific party
*/
public boolean isInvitedTo(UUID player, String party)
{
if (!_activeInvites.containsKey(player))
{
return false;
}
List<InviteData> dataList = _activeInvites.get(player);
for (InviteData data : dataList)
{
if (data.getInvitedTo().equalsIgnoreCase(party))
{
return true;
}
}
return false;
}
/**
* Remove a player's invite to a certain party
*
* @param party The name of the party
* @param invited The UUID of the player
*/
public InviteData remove(String party, UUID invited)
{
List<InviteData> data = _activeInvites.get(invited);
InviteData temp = null;
for (InviteData inviteData : data)
{
if (inviteData.getInvitedTo().equalsIgnoreCase(party))
{
temp = inviteData;
break;
}
}
if (temp != null)
{
data.remove(temp);
}
_activeInvites.put(invited, data);
return temp;
}
/**
* Stop the player's expired task from running
*
* @param player The UUID of the player
*/
public void cancelTask(UUID player)
{
BukkitTask task = _tasks.remove(player);
if(task != null)
{
task.cancel();
}
_activeInvites.remove(player.getName());
}
/**
* Retrieves all invites currently pending for a specific player
*
* @param player The player
* @return All his current pending invites
*/
public Collection<InviteData> getAllInvites(Player player)
public List<InviteData> getAllInvites(Player player)
{
return _activeInvites.get(player.getUniqueId());
return new ArrayList<>(_activeInvites.getOrDefault(player.getName(), Collections.emptySet()));
}
/**
* Send an "ExpiredPartyInvite" redis message
* Add a playerUUID to the active invites map
*
* @param server The server to
* @param party The party who initiated the request (can also be a player's name)
* @param playerName The name of the invited player
* @param player The invited player's UUID
* @param inviterName
* @param inviterUUID
*/
private void sendExpired(String server, String party, String playerName, UUID player)
public void inviteTo(String targetName, UUID targetUUID, String inviterName, UUID inviterUUID, UUID partyId, String server)
{
_plugin.getRedisManager().publish(server, RedisMessageType.INVITE_PLAYER_RESPONSE, party, playerName, player.toString(), InviteResponse.EXPIRED.name());
Set<InviteData> map = _activeInvites.computeIfAbsent(targetName, key -> new HashSet<>());
InviteData inviteData = new InviteData(inviterName, inviterUUID, partyId, server);
if (map.add(inviteData))
{
_tasks.put(targetUUID, _plugin.runSyncLater(new BukkitRunnable()
{
@Override
public void run()
{
if (!hasInviteTo(targetName, partyId))
{
cancel();
return;
}
InviteData data = removeInviteTo(targetName, partyId);
Player possible = Bukkit.getPlayer(targetUUID);
if (possible != null)
{
Party curParty = _plugin.getPartyById(partyId);
if (curParty != null)
{
possible.sendMessage(F.main("Party", "Your invite to " + F.name(inviterName) + "'s party has expired"));
}
else
{
UtilPlayer.message(possible, F.main("Party", "Your invite to " + F.name(inviterName) + "'s party has expired. Fortunately, that party no longer exists"));
}
}
}
}, 20 * 60));
}
/**
* Marks this player as having an accepted invite
* This is used to control the creation of single player parties, and makes sure a party is created ONLY if a player joins the server successfully.
*
* @param player The UUID of the player
* @param party The name of the party
*/
private void addToPendingJoin(UUID player, String party)
Player player = Bukkit.getPlayer(targetUUID);
if (player != null)
{
_awaitingJoin.put(player, party);
Party party = _plugin.getPartyByPlayer(player);
if (party == null)
{
if (server.equals(UtilServer.getServerName()))
{
UtilPlayer.message(player, F.main("Party", "You have been invited to " + F.elem(inviterName) + "'s party! You have 60 seconds to reply"));
}
/**
* Add a pending invite for a player
*
* @param invited The invited players UUUD
* @param invitedBy The person who invited him
* @param party The name of the party invited to
* @param server The server the request is from
*/
private void addToInvite(UUID invited, String invitedBy, String party, String server)
else
{
List<InviteData> inviteDatas = _activeInvites.get(invited);
if (inviteDatas == null)
{
inviteDatas = Lists.newArrayList();
UtilPlayer.message(player, F.main("Party", "You have been invited to " + F.elem(inviterName) + "'s party! You have 60 seconds to reply. If you accept, you will be be sent to " + F.elem(server)));
}
}
else
{
if (server.equals(UtilServer.getServerName()))
{
UtilPlayer.message(player, F.main("Party", "You have been invited to " + F.elem(inviterName) + "'s party! You have 60 seconds to reply. If you accept, you will leave your current party"));
}
else
{
UtilPlayer.message(player, F.main("Party", "You have been invited to " + F.elem(inviterName) + "'s party! You have 60 seconds to reply. If you accept, you will leave your current party and you will be be sent to " + F.elem(server)));
}
}
sendAcceptOrDeny(player, inviterName);
}
InviteData inviteData = new InviteData(party, server);
inviteDatas.add(inviteData);
_invitedBy.put(invited, invitedBy);
_activeInvites.put(invited, inviteDatas);
}
/**
@ -361,16 +250,16 @@ public class PartyInviteManager
* @param player The player who received the invite
* @param arg The name of the inviting party
*/
public void sendAcceptOrDeny(Player player, String arg)
private void sendAcceptOrDeny(Player player, String arg)
{
TextComponent textComponent = new TextComponent(F.main("Party", "Reply: "));
TextComponent accept = new TextComponent("ACCEPT");
accept.setColor(ChatColor.GREEN);
accept.setBold(true);
accept.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/partyaccept " + arg));
accept.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/party cli a " + arg));
accept.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{
new TextComponent("Click to join " + F.name(arg) + "'s party")
new TextComponent("Click to join " + F.name(arg) + ChatColor.WHITE + "'s party")
}));
textComponent.addExtra(accept);
@ -379,9 +268,9 @@ public class PartyInviteManager
TextComponent deny = new TextComponent("DENY");
deny.setColor(ChatColor.RED);
deny.setBold(true);
deny.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/partydeny " + arg));
deny.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/party cli d " + arg));
deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{
new TextComponent("Click to decline joining " + F.name(arg) + "'s party")
new TextComponent("Click to decline joining " + F.name(arg) + ChatColor.WHITE + "'s party")
}));
textComponent.addExtra(deny);
@ -390,13 +279,14 @@ public class PartyInviteManager
TextComponent view = new TextComponent("VIEW");
view.setColor(ChatColor.YELLOW);
view.setBold(true);
view.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/openinvitesmenu"));
view.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/party cli is"));
view.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{
new TextComponent("Click to view all pending invites.")
new TextComponent("Click to view all pending invites")
}));
textComponent.addExtra(view);
player.spigot().sendMessage(textComponent);
player.playSound(player.getLocation(), Sound.NOTE_PLING, 1.0F, 10.0F);
}
}

View File

@ -1,57 +1,140 @@
package mineplex.core.party.manager;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
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.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitTask;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import mineplex.core.command.CommandCenter;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.party.Lang;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.core.party.constants.JoinResponseReason;
import mineplex.core.party.redis.RedisMessageType;
import mineplex.serverdata.servers.ServerManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import mineplex.core.party.constants.PartyRemoveReason;
import mineplex.core.party.rediscommands.PartyTransferRequest;
import mineplex.core.party.rediscommands.PartyTransferResponse;
import mineplex.core.portal.Intent;
import mineplex.core.portal.events.GenericServerTransferEvent;
import mineplex.core.portal.events.ServerTransferEvent;
import mineplex.core.utils.UtilGameProfile;
import mineplex.serverdata.commands.ServerCommandManager;
import mineplex.serverdata.data.MinecraftServer;
/**
* Manages allocating slots for parties to join
*/
public class PartyJoinManager
public class PartyJoinManager implements Listener
{
private final PartyManager _plugin;
private final int _maxPLayers;
private final List<UUID> _transferring;
private final int _maxPlayers;
private final Map<UUID, BukkitTask> _pendingTransfers = new ConcurrentHashMap<>();
public PartyJoinManager(PartyManager plugin)
{
_plugin = plugin;
_maxPLayers = plugin.getPlugin().getServer().getMaxPlayers();
_transferring = Lists.newArrayList();
_maxPlayers = plugin.getPlugin().getServer().getMaxPlayers();
UtilServer.RegisterEvents(this);
ServerCommandManager.getInstance().registerCommandType(PartyTransferRequest.class, command ->
{
if (!command.isSentToThisServer())
return;
_plugin.runSync(() ->
{
int currentPlayers = UtilServer.getPlayersCollection().size();
if (currentPlayers + command.getUnrankedMembers().size() > _maxPlayers && !command.isCanJoinFullServers())
{
ServerCommandManager.getInstance().publishCommand(new PartyTransferResponse(command, PartyTransferResponse.Result.NOT_ENOUGH_ROOM));
return;
}
/**
* Scans through the party to check if all players are some form of VIP
* If the party contains even 1 non-vip, the party cannot be sent to a full server
*
* @param party The party
* @return <code>true</code> if the party contains all VIP's <code>false</code> if it contains even 1 non-vip
*/
public boolean canJoinFullServer(Party party)
for (UUID uuid : command.getUnrankedMembers())
{
List<Player> players = party.getMembersByUUID().stream().map(Bukkit::getPlayer).collect(Collectors.toList());
for (Player player : players)
{
Rank rank = _plugin.getClientManager().Get(player).GetRank();
if (rank == Rank.ALL)
{
return false;
_plugin.getClientManager().reserveFor(uuid);
}
Party newParty = new Party(command);
_plugin.addParty(newParty);
for (UUID uuid : command.getAllMembers())
{
_plugin.putIntoPendingJoin(uuid, newParty.getUniqueId());
}
return true;
ServerCommandManager.getInstance().publishCommand(new PartyTransferResponse(command, PartyTransferResponse.Result.SUCCESS));
});
});
ServerCommandManager.getInstance().registerCommandType(PartyTransferResponse.class, command ->
{
if (!command.getOrigin().wasSentFromThisServer())
return;
_plugin.runSync(() ->
{
BukkitTask task = _pendingTransfers.get(command.getOrigin().getPartyUUID());
if (task == null)
{
return;
}
task.cancel();
Party party = _plugin.getPartyById(command.getOrigin().getPartyUUID());
switch (command.getResult())
{
case NOT_ENOUGH_ROOM:
_pendingTransfers.remove(command.getOrigin().getPartyUUID());
party.sendMessage(F.main("Party", "Sorry, there wasn't enough room for your party in " + F.elem(command.getFromServer()) + "."));
break;
case SUCCESS:
party.sendMessage(F.main("Party", "Success! I've reserved some room for you in " + F.elem(command.getFromServer()) + "."));
party.sendMessage(F.main("Party", "You will be transferred shortly."));
List<Player> members = new ArrayList<>(party.getMembers());
// Clear the party first.
// We've already got a duplicate on the remote server so let's get rid of this one ASAP
party.clear();
_plugin.removeParty(party);
for (Player player : members)
{
_plugin.getPortal().sendPlayer(player, command.getFromServer());
}
break;
case UNKNOWN:
_pendingTransfers.remove(command.getOrigin().getPartyUUID());
party.sendMessage(F.main("Party", "Uh... something went wrong?"));
break;
}
});
});
}
/**
@ -60,78 +143,214 @@ public class PartyJoinManager
* @param server The desired server
* @param party The requesting party
*/
public void requestServerJoin(String server, Party party)
private void requestServerJoin(String server, Party party)
{
boolean canJoinFull = canJoinFullServer(party);
_plugin.getRedisManager().publish(server, RedisMessageType.PREJOIN_SERVER_REQUEST,
_plugin.getServerName(), party.getOwner(), "" + party.getMembers().size(), "" + canJoinFull);
}
/**
* Manages a received request
*
* @param serverFrom The server who initiated the request
* @param partySize The size of the party
* @param initiator The player who sent the request
* @param canJoinFull <code>true</code> if the party contains all donators or staff (full joining able players)
*/
public void handleJoinRequest(String serverFrom, int partySize, String initiator, boolean canJoinFull)
if (_pendingTransfers.containsKey(party.getUniqueId()))
{
int currentPlayers = UtilServer.getPlayers().length;
if (currentPlayers >= _maxPLayers || (currentPlayers + partySize) >= _maxPLayers)
{
//Max number of people on.
if (!canJoinFull)
{
_plugin.getRedisManager().publish(serverFrom, RedisMessageType.PREJOIN_SERVER_RESPONSE, initiator, JoinResponseReason.CANNOT_JOIN_FULL.name(), _plugin.getServerName());
party.sendMessage(F.main("Party", "Please wait until your current transfer is complete"));
return;
}
}
ServerManager.getServerRepository(_plugin.getRegion()).getServerStatus(_plugin.getServerName()).incrementPlayerCount(partySize);
_plugin.getRedisManager().publish(serverFrom, RedisMessageType.PREJOIN_SERVER_RESPONSE, initiator, JoinResponseReason.SUCCESS.name(), _plugin.getServerName());
}
/**
* Manages a received response
*
* @param playerSender The player who sent the request
* @param server The server responding
* @param reason The reason for the response
*/
public void handleJoinResponse(String playerSender, String server, JoinResponseReason reason)
List<UUID> unranked = new ArrayList<>();
List<UUID> all = new ArrayList<>();
for (Player player : party.getMembers())
{
Player player = Bukkit.getPlayer(playerSender);
if (player == null)
if (_plugin.getClientManager().Get(player).GetRank() == Rank.ALL)
{
unranked.add(player.getUniqueId());
}
all.add(player.getUniqueId());
}
_pendingTransfers.put(party.getUniqueId(), _plugin.runSyncLater(() ->
{
_pendingTransfers.remove(party.getUniqueId());
if (party.getMembers().size() == 0)
{
return;
}
Party party = _plugin.getParty(player);
party.sendMessage(F.main("Party", "Aww, the destination server didn't respond :("));
}, 20 * 5L));
System.out.println("Sending transfer request to " + server + " for " + party.getUniqueId() + " " + party.getMembers());
party.sendMessage(F.main("Party", "Please wait while I check whether " + F.elem(server) + " has enough room for this party."));
ServerCommandManager.getInstance().publishCommand(new PartyTransferRequest(party.getUniqueId(), UtilGameProfile.getGameProfile(party.getOwnerAsPlayer().get()), all, unranked, unranked.size() == 0, server));
}
@EventHandler
public void onTransferToGenericServer(GenericServerTransferEvent event)
{
Player player = event.getPlayer();
Party party = _plugin.getPartyByPlayer(player);
if (party == null)
{
return;
}
if (reason != JoinResponseReason.SUCCESS)
// If the server wants to kick the player, let's not stop it
if (event.getIntent() == Intent.KICK || event.getIntent() == Intent.FORCE_TRANSFER)
{
party.sendMessage(reason.getMessage());
_plugin.removeFromParty(event.getPlayer(), PartyRemoveReason.KICKED);
return;
}
party.sendMessage(F.main("Party", "Transferring servers..."));
_plugin.getRedisManager().sendPartyInfo(server, party);
_transferring.addAll(party.getMembersByUUID());
}
/**
* Retrieve whether or not the player is currently transferring servers
* We wont need this information again, so calling a remove works fine.
*
* @param player The player
* @return <code>true</code> if the player is transferring servers
*/
public boolean isTransferring(Player player)
event.setCancelled(true);
if (!party.getOwnerName().equalsIgnoreCase(player.getName()))
{
return _transferring.remove(player.getUniqueId());
Lang.NOT_OWNER_SERVER.send(player);
return;
}
MinecraftServer best = null;
int lowest = Integer.MAX_VALUE;
List<MinecraftServer> serverList = Lists.newArrayList(_plugin.getPortal().getRepository().getServersByGroup(event.getServer().getName()));
for (MinecraftServer server : serverList)
{
int playercount = server.getPlayerCount();
if (playercount < 20)
{
continue;
}
if (playercount < lowest)
{
lowest = playercount;
if (best == null)
{
best = server;
}
}
}
if (best == null)
{
best = serverList.get(new Random().nextInt(serverList.size()));
}
party.sendMessage(F.main("Party", F.elem(player.getName()) + " is moving the party to " + F.elem(best.getName())));
requestServerJoin(best.getName(), party);
}
@EventHandler
public void onTransfer(ServerTransferEvent event)
{
Player player = event.getPlayer();
Party party = _plugin.getPartyByPlayer(player);
if (party == null)
{
return;
}
// If the server wants to kick the player, let's not stop it
if (event.getIntent() == Intent.KICK || event.getIntent() == Intent.FORCE_TRANSFER)
{
_plugin.removeFromParty(event.getPlayer(), PartyRemoveReason.KICKED);
return;
}
if (_pendingTransfers.containsKey(party.getUniqueId()))
{
return;
}
event.setCancelled(true);
if (event.getServer().toUpperCase().startsWith("CLANS-"))
{
party.sendMessage(F.main("Party", "You cannot join a Clans server while in a party!"));
return;
}
if (!party.getOwnerName().equalsIgnoreCase(player.getName()))
{
Lang.NOT_OWNER_SERVER.send(player);
return;
}
party.sendMessage(F.main("Party", F.elem(player.getName()) + " is moving the party to " + F.elem(event.getServer())));
requestServerJoin(event.getServer(), party);
}
public void removePendingJoin(Party party)
{
_pendingTransfers.remove(party.getUniqueId());
}
@EventHandler
public void onJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();
if (_plugin.hasPendingJoin(player))
{
Party pendingParty = _plugin.getPendingParty(player);
_plugin.removePendingJoin(player);
if (pendingParty == null)
{
UtilPlayer.message(player, F.main("Party", "Uh oh. It seems that in the time it took for you to join this server, your inviter has disbanded their party"));
return;
}
if (pendingParty.getOwner().getId().equals(event.getPlayer().getUniqueId()))
{
UtilPlayer.message(player, F.main("Party", "Welcome back! Your party is just as you've left it!"));
}
else
{
UtilPlayer.message(player, F.main("Party", "Welcome! Adding you to " + F.elem(pendingParty.getOwnerName()) + "'s party!"));
}
_plugin.addToParty(player, pendingParty);
}
}
@EventHandler
public void onQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
Party party = _plugin.getPartyByPlayer(player);
_plugin.getInviteManager().removeAll(player);
if (party == null)
{
return;
}
PartyRemoveReason reason = PartyRemoveReason.LEFT;
_plugin.removeFromParty(player, reason);
}
@EventHandler(priority = EventPriority.LOWEST)
public void onInteract(PlayerInteractEntityEvent event)
{
if (UtilItem.isSimilar(event.getPlayer().getItemInHand(), PartyManager.INTERFACE_ITEM, UtilItem.ItemAttribute.NAME))
{
event.setCancelled(true);
event.getPlayer().updateInventory();
CommandCenter.getCommands().get("party").Execute(event.getPlayer(), new String[0]);
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onClick(PlayerInteractEvent event)
{
if (UtilItem.isSimilar(event.getItem(), PartyManager.INTERFACE_ITEM, UtilItem.ItemAttribute.NAME))
{
event.setCancelled(true);
CommandCenter.getCommands().get("party").Execute(event.getPlayer(), new String[0]);
}
}
}

View File

@ -1,347 +0,0 @@
package mineplex.core.party.manager;
import com.google.common.collect.Lists;
import mineplex.core.common.util.F;
import mineplex.core.menu.Menu;
import mineplex.core.party.Lang;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.core.party.constants.PartyRemoveReason;
import mineplex.core.preferences.Preference;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.UUID;
/**
* Contains all methods used by the internal UI system
*/
public class PartyMethodManager
{
private PartyManager _plugin;
public PartyMethodManager(PartyManager plugin)
{
_plugin = plugin;
}
/**
* Invite a player to either a new party or existing one
*
* @param caller The player who initiated the request
* @param target The player's target
*/
public void invite(Player caller, String target)
{
Player possible = Bukkit.getPlayer(target);
Party party = _plugin.getParty(caller);
if(target.equalsIgnoreCase(caller.getName()))
{
caller.sendMessage(F.main("Party", "You cannot invite yourself!"));
return;
}
if(party != null)
{
if(!party.getOwner().equalsIgnoreCase(caller.getName()))
{
Lang.NOT_OWNER.send(caller);
return;
}
if(possible != null && _plugin.getInviteManager().isInvitedTo(possible.getUniqueId(), party.getName()))
{
Lang.ALREADY_INVITED.send(caller, target);
return;
}
if(party.getMembers().contains(target))
{
Lang.ALREADY_MEMBER.send(caller, target);
return;
}
if(_plugin.getParty(target) != null)
{
Lang.PLAYER_IN_DIFFERENT_PARTY.send(caller, target);
return;
}
if(party.getMembers().size() >= party.getSize())
{
Lang.PARTY_FULL.send(caller);
return;
}
}
//Same Server
if (possible != null)
{
if(!_plugin.getPreferencesManager().get(possible).isActive(Preference.PARTY_REQUESTS))
{
caller.sendMessage(F.main("Party> ", F.name(target) + " is not accepting invites at this time."));
return;
}
if (party == null)
{
if(_plugin.getParty(target) != null)
{
Lang.PLAYER_IN_DIFFERENT_PARTY.send(caller, target);
return;
}
if(_plugin.getInviteManager().isInvitedTo(possible.getUniqueId(), caller.getName()))
{
Lang.ALREADY_INVITED.send(caller, target);
return;
}
Lang.INVITE_SUCCESS_PLAYER.send(caller, possible.getName());
} else
{
Lang.SUCCESS_INVITE.send(party, caller.getName(), target);
}
UUID uuid = possible.getUniqueId();
Lang.INVITE_RECEIVED.send(possible, caller.getName(), caller.getName());
_plugin.getInviteManager().inviteTo(uuid, caller.getName(), caller.getName(), _plugin.getServerName());
_plugin.getInviteManager().sendAcceptOrDeny(possible, caller.getName());
return;
}
//Only perform this when I actually need to.
boolean can = Bukkit.getMaxPlayers() >= _plugin.getPlugin().getServer().getOnlinePlayers().size();
if(!can)
{
Lang.SERVER_FULL.send(caller);
return;
}
//Not on the same server
_plugin.getRedisManager().findAndInvite(target, caller.getName());
}
/**
* Responds to a pending invite
*
* @param caller The player who initiated the request
* @param target The player's target
* @param accept <code>true</code> If the player has accepted the invite
*/
public void respondToInvite(Player caller, String target, boolean accept)
{
if(_plugin.getParty(caller) != null)
{
Lang.ALREADY_IN.send(caller);
caller.sendMessage(F.main("Party", "Please leave your party before joining!"));
return;
}
PartyInviteManager inviteManager = _plugin.getInviteManager();
if (!inviteManager.isInvitedTo(caller.getUniqueId(), target))
{
//He isn't invited to this party.
Lang.NOT_INVITED.send(caller, target);
return;
}
if(!accept)
{
caller.sendMessage(F.main("Party", "You have denied the invite to " + F.name(target)) + "'s party.");
}
inviteManager.respondToInvite(caller, target, accept);
}
/**
* Kicks a player from the callers party
*
* @param caller The player who initiated the request
* @param target The player's target
*/
public void forceRemove(Player caller, String target)
{
Party party = _plugin.getParty(caller);
if (party == null)
{
Lang.NO_PARTY.send(caller);
return;
}
if (!party.getOwner().equalsIgnoreCase(caller.getName()))
{
Lang.NOT_OWNER.send(caller);
return;
}
Player playerTarget = Bukkit.getPlayerExact(target);
if (playerTarget == null)
{
Lang.NOT_MEMBER.send(caller, target);
return;
}
Party targetParty = _plugin.getParty(playerTarget);
if (targetParty == null ||!party.getMembers().contains(target))
{
Lang.NOT_MEMBER.send(caller, target);
return;
}
removeFromParty(playerTarget.getUniqueId(), PartyRemoveReason.KICKED);
Lang.REMOVE_PLAYER_KICK.send(targetParty);
}
/**
* Leaves the players current party if he is in one
*
* @param caller The player who wishes to leave his party
*/
public void leaveParty(Player caller)
{
Party party = _plugin.getParty(caller);
if (party == null)
{
Lang.NO_PARTY.send(caller);
return;
}
removeFromParty(caller.getUniqueId(), PartyRemoveReason.LEFT);
Lang.LEFT.send(caller);
}
/**
* Disbands a players current party, assuming he is the leader
*
* @param caller The player who wishes to disband his party
*/
public void disband(Player caller)
{
Party party = _plugin.getParty(caller);
if (party == null)
{
Lang.NO_PARTY.send(caller);
return;
}
if (!party.getOwner().equalsIgnoreCase(caller.getName()))
{
Lang.NOT_OWNER.send(caller);
return;
}
caller.sendMessage(F.main("Party", "You have disbanded your party."));
disbandParty(party);
}
public void addToParty(UUID uuid, Party party)
{
_plugin.getPlayerParties().put(uuid, party);
Player player = Bukkit.getPlayer(uuid);
party.onPlayerAdd(player.getName());
if(!party.getMembersByUUID().contains(uuid))
{
party.getMembersByUUID().add(uuid);
}
}
public void addToPartyOnTransfer(UUID uuid, Party party)
{
_plugin.getPlayerParties().put(uuid, party);
}
public void addToParty(Player player, Party party)
{
addToParty(player.getUniqueId(), party);
}
public void removeForTransfer(UUID uuid)
{
Party party = _plugin.getPlayerParties().remove(uuid);
if(party == null)
{
return;
}
String player = Bukkit.getPlayer(uuid).getName();
party.onPlayerRemove(player, PartyRemoveReason.OTHER);
}
public void removeFromParty(UUID uuid, PartyRemoveReason reason)
{
Party party = _plugin.getPlayerParties().remove(uuid);
if(party == null)
{
return;
}
Player player = Bukkit.getPlayer(uuid);
if(player.getOpenInventory() != null)
{
if (Menu.get(player.getUniqueId()) != null)
{
player.closeInventory();
Menu.remove(player.getUniqueId());
}
}
if(reason == PartyRemoveReason.DISBANDED_BY_OWNER)
{
return;
}
party.getMembers().remove(player.getName());
party.getMembersByUUID().remove(uuid);
party.onPlayerRemove(player.getName(), reason);
int size = party.getMembers().size();
if(size <= 1)
{
if(size == 0)
{
_plugin.removeParty(party);
return;
}
_plugin.getPlayerParties().remove(Bukkit.getPlayerExact(party.getMembers().get(0)).getUniqueId());
party.onPlayerRemove(party.getMembers().get(0), PartyRemoveReason.DISBANDED);
_plugin.removeParty(party);
}
}
public void removeFromParty(Player player, PartyRemoveReason reason)
{
removeFromParty(player.getUniqueId(), reason);
}
public void disbandParty(Party party)
{
List<UUID> members = Lists.newArrayList(party.getMembersByUUID());
Lang.DISBANDED_BY_OWNER.send(party);
members.forEach(player -> removeFromParty(player, PartyRemoveReason.DISBANDED_BY_OWNER));
party.getMembers().clear();
party.getMembersByUUID().clear();
_plugin.removeParty(party);
}
public void transferOwner(String newOwner, String oldOwner)
{
Party party = _plugin.getParties().remove(oldOwner);
if(party == null)
{
return;
}
_plugin.getParties().put(newOwner, party);
party.setOwner(newOwner);
party.getMembers().remove(oldOwner);
party.getMembers().add(oldOwner);
UUID uuid = Bukkit.getPlayerExact(oldOwner).getUniqueId();
party.getMembersByUUID().remove(uuid);
party.getMembersByUUID().add(uuid);
}
}

View File

@ -1,296 +1,205 @@
package mineplex.core.party.manager;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import mineplex.core.common.util.F;
import mineplex.core.party.Lang;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.core.party.constants.InviteResponse;
import mineplex.core.party.constants.JoinResponseReason;
import mineplex.core.party.event.PartyDataReceivedEvent;
import mineplex.core.party.redis.PartyRedisListener;
import mineplex.core.party.redis.RedisMessageType;
import mineplex.core.preferences.Preference;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import static mineplex.core.party.redis.RedisMessageType.INVITE_PLAYER_REQUEST;
import static mineplex.core.party.redis.RedisMessageType.PARTY_INFO;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.core.party.rediscommands.PartyCrossServerInviteAccept;
import mineplex.core.party.rediscommands.PartyCrossServerInviteCommand;
import mineplex.core.party.rediscommands.PartyCrossServerInviteDeny;
import mineplex.core.party.rediscommands.PartyCrossServerInviteResponse;
import mineplex.core.portal.Portal;
import mineplex.core.preferences.Preference;
import mineplex.serverdata.commands.ServerCommandManager;
/**
* Redis system for Parties
*/
public class PartyRedisManager
{
protected final Gson GSON = new GsonBuilder().create();
protected static final String CHANNEL_BASE = "party-pubsub";
protected static final String FIND_PLAYERS_CHANNEL = "party-player-finder";
private final Map<String, BukkitTask> TASKS = Maps.newHashMap();
private final Map<UUID, Map<String, BukkitTask>> _pendingFindResponse = new HashMap<>();
private final PartyManager _plugin;
private final JedisPool _writePool;
private final String _channel;
private final String _serverName;
public PartyRedisManager(PartyManager plugin, String serverName, JedisPool writePool, JedisPool readPool)
public PartyRedisManager(PartyManager plugin, String serverName)
{
_plugin = plugin;
_serverName = serverName;
_writePool = writePool;
_channel = CHANNEL_BASE + "-" + serverName;
plugin.runAsync(() -> {
try (Jedis jedis = readPool.getResource())
ServerCommandManager.getInstance().registerCommandType(PartyCrossServerInviteCommand.class, command ->
{
jedis.subscribe(new PartyRedisListener(this), _channel, FIND_PLAYERS_CHANNEL);
}
});
}
_plugin.runSync(() ->
{
Player player = Bukkit.getPlayerExact(command.getTarget());
/**
* Send a message to a specific server
*
* @param server The destination server
* @param messageType The message to send
* @param args The arguments accompanying the request
*/
public void publish(String server, RedisMessageType messageType, String... args)
if (player == null || !player.isOnline())
{
_plugin.runAsync(() -> {
try (Jedis jedis = _writePool.getResource())
{
jedis.publish(CHANNEL_BASE + "-" + server, messageType.name() + "@" + messageType.format(args));
}
});
}
/**
* Handle a message received on this server
*
* @param messageType The type of message received
* @param message The contents of the request
*/
public void handle(RedisMessageType messageType, String message)
{
if (messageType == PARTY_INFO)
{
handlePartyInfo(message);
return;
}
String[] contents = message.split(",");
if (contents.length < 3)
{
return;
}
String first = contents[0];
String second = contents[1];
String third = contents[2];
Bukkit.getScheduler().runTask(_plugin.getPlugin(), () -> {
switch (messageType)
{
case INVITE_PLAYER_REQUEST:
_plugin.getInviteManager().handleInviteRequest(second, third, first);
break;
case INVITE_PLAYER_RESPONSE:
_plugin.getInviteManager().handleInviteResponse(first, second, UUID.fromString(third), InviteResponse.valueOf(contents[3].toUpperCase()));
break;
case PLAYER_FIND_REQUEST:
Player player = Bukkit.getPlayerExact(second);
if (player == null)
{
return;
}
if(_plugin.getParty(player) != null)
{
publish(first, RedisMessageType.INVITE_PLAYER_ALREADY_IN_PARTY, _serverName, player.getName(), player.getUniqueId().toString(), third);
return;
}
if (!_plugin.getPreferencesManager().get(player).isActive(Preference.PARTY_REQUESTS))
{
publish(first, RedisMessageType.INVITE_PLAYER_NOT_ACCEPTING_INVITES, _serverName, player.getName(), player.getUniqueId().toString(), third);
ServerCommandManager.getInstance().publishCommand(new PartyCrossServerInviteResponse(PartyCrossServerInviteResponse.Result.TARGET_NOT_ACCEPTING_INVITES, command, player));
return;
}
publish(first, RedisMessageType.PLAYER_FIND_RESPONSE, _serverName, player.getName(), player.getUniqueId().toString(), third);
break;
_plugin.getInviteManager().inviteTo(player.getName(), player.getUniqueId(), command.getRequesterName(), command.getRequesterUUID(), command.getPartyUUID(), command.getFromServer());
case INVITE_PLAYER_ALREADY_IN_PARTY:
handleAlreadyIn(second, contents);
break;
case INVITE_PLAYER_NOT_ACCEPTING_INVITES:
handleNotAccepting(second, contents);
break;
case PLAYER_FIND_RESPONSE:
UUID uuid = UUID.fromString(third);
cancelTask(second);
Player inviter = Bukkit.getPlayerExact(contents[3]);
if (_plugin.getInviteManager().isInvitedTo(uuid, inviter.getName()))
if (_plugin.getPartyByPlayer(player) != null)
{
Lang.ALREADY_INVITED.send(inviter, second);
ServerCommandManager.getInstance().publishCommand(new PartyCrossServerInviteResponse(PartyCrossServerInviteResponse.Result.SUCCESS_IN_PARTY, command, player));
}
else
{
ServerCommandManager.getInstance().publishCommand(new PartyCrossServerInviteResponse(PartyCrossServerInviteResponse.Result.SUCCESS, command, player));
}
});
});
ServerCommandManager.getInstance().registerCommandType(PartyCrossServerInviteResponse.class, command ->
{
if (!command.getOrigin().wasSentFromThisServer())
return;
_plugin.runSync(() ->
{
Map<String, BukkitTask> pendingTasks = _pendingFindResponse.get(command.getOrigin().getRequesterUUID());
if (pendingTasks == null)
return;
BukkitTask alertTask = pendingTasks.remove(command.getOrigin().getTarget());
if (alertTask == null)
return;
alertTask.cancel();
Player caller = Bukkit.getPlayer(command.getOrigin().getRequesterUUID());
if (caller == null || !caller.isOnline())
return;
switch (command.getResult())
{
case TARGET_NOT_ACCEPTING_INVITES:
UtilPlayer.message(caller, F.main("Party", "The player " + F.elem(command.getOrigin().getTarget()) + " is not accepting invites!"));
break;
case SUCCESS_IN_PARTY:
{
Party party = _plugin.getPartyByPlayer(command.getOrigin().getRequesterUUID());
if (party == null)
{
// todo wat do
return;
}
if (_plugin.getParty(inviter) == null)
if (!party.getOwnerName().equals(command.getOrigin().getRequesterName()))
{
Lang.INVITE_SUCCESS_PLAYER.send(inviter, second);
} else
{
Lang.SUCCESS_INVITE.send(_plugin.getParty(inviter), inviter.getName(), second);
//todo wat do
}
_plugin.getInviteManager().inviteTo(uuid, inviter.getName(), inviter.getName(), _plugin.getServerName());
publish(first, INVITE_PLAYER_REQUEST, _serverName, inviter.getName(), second);
break;
case PREJOIN_SERVER_REQUEST:
_plugin.getJoinManager().handleJoinRequest(first, Integer.valueOf(third), second, Boolean.valueOf(contents[3]));
_plugin.getInviteManager().inviteTo(command.getTargetName(), command.getTargetUUID(), command.getOrigin().getRequesterName(), command.getOrigin().getRequesterUUID(), command.getOrigin().getPartyUUID(), _plugin.getServerName());
party.sendMessage(F.main("Party", F.elem(command.getOrigin().getRequesterName()) + " has invited " + F.elem(command.getTargetName()) + " to the party"));
break;
}
case SUCCESS:
{
Party party = _plugin.getPartyByPlayer(command.getOrigin().getRequesterUUID());
if (party == null)
{
// todo wat do
return;
}
if (!party.getOwnerName().equals(command.getOrigin().getRequesterName()))
{
//todo wat do
}
case PREJOIN_SERVER_RESPONSE:
_plugin.getJoinManager().handleJoinResponse(first, third, JoinResponseReason.valueOf(second.toUpperCase()));
_plugin.getInviteManager().inviteTo(command.getTargetName(), command.getTargetUUID(), command.getOrigin().getRequesterName(), command.getOrigin().getRequesterUUID(), command.getOrigin().getPartyUUID(), _plugin.getServerName());
party.sendMessage(F.main("Party", F.elem(command.getOrigin().getRequesterName()) + " has invited " + F.elem(command.getTargetName()) + " to the party"));
break;
}
case UNKNOWN:
UtilPlayer.message(caller, F.main("Party", "Uh oh, something went wrong while inviting " + F.elem(command.getTargetName())));
break;
}
});
});
}
ServerCommandManager.getInstance().registerCommandType(PartyCrossServerInviteAccept.class, command ->
{
_plugin.runSync(() ->
{
Player apparentSender = Bukkit.getPlayer(command.getInviterUUID());
if (apparentSender != null && apparentSender.isOnline())
{
_plugin.getInviteManager().removeInviteTo(command.getPlayerName(), command.getPartyUUID());
private void handleNotAccepting(String second, String[] contents)
Party partyOfSender = _plugin.getPartyByPlayer(apparentSender);
if (partyOfSender == null)
{
cancelTask(second);
Player inviter = Bukkit.getPlayerExact(contents[3]);
inviter.sendMessage(F.main("Party", F.name(second) + " is not accepting invites at this time."));
}
private void handleAlreadyIn(String second, String[] contents)
{
cancelTask(second);
Player inviter = Bukkit.getPlayerExact(contents[3]);
Lang.ALREADY_IN.send(inviter, second);
}
/**
* Initiates inviting a player who is no on the same server
*
* @param player The player target
* @param sender The sending player
*/
public void findAndInvite(String player, String sender)
{
Bukkit.getPlayerExact(sender).sendMessage(F.main("Party", "Locating " + F.elem(player) + "..."));
TASKS.put(player, new BukkitRunnable()
{
@Override
public void run()
{
if(!TASKS.containsKey(player))
{
cancel();
//todo wat do
return;
}
TASKS.remove(player);
Player senderPlayer = Bukkit.getPlayerExact(sender);
if (senderPlayer == null)
if (!partyOfSender.getUniqueId().equals(command.getPartyUUID()))
{
cancel();
//todo wat do
return;
}
if (Bukkit.getPlayerExact(player) != null)
{
cancel();
return;
}
senderPlayer.sendMessage(F.main("Party", "Could not locate " + F.elem(player) + "."));
}
}.runTaskLater(_plugin.getPlugin(), 20L * 5));
_plugin.runAsync(() -> {
try (Jedis jedis = _writePool.getResource())
if (!partyOfSender.getOwnerName().equals(command.getInviterName()))
{
jedis.publish(FIND_PLAYERS_CHANNEL, RedisMessageType.PLAYER_FIND_REQUEST.format(_serverName, player, sender));
// todo ignore for now but wat do
}
// we good
_plugin.putIntoPendingJoin(command.getPlayerUUID(), partyOfSender.getUniqueId());
Portal.transferPlayer(command.getPlayerName(), _serverName);
}
});
});
ServerCommandManager.getInstance().registerCommandType(PartyCrossServerInviteDeny.class, command ->
{
_plugin.runSync(() ->
{
Player apparentSender = Bukkit.getPlayer(command.getInviterUUID());
if (apparentSender != null && apparentSender.isOnline())
{
_plugin.getInviteManager().removeInviteTo(command.getPlayerName(), command.getPartyUUID());
Party partyOfSender = _plugin.getPartyByPlayer(apparentSender);
if (partyOfSender == null)
{
UtilPlayer.message(apparentSender, F.main("Party", F.elem(command.getPlayerName()) + " has denied your invite, but it seems you don't have a party anymore"));
return;
}
if (!partyOfSender.getUniqueId().equals(command.getPartyUUID()))
{
UtilPlayer.message(apparentSender, F.main("Party", F.elem(command.getPlayerName()) + " has denied your invite, but it seems that you've made a new party in the meantime"));
return;
}
if (!partyOfSender.getOwnerName().equals(command.getInviterName()))
{
UtilPlayer.message(apparentSender, F.main("Party", F.elem(command.getPlayerName()) + " has denied your invite, but it seems that you are not the owner of the party anymore"));
return;
}
UtilPlayer.message(apparentSender, F.main("Party", F.elem(command.getPlayerName()) + " has denied your invite"));
}
});
});
}
/**
* Serializes and sends a party to another server
*
* @param server The destination server
* @param party The party to be sent
*/
public void sendPartyInfo(String server, Party party)
public Map<UUID, Map<String, BukkitTask>> getPendingFindResponse()
{
publish(server, PARTY_INFO, GSON.toJson(party));
List<UUID> members = party.getMembersByUUID();
party.getMembersByUUID().forEach(uuid -> _plugin.getMethodManager().removeForTransfer(uuid));
members.stream().map(Bukkit::getPlayer).forEach(player1 ->
{
player1.leaveVehicle();
player1.eject();
_plugin.getPortal().sendPlayer(player1, server);
});
_plugin.removeParty(party);
}
/**
* Deserialize and store a received party's information
* @param json
*/
public void handlePartyInfo(String json)
{
new BukkitRunnable()
{
@Override
public void run()
{
Party party = GSON.fromJson(json, Party.class);
_plugin.addParty(party);
party.getMembersByUUID().forEach(s -> _plugin.getMethodManager().addToPartyOnTransfer(s, party));
Bukkit.getServer().getPluginManager().callEvent(new PartyDataReceivedEvent(party));
}
}.runTaskLater(_plugin.getPlugin(), 10L);
}
/**
* @return This servers name
*/
public String getServerName()
{
return _serverName;
}
/**
* @return The channel constant for finding players
*/
public String getFinder()
{
return FIND_PLAYERS_CHANNEL;
}
public void cancelTask(String player)
{
BukkitTask task = TASKS.remove(player);
if (task != null)
{
task.cancel();
}
return _pendingFindResponse;
}
}

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