diff --git a/LandCore/.idea/.gitignore b/LandCore/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/LandCore/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/LandCore/.idea/LandCore.iml b/LandCore/.idea/LandCore.iml
new file mode 100644
index 0000000..fa63d4b
--- /dev/null
+++ b/LandCore/.idea/LandCore.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ SPIGOT
+
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/.idea/artifacts/LandCore.xml b/LandCore/.idea/artifacts/LandCore.xml
new file mode 100644
index 0000000..92e100c
--- /dev/null
+++ b/LandCore/.idea/artifacts/LandCore.xml
@@ -0,0 +1,6 @@
+
+
+ $PROJECT_DIR$/out/artifacts/LandCore
+
+
+
\ No newline at end of file
diff --git a/LandCore/.idea/compiler.xml b/LandCore/.idea/compiler.xml
new file mode 100644
index 0000000..79340ac
--- /dev/null
+++ b/LandCore/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/.idea/discord.xml b/LandCore/.idea/discord.xml
new file mode 100644
index 0000000..d8e9561
--- /dev/null
+++ b/LandCore/.idea/discord.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/.idea/encodings.xml b/LandCore/.idea/encodings.xml
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/LandCore/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/.idea/inspectionProfiles/Project_Default.xml b/LandCore/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..8fc8123
--- /dev/null
+++ b/LandCore/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/.idea/jarRepositories.xml b/LandCore/.idea/jarRepositories.xml
new file mode 100644
index 0000000..43e93b5
--- /dev/null
+++ b/LandCore/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/.idea/jpa-buddy.xml b/LandCore/.idea/jpa-buddy.xml
new file mode 100644
index 0000000..966d5f5
--- /dev/null
+++ b/LandCore/.idea/jpa-buddy.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/.idea/misc.xml b/LandCore/.idea/misc.xml
new file mode 100644
index 0000000..8c87c88
--- /dev/null
+++ b/LandCore/.idea/misc.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/.idea/uiDesigner.xml b/LandCore/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/LandCore/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/lib/Carbon-Server-1.8.8-R0.1-SNAPSHOT.jar b/LandCore/lib/Carbon-Server-1.8.8-R0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..b8e579f
Binary files /dev/null and b/LandCore/lib/Carbon-Server-1.8.8-R0.1-SNAPSHOT.jar differ
diff --git a/LandCore/lib/NickAPI-v6.5.jar b/LandCore/lib/NickAPI-v6.5.jar
new file mode 100644
index 0000000..6520100
Binary files /dev/null and b/LandCore/lib/NickAPI-v6.5.jar differ
diff --git a/LandCore/lib/ProtocolLib.jar b/LandCore/lib/ProtocolLib.jar
new file mode 100644
index 0000000..74682ff
Binary files /dev/null and b/LandCore/lib/ProtocolLib.jar differ
diff --git a/LandCore/lib/ViaVersion-3.2.1.jar b/LandCore/lib/ViaVersion-3.2.1.jar
new file mode 100644
index 0000000..c68ea80
Binary files /dev/null and b/LandCore/lib/ViaVersion-3.2.1.jar differ
diff --git a/LandCore/pom.xml b/LandCore/pom.xml
new file mode 100644
index 0000000..2c53d52
--- /dev/null
+++ b/LandCore/pom.xml
@@ -0,0 +1,156 @@
+
+
+ 4.0.0
+
+ me.devkevin.landcore
+ LandCore
+ 1.3-SNAPSHOT
+ jar
+
+
+ 1.8
+ UTF-8
+
+
+
+
+ destroystokyo-releases
+ https://repo.destroystokyo.com/repository/maven-releases/
+
+
+ destroystokyo-snapshots
+ https://repo.destroystokyo.com/repository/maven-snapshots/
+
+
+
+
+
+
+
+ club.inverted
+ inverted-spigot
+ 1.8.8-R0.1-SNAPSHOT
+ system
+ ${project.basedir}/lib/Carbon-Server-1.8.8-R0.1-SNAPSHOT.jar
+
+
+
+
+ org.mongodb
+ mongo-java-driver
+ 3.12.11
+ compile
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.3
+
+
+
+
+ xyz.haoshoku.nick
+ nickapi
+ 5.0.2-SNAPSHOT
+ system
+ ${project.basedir}/lib/NickAPI-v6.5.jar
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.24
+ provided
+
+
+
+ redis.clients
+ jedis
+ 2.9.0
+ compile
+
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.0
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.3.2
+
+
+
+
+ com.googlecode.json-simple
+ json-simple
+ 1.1.1
+ provided
+
+
+
+
+ ViaVersion-3.2.1
+ ViaVersion-3.2.1
+ 1.0-SNAPSHOT
+ system
+ ${project.basedir}/lib/ViaVersion-3.2.1.jar
+
+
+
+
+ com.comphenix.protocol
+ ProtocolLib
+ yes
+ system
+ ${project.basedir}/lib/ProtocolLib.jar
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+
+ ${java.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+ false
+
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
\ No newline at end of file
diff --git a/LandCore/src/main/java/me/devkevin/landcore/LandCore.java b/LandCore/src/main/java/me/devkevin/landcore/LandCore.java
new file mode 100644
index 0000000..a30964b
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/LandCore.java
@@ -0,0 +1,346 @@
+package me.devkevin.landcore;
+
+import com.google.common.collect.Maps;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import lombok.Getter;
+import me.devkevin.landcore.commands.impl.*;
+import me.devkevin.landcore.commands.impl.staff.*;
+import me.devkevin.landcore.commands.impl.staff.punish.*;
+import me.devkevin.landcore.commands.impl.toggle.ToggleGlobalChat;
+import me.devkevin.landcore.commands.impl.toggle.ToggleMessagesCommand;
+import me.devkevin.landcore.commands.impl.toggle.ToggleSoundsCommand;
+import me.devkevin.landcore.disguise.commands.DisguiseCommand;
+import me.devkevin.landcore.disguise.manager.DisguiseManager;
+import me.devkevin.landcore.disguise.commands.UndisguiseCommand;
+import me.devkevin.landcore.disguise.menu.DisguiseMenu;
+import me.devkevin.landcore.faction.commands.FactionHelpCommand;
+import me.devkevin.landcore.faction.commands.captain.*;
+import me.devkevin.landcore.faction.commands.leader.FactionDescriptionCommand;
+import me.devkevin.landcore.faction.commands.leader.FactionDisbandCommand;
+import me.devkevin.landcore.faction.commands.player.*;
+import me.devkevin.landcore.faction.listener.FactionListener;
+import me.devkevin.landcore.faction.manager.FactionManager;
+import me.devkevin.landcore.gson.CustomLocationTypeAdapterFactory;
+import me.devkevin.landcore.gson.ItemStackTypeAdapterFactory;
+import me.devkevin.landcore.listeners.*;
+import me.devkevin.landcore.listeners.redis.*;
+import me.devkevin.landcore.managers.MenuManager;
+import me.devkevin.landcore.managers.PlayerManager;
+import me.devkevin.landcore.managers.ProfileManager;
+import me.devkevin.landcore.managers.StaffManager;
+import me.devkevin.landcore.nametag.NameTagAdapter;
+import me.devkevin.landcore.nametag.impl.InternalNametag;
+import me.devkevin.landcore.player.color.ColorCommand;
+import me.devkevin.landcore.player.color.SetColorCommand;
+import me.devkevin.landcore.player.color.menu.ColorMenu;
+import me.devkevin.landcore.player.grant.procedure.GrantProcedureListener;
+import me.devkevin.landcore.player.info.UserCommand;
+import me.devkevin.landcore.player.notes.commands.NoteAddCommand;
+import me.devkevin.landcore.player.notes.commands.NoteRemoveCommand;
+import me.devkevin.landcore.player.notes.commands.NotesCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.player.rank.commands.*;
+import me.devkevin.landcore.player.tags.PrefixCommand;
+import me.devkevin.landcore.player.tags.menu.PrefixMenu;
+import me.devkevin.landcore.punishment.listener.PunishmentListener;
+import me.devkevin.landcore.redis.RedisMessenger;
+import me.devkevin.landcore.server.ServerSettings;
+import me.devkevin.landcore.server.filter.Filter;
+import me.devkevin.landcore.storage.database.MongoStorage;
+import me.devkevin.landcore.store.StorePCoinMenu;
+import me.devkevin.landcore.task.BroadcastTask;
+import me.devkevin.landcore.task.GrantDisguiseCheckTask;
+import me.devkevin.landcore.utils.inventory.UIListener;
+import me.devkevin.landcore.utils.menu.ButtonListener;
+import me.devkevin.landcore.utils.menu.MenuUpdateTask;
+import me.devkevin.landcore.utils.message.CC;
+import me.devkevin.landcore.utils.packet.PacketAdapter;
+import me.devkevin.landcore.utils.packet.PacketListener;
+import me.devkevin.landcore.utils.structure.Cuboid;
+import net.minecraft.server.v1_8_R3.Packet;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandMap;
+import org.bukkit.configuration.serialization.ConfigurationSerializable;
+import org.bukkit.configuration.serialization.ConfigurationSerialization;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Random;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@Getter
+public class LandCore extends JavaPlugin {
+ @Getter
+ private static LandCore instance;
+
+ public static GsonBuilder GSONBUILDER;
+ public static Gson GSON;
+ public static final Random RANDOM = new Random();
+
+ private ServerSettings serverSettings;
+ private Filter filter;
+ private MongoStorage mongoStorage;
+
+ private ProfileManager profileManager;
+ private StaffManager staffManager;
+ private PlayerManager playerManager;
+ private MenuManager menuManager;
+ private RedisMessenger redisMessenger;
+ private static Field bukkitCommandMap;
+ private PrefixMenu prefixMenu;
+ private ColorMenu colorMenu;
+ private DisguiseMenu disguiseMenu;
+ private DisguiseManager disguiseManager;
+ private PacketListener packetListener;
+ private FactionManager factionManager;
+ private StorePCoinMenu storePCoinMenu;
+
+ private static void registerSerializableClass(Class> clazz) {
+ if (ConfigurationSerializable.class.isAssignableFrom(clazz)) {
+ Class extends ConfigurationSerializable> serializable = clazz.asSubclass(ConfigurationSerializable.class);
+ ConfigurationSerialization.registerClass(serializable);
+ }
+ }
+
+ @Override
+ public void onEnable() {
+ instance = this;
+
+ LandCore.GSONBUILDER = new GsonBuilder()
+ .registerTypeAdapterFactory(new CustomLocationTypeAdapterFactory())
+ .registerTypeAdapterFactory(new ItemStackTypeAdapterFactory());
+ LandCore.GSON = LandCore.GSONBUILDER.create();
+
+ getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
+ saveDefaultConfig();
+
+ registerSerializableClass(Cuboid.class);
+
+ serverSettings = new ServerSettings(this);
+ filter = new Filter();
+
+ redisMessenger = new RedisMessenger(
+ this,
+ getConfig().getString("redis.host"),
+ getConfig().getInt("redis.port"),
+ getConfig().getInt("redis.timeout"),
+ getConfig().getString("redis.password")
+ );
+
+ redisMessenger.registerListeners(
+ new FreezeListener(this),
+ new FrozenDisconnectListener(this),
+ new HelpopListener(this),
+ new ReportListener(this),
+ new StaffChatListener(this),
+ new StaffStreamListener(this),
+ new RedisServerMonitorListener(this),
+ new RedisFactionListener(this)
+ );
+
+ redisMessenger.initialize();
+ mongoStorage = new MongoStorage(this);
+
+ this.disableLoggers();
+ this.addServerMonitor();
+
+ Bukkit.getConsoleSender().sendMessage(CC.SEPARATOR);
+ Bukkit.getConsoleSender().sendMessage(CC.translate("&eLandCore &8- &b" + getDescription().getVersion()));
+ Bukkit.getConsoleSender().sendMessage(CC.translate(" "));
+ Bukkit.getConsoleSender().sendMessage(CC.translate("&b • &eDeveloper: &eDevKevin"));
+ Bukkit.getConsoleSender().sendMessage(CC.translate("&b • &eMongo: &f" + (mongoStorage.isConnected() ? "&aenabled" : "&cdisabled")));
+ Bukkit.getConsoleSender().sendMessage(CC.translate("&b • &eRedis: &f" + (redisMessenger.isActive() ? "&aenabled" : "&cdisabled")));
+ Bukkit.getConsoleSender().sendMessage(CC.SEPARATOR);
+
+ profileManager = new ProfileManager();
+ staffManager = new StaffManager(this);
+ playerManager = new PlayerManager();
+ menuManager = new MenuManager(this);
+ prefixMenu = new PrefixMenu();
+ colorMenu = new ColorMenu();
+ disguiseMenu = new DisguiseMenu();
+ disguiseManager = new DisguiseManager();
+ factionManager = new FactionManager();
+ storePCoinMenu = new StorePCoinMenu();
+
+ new InternalNametag(this, new NameTagAdapter());
+ //LandSpigot.getInstance().registerPacketHandler(new EntityPacketHandler());
+
+ Arrays.asList(
+ new BroadcastCommand(this),
+ new ClearChatCommand(this),
+ new IgnoreCommand(this),
+ new ListCommand(),
+ new MessageCommand(this),
+ new RankCommand(this),
+ new ReplyCommand(this),
+ new StaffChatCommand(this),
+ new TeleportCommand(this),
+ new ToggleMessagesCommand(this),
+ new ToggleGlobalChat(this),
+ new ToggleSoundsCommand(this),
+ new VanishCommand(this),
+ new ReportCommand(this),
+ new CheckCommand(this),
+ new HelpOpCommand(this),
+ new PingCommand(),
+ new BanCommand(this),
+ new MuteCommand(this),
+ new UnbanCommand(this),
+ new UnmuteCommand(this),
+ new WarnCommand(this),
+ new KickCommand(this),
+ new MuteChatCommand(this),
+ new SlowChatCommand(this),
+ new GameModeCommand(),
+ new ShutdownCommand(this),
+ new FreezeCommand(this),
+ new WhitelistCommand(this),
+ new GrantCommand(this),
+ new GrantsCommand(this),
+ new QuickGrantCommand(this),
+ new UserCommand(this),
+ new PlayTimeCommand(this),
+ new RankListCommand(),
+ new NoteAddCommand(this),
+ new NoteRemoveCommand(this),
+ new NotesCommand(this),
+ new MisplaceCommand(this),
+ new PrefixCommand(this),
+ new ColorCommand(this),
+ new SetColorCommand(this),
+ new BuildServerCommand(this),
+ new TeleportPositionCommand(this),
+ new FeedCommand(this),
+ new HealCommand(this),
+ new AltsCommand(this),
+ new UndisguiseCommand(this),
+ new DisguiseCommand(this),
+ new EnchantCommand(this),
+
+ // factions
+ new FactionHelpCommand(this),
+ new FactionAcceptCommand(this),
+ new FactionCreateCommand(this),
+ new FactionLeaveCommand(this),
+ new FactionInfoCommand(this),
+ new FactionDescriptionCommand(this),
+ new FactionDisbandCommand(this),
+ new FactionDemoteCommand(this),
+ new FactionInviteCommand(this),
+ new FactionKickCommand(this),
+ new FactionPasswordCommand(this),
+ new FactionPromoteCommand(this),
+ new FactionChatCommand(this),
+
+ new PCoinsCommand(this),
+ new StoreCommand(this)
+ ).forEach(command -> registerCommand(command, getName()));
+
+ Arrays.asList(
+ new PlayerListener(this),
+ new ButtonListener(),
+ new MessageListener(this),
+ new InventoryListener(this),
+ new HelpCommandListener(this),
+ new PlayerInteractListener(this),
+ new UIListener(),
+ new GrantProcedureListener(this),
+ new PunishmentListener(),
+ new FactionListener()
+ ).forEach(listener -> getServer().getPluginManager().registerEvents(listener, this));
+
+ getServer().getScheduler().runTaskTimerAsynchronously(this, new BroadcastTask(this), 20 * 120L, 20 * 120L);
+ new MenuUpdateTask();
+ new GrantDisguiseCheckTask();
+
+ //WindSpigot.getInstance().registerPacketListener(new PacketListener());
+
+ packetListener = new PacketListener();
+ new PlayerPacketListener(this, packetListener);
+
+ Rank.importRanks();
+ CC.logConsole(CC.PRIMARY + "[LandCore] " + CC.SECONDARY + "Core has started successfully.");
+ CC.logConsole(CC.PRIMARY + "[LandCore] " + CC.GREEN + " All databases connected successfully.");
+
+ getServer().getScheduler().runTaskTimerAsynchronously(this, () -> {
+ factionManager.save();
+ }, 0L, 6000L);
+ }
+
+ @Override
+ public void onDisable() {
+ this.getServer().getScheduler().cancelTasks(this);
+
+ Map message = Maps.newHashMap();
+ message.put("server", this.getServerName());
+
+ this.getRedisMessenger().sendOff("server-monitor-remove", message);
+
+ factionManager.save();
+ getServer().getOnlinePlayers().parallelStream().forEach(player -> factionManager.savePlayerFaction(player));
+
+ try {
+ Thread.sleep(1000L);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ for (Player player : getServer().getOnlinePlayers()) {
+ player.kickPlayer(CC.RED + "The server is restarting.");
+
+ // remove fake players
+ LandCore.getInstance().getPlayerManager().getDummyPlayers().remove(player.getUniqueId());
+ }
+
+ profileManager.saveProfiles();
+ serverSettings.saveConfig();
+
+ Bukkit.getScheduler().cancelTasks(this);
+ }
+
+ public String getServerName() {
+ return getConfig().getString("server_name");
+ }
+
+ public String getNetworkName() {
+ return getConfig().getString("network_name");
+ }
+
+ public void registerCommand(Command cmd, String fallbackPrefix) {
+ try {
+ if (bukkitCommandMap == null) {
+ bukkitCommandMap = Bukkit.getServer().getClass().getDeclaredField("commandMap");
+ bukkitCommandMap.setAccessible(true);
+ }
+ CommandMap commandMap = (CommandMap) bukkitCommandMap.get(Bukkit.getServer());
+ commandMap.register(cmd.getName(), fallbackPrefix, cmd);
+ } catch (Exception e) {
+ Bukkit.getLogger().info("[LandCore] CommandMap failed to register.");
+ e.printStackTrace();
+ }
+ }
+
+ private void disableLoggers() {
+ Logger.getLogger("org.mongodb.driver.connection").setLevel(Level.OFF);
+ Logger.getLogger("org.mongodb.driver.cluster").setLevel(Level.OFF);
+ }
+
+ private void addServerMonitor() {
+ Map message = Maps.newHashMap();
+ message.put("server", this.getServerName());
+
+ this.getRedisMessenger().send("server-monitor-add", message);
+ }
+
+ public > void registerAdapter(Class extends E> classType, PacketAdapter handler) {
+ packetListener.registerAdapter(classType, handler);
+ }
+
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/LandCoreAPI.java b/LandCore/src/main/java/me/devkevin/landcore/LandCoreAPI.java
new file mode 100644
index 0000000..7308a30
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/LandCoreAPI.java
@@ -0,0 +1,191 @@
+package me.devkevin.landcore;
+
+import com.google.common.io.ByteArrayDataOutput;
+import com.google.common.io.ByteStreams;
+import lombok.Getter;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.PlayerVersion;
+import me.devkevin.landcore.utils.item.ItemBuilder;
+import me.devkevin.landcore.utils.message.CC;
+import lombok.experimental.UtilityClass;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Listener;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.plugin.java.JavaPlugin;
+import us.myles.ViaVersion.api.Via;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 18/01/2023 @ 13:49
+ * CorePluginAPI / land.pvp.core / LandCore
+ */
+@UtilityClass
+public class LandCoreAPI {
+ public final static ItemStack PLACEHOLDER_ITEM = new ItemBuilder(Material.STAINED_GLASS_PANE)
+ .durability(7)
+ .name("&a")
+ .lore(" ")
+ .hideFlags()
+ .build();
+
+ public static String getColorPing(int ping) {
+ if (ping <= 40) return CC.translate("&a" + ping);
+ if (ping <= 70) return CC.translate("&e" + ping);
+ if (ping <= 100) return CC.translate("&6" + ping);
+ else return CC.translate("&c" + ping);
+ }
+
+ public static boolean isInteger(String index) {
+ try {
+ Integer.parseInt(index);
+ return true;
+ } catch (Exception ignored) {
+ return false;
+ }
+ }
+
+ public static void sendToServer(Player player, String server) {
+ try {
+ ByteArrayDataOutput out = ByteStreams.newDataOutput();
+ out.writeUTF("Connect");
+ out.writeUTF(server);
+ player.sendMessage(CC.translate("&aSending to " + server + "..."));
+ player.sendPluginMessage(LandCore.getInstance(), "BungeeCord", out.toByteArray());
+ } catch (Exception e) {
+ player.sendMessage(CC.translate("&cAn Error occurred while sending to the server."));
+ }
+ }
+
+ public static int getMaxEnchantLevel(Player player) {
+ CoreProfile profile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ if (profile.hasRank(Rank.DEVELOPER)) return 9999;
+ if (profile.hasRank(Rank.DEVELOPER)) return 21;
+ if (profile.hasRank(Rank.DEVELOPER)) return 14;
+ if (profile.hasRank(Rank.DEVELOPER)) return 7;
+
+ return 5;
+ }
+
+ public static Enchantment getEnchantmentByName(Object object) {
+ String value = object.toString().replace("_", "").trim();
+
+ switch (value.toUpperCase()) {
+ case "PROT":
+ case "PROTECTION":
+ return Enchantment.PROTECTION_ENVIRONMENTAL;
+ case "UNB":
+ case "UNBREAKING":
+ return Enchantment.DURABILITY;
+ case "FIREP":
+ case "FP":
+ case "FIREPROTECTION":
+ return Enchantment.PROTECTION_FIRE;
+ case "FEATHERF":
+ case "FL":
+ case "FEATHERFALLING":
+ return Enchantment.PROTECTION_FALL;
+ case "BLASTP":
+ case "BP":
+ case "BLASTPROTECTION":
+ return Enchantment.PROTECTION_EXPLOSIONS;
+ case "SHARP":
+ case "SHARPNESS":
+ return Enchantment.DAMAGE_ALL;
+ case "KNOCK":
+ case "KNOCKBACK":
+ return Enchantment.KNOCKBACK;
+ case "FIREA":
+ case "FA":
+ case "FIRE":
+ case "FIREASPECT":
+ return Enchantment.FIRE_ASPECT;
+ case "L":
+ case "LOOT":
+ case "LOOTING":
+ return Enchantment.LOOT_BONUS_MOBS;
+ case "F":
+ case "FORT":
+ case "FORTUNE":
+ return Enchantment.LOOT_BONUS_BLOCKS;
+ case "ST":
+ case "SILK":
+ case "SILKTOUCH":
+ return Enchantment.SILK_TOUCH;
+ case "EFF":
+ case "EFFICIENCY":
+ return Enchantment.DIG_SPEED;
+ case "SM":
+ case "SMITE":
+ return Enchantment.DAMAGE_UNDEAD;
+ case "INF":
+ case "INFINITY":
+ return Enchantment.ARROW_INFINITE;
+ case "FLA":
+ case "FLAME":
+ return Enchantment.ARROW_FIRE;
+ case "PUNCH":
+ return Enchantment.ARROW_KNOCKBACK;
+ case "POWER":
+ return Enchantment.ARROW_DAMAGE;
+ default:
+ return null;
+ }
+ }
+
+ public enum Language {
+ USE_NUMBERS("USE_NUMBERS", "{prefix} &cPlease use numbers."),
+ ENCHANT_MUST_HOLD_ITEM("ENCHANT.MUST-HOLD-ITEM", "{prefix} &eYou must hold item in order to enchant."),
+ ENCHANT_ENCHANT_MUST_BE_POSITIVE("ENCHANT.ENCHANT-MUST-BE-POSITIVE", "{prefix} &eEnchant level must be positive."),
+ ENCHANT_MAXIMUM_LEVEL_EXCEEDED("ENCHANT.MAXIMUM-LEVEL-EXCEEDED", "{prefix} &eYour maximum level for enchant is &6&e."),
+ ENCHANT_WRONG_ENCHANTMENT("ENCHANT.WRONG-ENCHANTMENT", "{prefix} &eYou've entered wrong enchantment."),
+ ENCHANT_ITEM_DOESNT_HAVE_ENCHANT("ENCHANT.ITEM-IS-NOT-ENCHANTED", "{prefix} &eYour item does not have that enchantment."),
+ ENCHANT_REMOVED("ENCHANT.REMOVED", "{prefix} &eYou've removed &6 &eenchantment from your item."),
+ ENCHANT_ADDED("ENCHANT.ADDED", "{prefix} &eYou've added &6 &eenchantment to your item.");
+
+ @Getter
+ private String path;
+ @Getter
+ private String value;
+ @Getter
+ private List listValue;
+
+ Language(String path, String value) {
+ this.path = path;
+ this.value = value;
+ this.listValue = new ArrayList<>(Collections.singletonList(value));
+ }
+ }
+
+ public PlayerVersion getPlayerVersion(Player player) {
+ return PlayerVersion.getVersionFromRaw(Via.getAPI().getPlayerVersion(player.getUniqueId()));
+ }
+
+ public abstract class LandCoreListener implements Listener {
+ public LandCoreListener(JavaPlugin javaPlugin) {
+ Bukkit.getServer().getPluginManager().registerEvents(this, javaPlugin);
+ }
+ }
+
+ public static String getTodayDate() {
+ Date todayDate = new Date();
+ DateFormat todayDateFormat = new SimpleDateFormat("MMM dd, yyyy");
+ todayDateFormat.setTimeZone(TimeZone.getTimeZone("US/Eastern"));
+ return todayDateFormat.format(todayDate);
+ }
+
+ public static String getCurrentTime() {
+ DateFormat dateFormat = new SimpleDateFormat("hh:mm a");
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("US/Eastern"));
+ dateFormat.setTimeZone(cal.getTimeZone());
+ return dateFormat.format(cal.getTime());
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/callback/DocumentCallback.java b/LandCore/src/main/java/me/devkevin/landcore/callback/DocumentCallback.java
new file mode 100644
index 0000000..0ccf6ec
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/callback/DocumentCallback.java
@@ -0,0 +1,7 @@
+package me.devkevin.landcore.callback;
+
+import org.bson.Document;
+
+public interface DocumentCallback {
+ void call(Document document, boolean found);
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/callback/WebCallback.java b/LandCore/src/main/java/me/devkevin/landcore/callback/WebCallback.java
new file mode 100644
index 0000000..22aed18
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/callback/WebCallback.java
@@ -0,0 +1,5 @@
+package me.devkevin.landcore.callback;
+
+public interface WebCallback {
+ void callback(String response);
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/BaseCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/BaseCommand.java
new file mode 100644
index 0000000..16a1a57
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/BaseCommand.java
@@ -0,0 +1,66 @@
+package me.devkevin.landcore.commands;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public abstract class BaseCommand extends Command {
+ private static final String LINE_SEPARATOR = System.lineSeparator();
+ private final Rank requiredRank;
+
+ protected BaseCommand(String name, Rank requiredRank) {
+ super(name);
+ this.requiredRank = requiredRank;
+ }
+
+ protected BaseCommand(String name) {
+ this(name, Rank.MEMBER);
+ }
+
+ @Override
+ public final boolean execute(CommandSender sender, String alias, String[] args) {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ CoreProfile profile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ if (!profile.hasRank(requiredRank)) {
+ player.sendMessage(CC.RED + "You don't have the required rank to perform this command.");
+ return true;
+ }
+ }
+
+ execute(sender, args);
+ return true;
+ }
+
+ protected final void setAliases(String... aliases) {
+ if (aliases.length > 0) {
+ setAliases(aliases.length == 1 ? Collections.singletonList(aliases[0]) : Arrays.asList(aliases));
+ }
+ }
+
+ protected final void setUsage(String... uses) {
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = 0; i < uses.length; i++) {
+ String use = uses[i];
+
+ builder.append(use);
+
+ if (i + 1 != uses.length) {
+ builder.append(LINE_SEPARATOR);
+ }
+ }
+
+ setUsage(builder.toString());
+ }
+
+ protected abstract void execute(CommandSender sender, String[] args);
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/PlayerCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/PlayerCommand.java
new file mode 100644
index 0000000..172761f
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/PlayerCommand.java
@@ -0,0 +1,27 @@
+package me.devkevin.landcore.commands;
+
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public abstract class PlayerCommand extends BaseCommand {
+ protected PlayerCommand(String name, Rank requiredRank) {
+ super(name, requiredRank);
+ }
+
+ protected PlayerCommand(String name) {
+ super(name, Rank.MEMBER);
+ }
+
+ @Override
+ protected final void execute(CommandSender sender, String[] args) {
+ if (sender instanceof Player) {
+ execute((Player) sender, args);
+ } else {
+ sender.sendMessage(CC.RED + "Only players can perform this command.");
+ }
+ }
+
+ public abstract void execute(Player player, String[] args);
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ClearChatCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ClearChatCommand.java
new file mode 100644
index 0000000..127d663
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ClearChatCommand.java
@@ -0,0 +1,36 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.util.Collections;
+
+public class ClearChatCommand extends BaseCommand {
+ private static final String BLANK_MESSAGE = String.join("", Collections.nCopies(150, "§8 §8 §1 §3 §3 §7 §8 §r\n"));
+ private final LandCore plugin;
+
+ public ClearChatCommand(LandCore plugin) {
+ super("clearchat", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ setAliases("cc");
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ for (Player player : plugin.getServer().getOnlinePlayers()) {
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+
+ if (!profile.hasStaff()) {
+ player.sendMessage(BLANK_MESSAGE);
+ }
+ }
+
+ plugin.getServer().broadcastMessage(CC.GREEN + "The chat was cleared by " + sender.getName() + ".");
+ sender.sendMessage(CC.YELLOW + "Don't worry, staff can still see cleared messages.");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/EnchantCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/EnchantCommand.java
new file mode 100644
index 0000000..3dc7f18
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/EnchantCommand.java
@@ -0,0 +1,87 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.LandCoreAPI;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.TaskUtil;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Material;
+import org.bukkit.command.CommandSender;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 13/02/2023 @ 19:55
+ * EnchantCommand / me.devkevin.landcore.commands.impl / LandCore
+ */
+public class EnchantCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public EnchantCommand(LandCore plugin) {
+ super("enchant", Rank.DEVELOPER);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ TaskUtil.runAsync(() -> {
+ Player player = (Player) sender;
+
+ if (args.length < 2) {
+ player.sendMessage(CC.translate("&cCorrect usage: /enchant "));
+ return;
+ }
+
+ ItemStack item = player.getItemInHand();
+
+ if (item == null || item.getType() == Material.AIR) {
+ player.sendMessage(LandCoreAPI.Language.ENCHANT_MUST_HOLD_ITEM.toString());
+ return;
+ }
+
+ if (!LandCoreAPI.isInteger(args[1])) {
+ player.sendMessage(LandCoreAPI.Language.USE_NUMBERS.toString());
+ return;
+ }
+
+ int level = Integer.parseInt(args[1]);
+
+ if (level < 0) {
+ player.sendMessage(LandCoreAPI.Language.ENCHANT_ENCHANT_MUST_BE_POSITIVE.toString());
+ return;
+ }
+
+ if (level > LandCoreAPI.getMaxEnchantLevel(player)) {
+ player.sendMessage(LandCoreAPI.Language.ENCHANT_MAXIMUM_LEVEL_EXCEEDED.toString()
+ .replace("", String.valueOf(LandCoreAPI.getMaxEnchantLevel(player))));
+ return;
+ }
+
+ Enchantment enchantment = LandCoreAPI.getEnchantmentByName(args[0]);
+
+ if (enchantment == null) {
+ player.sendMessage(LandCoreAPI.Language.ENCHANT_WRONG_ENCHANTMENT.toString());
+ return;
+ }
+
+ if (level == 0) {
+ if (!item.containsEnchantment(enchantment)) {
+ player.sendMessage(LandCoreAPI.Language.ENCHANT_ITEM_DOESNT_HAVE_ENCHANT.toString());
+ return;
+ }
+
+ item.removeEnchantment(enchantment);
+ player.sendMessage(LandCoreAPI.Language.ENCHANT_REMOVED.toString()
+ .replace("", enchantment.getName().toUpperCase().replace("_", " ") + " " + level));
+ return;
+ }
+
+ item.addUnsafeEnchantment(enchantment, level);
+ player.sendMessage(LandCoreAPI.Language.ENCHANT_ADDED.toString()
+ .replace("", enchantment.getName().toUpperCase().replace("_", " ")));
+ });
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/FeedCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/FeedCommand.java
new file mode 100644
index 0000000..348f027
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/FeedCommand.java
@@ -0,0 +1,27 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 07/02/2023 @ 18:07
+ * FeedCommand / me.devkevin.landcore.commands.impl / LandCore
+ */
+public class FeedCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FeedCommand(LandCore plugin) {
+ super("feed", Rank.ADMIN);
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ player.sendMessage(CC.GOLD + CC.B + "You now have full hunger");
+ player.setFoodLevel(20);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/HealCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/HealCommand.java
new file mode 100644
index 0000000..9a621b8
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/HealCommand.java
@@ -0,0 +1,27 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 07/02/2023 @ 18:08
+ * HealCommand / me.devkevin.landcore.commands.impl / LandCore
+ */
+public class HealCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public HealCommand(LandCore plugin) {
+ super("heal", Rank.ADMIN);
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ player.sendMessage(CC.GOLD + CC.B + "You now have fully healed.");
+ player.setHealth(player.getMaxHealth());
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/HelpOpCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/HelpOpCommand.java
new file mode 100644
index 0000000..ee3a8b8
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/HelpOpCommand.java
@@ -0,0 +1,49 @@
+package me.devkevin.landcore.commands.impl;
+
+import com.google.common.collect.Maps;
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.StringUtil;
+import me.devkevin.landcore.utils.message.CC;
+import me.devkevin.landcore.utils.timer.Timer;
+import org.bukkit.entity.Player;
+
+import java.util.Map;
+
+public class HelpOpCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public HelpOpCommand(LandCore plugin) {
+ super("helpop");
+ this.plugin = plugin;
+ setUsage(CC.RED + "/helpop ");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length < 1) {
+ player.sendMessage(usageMessage);
+ return;
+ }
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+ Timer cooldownTimer = profile.getReportCooldownTimer();
+
+ if (cooldownTimer.isActive()) {
+ player.sendMessage(CC.RED + "You can't request assistance for another " + cooldownTimer.formattedExpiration() + ".");
+ return;
+ }
+
+ String request = StringUtil.buildString(args, 0);
+
+ Map requestMap = Maps.newHashMap();
+ requestMap.put("server", plugin.getServerName());
+ requestMap.put("player", player.getName());
+ requestMap.put("request", request);
+
+ plugin.getRedisMessenger().send("help-op", requestMap);
+
+ player.sendMessage(CC.GREEN + "Request sent: " + CC.R + request);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/IgnoreCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/IgnoreCommand.java
new file mode 100644
index 0000000..72165d8
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/IgnoreCommand.java
@@ -0,0 +1,57 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.message.CC;
+import me.devkevin.landcore.utils.message.Messages;
+import org.bukkit.entity.Player;
+
+public class IgnoreCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public IgnoreCommand(LandCore plugin) {
+ super("ignore");
+ this.plugin = plugin;
+ setAliases("unignore");
+ setUsage(CC.RED + "Usage: /ignore ");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length < 1) {
+ player.sendMessage(usageMessage);
+ return;
+ }
+
+ Player target = plugin.getServer().getPlayer(args[0]);
+
+ if (target == null) {
+ player.sendMessage(Messages.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ if (target.getName().equals(player.getName())) {
+ player.sendMessage(CC.RED + "You can't ignore yourself!");
+ return;
+ }
+
+ CoreProfile targetProfile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (targetProfile.hasStaff()) {
+ player.sendMessage(CC.RED + "You can't ignore a staff member. If this staff member is harrassing you " +
+ "or engaging in other abusive manners, please report this or contact a higher staff member.");
+ return;
+ }
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+
+ if (profile.hasPlayerIgnored(target.getUniqueId())) {
+ profile.unignore(target.getUniqueId());
+ player.sendMessage(CC.GREEN + "No longer ignoring " + target.getName() + ".");
+ } else {
+ profile.ignore(target.getUniqueId());
+ player.sendMessage(CC.GREEN + "Now ignoring " + target.getName() + ".");
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ListCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ListCommand.java
new file mode 100644
index 0000000..e190f7a
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ListCommand.java
@@ -0,0 +1,23 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.utils.PlayerList;
+import org.bukkit.command.CommandSender;
+
+public class ListCommand extends BaseCommand {
+ public ListCommand() {
+ super("list");
+ setAliases("online", "players", "who");
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ PlayerList onlinePlayerList = PlayerList.newList().sortedByRank();
+
+ sender.sendMessage(" ");
+ sender.sendMessage(PlayerList.ORDERED_RANKS);
+ sender.sendMessage(" ");
+ sender.sendMessage("(" + onlinePlayerList.size() + ") " + onlinePlayerList.asColoredNames());
+ sender.sendMessage(" ");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/MessageCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/MessageCommand.java
new file mode 100644
index 0000000..5dd4b98
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/MessageCommand.java
@@ -0,0 +1,56 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.event.player.PlayerMessageEvent;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.StringUtil;
+import me.devkevin.landcore.utils.message.CC;
+import me.devkevin.landcore.utils.message.Messages;
+import org.bukkit.entity.Player;
+
+public class MessageCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public MessageCommand(LandCore plugin) {
+ super("message");
+ this.plugin = plugin;
+ setAliases("msg", "m", "whisper", "w", "tell", "t");
+ setUsage(CC.RED + "Usage: /message ");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length < 2) {
+ player.sendMessage(usageMessage);
+ return;
+ }
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+
+ if (profile.getActiveMute() != null) {
+ if (profile.getActiveMute().isActive()) {
+ player.sendMessage(CC.RED + "You're muted for another " + profile.getActiveBan().getTimeRemaining() + ".");
+ } else if (profile.getActiveMute().isPermanent()) {
+ player.sendMessage(CC.RED + "You're permanently muted.");
+ }
+ return;
+ }
+
+ Player target = plugin.getServer().getPlayer(args[0]);
+
+ if (target == null) {
+ player.sendMessage(Messages.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ CoreProfile targetProfile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (targetProfile.hasPlayerIgnored(player.getUniqueId())) {
+ player.sendMessage(CC.RED + "That player is ignoring you!");
+ return;
+ }
+
+ plugin.getServer().getPluginManager().callEvent(new PlayerMessageEvent(player, target, StringUtil.buildString(args, 1)));
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/PCoinsCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/PCoinsCommand.java
new file mode 100644
index 0000000..94b2eb7
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/PCoinsCommand.java
@@ -0,0 +1,105 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.LandCoreAPI;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import me.devkevin.landcore.utils.message.Messages;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 24/03/2023 @ 1:43
+ * P_CoinsCommand / me.devkevin.landcore.commands.impl / LandCore
+ */
+public class PCoinsCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public PCoinsCommand(LandCore plugin) {
+ super("pcoin", Rank.MANAGER);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ if (args.length == 3) {
+ if (args[0].equalsIgnoreCase("set")) {
+ Player target = Bukkit.getPlayer(args[1]);
+
+ if (target == null) {
+ sender.sendMessage(Messages.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ CoreProfile targetAccount = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (!LandCoreAPI.isInteger(args[2]) || Integer.parseInt(args[2]) < 0) {
+ sender.sendMessage(CC.RED + "Please use numbers.");
+ return;
+ }
+
+ targetAccount.setP_coin(Integer.parseInt(args[2]));
+
+ sender.sendMessage("&eYou have successfully set &6" + targetAccount.getP_coin() + "'s &ePCoins to &6" + target.getName() + "&e.\"");
+ return;
+ }
+ if (args[0].equalsIgnoreCase("add")) {
+ Player target = Bukkit.getPlayer(args[1]);
+
+ if (target == null) {
+ sender.sendMessage(Messages.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ CoreProfile targetAccount = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (!LandCoreAPI.isInteger(args[2]) || Integer.parseInt(args[2]) <= 0) {
+ sender.sendMessage(CC.RED + "Please use numbers.");
+ return;
+ }
+
+ targetAccount.setP_coin(targetAccount.getP_coin() + Integer.parseInt(args[2]));
+
+ sender.sendMessage("&eYou have successfully added &6" + targetAccount.getP_coin() + "'s &ePCoins to &6" + target.getName() + "&e.\"");
+ return;
+ }
+ if (args[0].equalsIgnoreCase("remove")) {
+ Player target = Bukkit.getPlayer(args[1]);
+
+ if (target == null) {
+ sender.sendMessage(Messages.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ CoreProfile targetAccount = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (!LandCoreAPI.isInteger(args[2]) || Integer.parseInt(args[2]) <= 0) {
+ sender.sendMessage(CC.RED + "Please use numbers.");
+ return;
+ }
+
+ if (Integer.parseInt(args[2]) > targetAccount.getP_coin()) {
+ sender.sendMessage(CC.translate("&cInvalid amount."));
+ return;
+ }
+
+ targetAccount.setP_coin(targetAccount.getP_coin() - Integer.parseInt(args[2]));
+
+ sender.sendMessage("&eYou have successfully removed &6" + targetAccount.getP_coin() + "'s &ePCoins to &6" + target.getName() + "&e.\"");
+ return;
+ }
+ }
+
+ sender.sendMessage(" ");
+ sender.sendMessage(CC.translate("&e&lCoins HELP"));
+ sender.sendMessage(CC.translate("&e/pcoin set "));
+ sender.sendMessage(CC.translate("&e/pcoin add "));
+ sender.sendMessage(CC.translate("&e/pcoin remove "));
+ sender.sendMessage(" ");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/PingCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/PingCommand.java
new file mode 100644
index 0000000..656681b
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/PingCommand.java
@@ -0,0 +1,29 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCoreAPI;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+public class PingCommand extends PlayerCommand {
+ public PingCommand() {
+ super("ping");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ Player target = args.length < 1 || Bukkit.getPlayer(args[0]) == null ? player : Bukkit.getPlayer(args[0]);
+ int targetPing = target.spigot().getPing();
+
+ if (target == player) {
+ player.sendMessage(CC.PRIMARY + "Your ping is " + CC.SECONDARY + LandCoreAPI.getColorPing(targetPing) + CC.PRIMARY + " ms.");
+ } else {
+ int difference = targetPing - player.spigot().getPing();
+ String name = target.getDisplayName();
+
+ player.sendMessage(name + CC.PRIMARY + "'s ping is " + CC.SECONDARY + targetPing + CC.PRIMARY + " ms "
+ + CC.ACCENT + "(" + (difference > 0 ? "+" : "") + LandCoreAPI.getColorPing(difference) + " difference)" + CC.PRIMARY + ".");
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/PlayTimeCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/PlayTimeCommand.java
new file mode 100644
index 0000000..dc9fdc6
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/PlayTimeCommand.java
@@ -0,0 +1,43 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.utils.message.CC;
+import org.apache.commons.lang.time.DurationFormatUtils;
+import org.bukkit.Statistic;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/01/2023 @ 1:13
+ * PlayTimeCommand / land.pvp.core.commands.impl / LandCore
+ */
+public class PlayTimeCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public PlayTimeCommand(LandCore plugin) {
+ super("playtime");
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length == 0) {
+ long time = player.getStatistic(Statistic.PLAY_ONE_TICK);
+
+ player.sendMessage(CC.translate("&eYour playtime is &6" + DurationFormatUtils.formatDurationWords(time * 50L, true, true) + " &eon this server."));
+ } else {
+ Player target = this.plugin.getServer().getPlayer(args[0]);
+
+ if (target == null || !target.isOnline()) {
+ assert target != null;
+ player.sendMessage(CC.RED + "No player matching " + CC.YELLOW + target.getName() + CC.RED + " is connected to this server");
+ return;
+ }
+
+ long time = target.getStatistic(Statistic.PLAY_ONE_TICK);
+
+ player.sendMessage(CC.translate(plugin.getProfileManager().getProfile(target.getUniqueId()).getGrant().getRank().getColor() + target.getName() + "'s &eplaytime is &6" + DurationFormatUtils.formatDurationWords(time * 50L, true, true) + " &eon this server."));
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ReplyCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ReplyCommand.java
new file mode 100644
index 0000000..4ac6068
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ReplyCommand.java
@@ -0,0 +1,55 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.event.player.PlayerMessageEvent;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.StringUtil;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+public class ReplyCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public ReplyCommand(LandCore plugin) {
+ super("reply");
+ this.plugin = plugin;
+ setAliases("r");
+ setUsage(CC.RED + "Usage: /reply ");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length < 1) {
+ player.sendMessage(usageMessage);
+ return;
+ }
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+
+ if (profile.getActiveMute() != null) {
+ if (profile.getActiveMute().isActive()) {
+ player.sendMessage(CC.RED + "You're muted for another " + profile.getActiveBan().getTimeRemaining() + ".");
+ } else if (profile.getActiveMute().isPermanent()) {
+ player.sendMessage(CC.RED + "You're permanently muted.");
+ }
+ return;
+ }
+
+ Player target = plugin.getServer().getPlayer(profile.getConverser());
+
+ if (target == null) {
+ player.sendMessage(CC.RED + "You are not in a conversation.");
+ return;
+ }
+
+ CoreProfile targetProfile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (targetProfile.hasPlayerIgnored(player.getUniqueId())) {
+ player.sendMessage(CC.RED + "That player is ignoring you!");
+ return;
+ }
+
+ plugin.getServer().getPluginManager().callEvent(new PlayerMessageEvent(player, target, StringUtil.buildString(args, 0)));
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ReportCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ReportCommand.java
new file mode 100644
index 0000000..71eaa3c
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/ReportCommand.java
@@ -0,0 +1,58 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.inventory.menu.impl.ReportMenu;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.message.CC;
+import me.devkevin.landcore.utils.message.Messages;
+import org.bukkit.entity.Player;
+
+public class ReportCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public ReportCommand(LandCore plugin) {
+ super("report");
+ this.plugin = plugin;
+ setUsage(CC.RED + "Usage: /report ");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length == 0) {
+ player.sendMessage(usageMessage);
+ return;
+ }
+
+ Player target = plugin.getServer().getPlayer(args[0]);
+
+ if (target == null) {
+ player.sendMessage(Messages.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ if (player == target) {
+ player.sendMessage(CC.RED + "You can't report yourself!");
+ return;
+ }
+
+ CoreProfile targetProfile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (targetProfile.hasStaff()) {
+ player.sendMessage(CC.RED + "You can't report a staff member. If this staff member is harassing you or" +
+ " engaging in other abusive manners, please report this or contact a higher staff member.");
+ return;
+ }
+
+ if (args.length == 1 || args.length == 2) {
+ if (target.getName() != null || targetProfile.getName() != null) {
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+
+ profile.setReportingPlayerName(target.getName());
+ plugin.getMenuManager().getMenu(ReportMenu.class).open(player);
+ } else {
+ player.sendMessage(CC.RED + "Error: That player does not exist.");
+ }
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/StoreCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/StoreCommand.java
new file mode 100644
index 0000000..c8bb166
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/StoreCommand.java
@@ -0,0 +1,25 @@
+package me.devkevin.landcore.commands.impl;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 24/03/2023 @ 20:43
+ * StoreCommand / me.devkevin.landcore.commands.impl / LandCore
+ */
+public class StoreCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public StoreCommand(LandCore plugin) {
+ super("store");
+ this.plugin = plugin;
+ setAliases("pstore");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ player.openInventory(this.plugin.getStorePCoinMenu().menu(player).getCurrentPage());
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/TeleportPositionCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/TeleportPositionCommand.java
new file mode 100644
index 0000000..615e8f3
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/TeleportPositionCommand.java
@@ -0,0 +1,44 @@
+package me.devkevin.landcore.commands.impl;
+
+import com.google.common.primitives.Ints;
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 07/02/2023 @ 18:05
+ * TeleportPositionCommand / me.devkevin.landcore.commands.impl / LandCore
+ */
+public class TeleportPositionCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public TeleportPositionCommand(LandCore plugin) {
+ super("tppos", Rank.DEVELOPER);
+ this.plugin = plugin;
+ setAliases("teleportposition");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length < 3) {
+ player.sendMessage(CC.RED + "Usage: /tppos ");
+ return;
+ }
+
+ Integer x = Ints.tryParse(args[0]);
+ Integer y = Ints.tryParse(args[1]);
+ Integer z = Ints.tryParse(args[2]);
+
+ if (x == null || y == null || z == null) {
+ player.sendMessage(CC.RED + "Location not found.");
+ return;
+ }
+
+ player.sendMessage(CC.GRAY + "Teleporting...");
+ player.teleport(new Location(player.getWorld(), (double) x, (double) y, (double) z));
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/AltsCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/AltsCommand.java
new file mode 100644
index 0000000..1bc4294
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/AltsCommand.java
@@ -0,0 +1,60 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import me.devkevin.landcore.utils.message.Messages;
+import org.bukkit.entity.Player;
+import java.util.*;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 09/02/2023 @ 17:25
+ * AltsCommand / me.devkevin.landcore.commands.impl.staff / LandCore
+ */
+public class AltsCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public AltsCommand(LandCore plugin) {
+ super("alts", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ setAliases("dupeip");
+ setUsage(CC.RED + "Usage: /alts ");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ Player target = plugin.getServer().getPlayer(args[0]);
+ CoreProfile coreProfile = this.plugin.getProfileManager().getProfile(player.getUniqueId());
+
+ if (target == null || coreProfile == null) {
+ player.sendMessage(Messages.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ List alts = new ArrayList<>();
+
+ for (UUID altUUID : coreProfile.getKnownAlts()) {
+ CoreProfile altProfile = this.plugin.getProfileManager().getProfile(altUUID);
+
+ if (altProfile != null) {
+ alts.add(altProfile);
+ }
+ }
+
+ if (alts.isEmpty()) {
+ player.sendMessage(CC.RED + "This player has no known alt accounts.");
+ } else {
+ StringBuilder builder = new StringBuilder();
+
+ for (CoreProfile altProfile : alts) {
+ builder.append(altProfile.getName());
+ builder.append(", ");
+ }
+
+ player.sendMessage(CC.GOLD + "Alts: " + CC.R + builder);
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/BroadcastCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/BroadcastCommand.java
new file mode 100644
index 0000000..d1b9edd
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/BroadcastCommand.java
@@ -0,0 +1,37 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.StringUtil;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender;
+
+public class BroadcastCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public BroadcastCommand(LandCore plugin) {
+ super("broadcast", Rank.ADMIN);
+ this.plugin = plugin;
+ setAliases("bc");
+ setUsage(CC.RED + "Usage: /broadcast [-god]");
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ if (args.length == 0) {
+ sender.sendMessage(usageMessage);
+ return;
+ }
+
+ String message = CC.SECONDARY + "[Alert] " + CC.PRIMARY
+ + ChatColor.translateAlternateColorCodes('&', StringUtil.buildString(args, 0)).trim();
+
+ if (message.endsWith(" -god")) {
+ message = message.substring(12, message.length() - 5).trim();
+ }
+
+ plugin.getServer().broadcastMessage(message);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/BuildServerCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/BuildServerCommand.java
new file mode 100644
index 0000000..ccc239e
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/BuildServerCommand.java
@@ -0,0 +1,26 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.LandCoreAPI;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 07/02/2023 @ 17:46
+ * BuilServerCommand / me.devkevin.landcore.commands.impl / LandCore
+ */
+public class BuildServerCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public BuildServerCommand(LandCore plugin) {
+ super("buildserver", Rank.BUILDER);
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ LandCoreAPI.sendToServer(player, "build");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/FreezeCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/FreezeCommand.java
new file mode 100644
index 0000000..be84df7
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/FreezeCommand.java
@@ -0,0 +1,68 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import com.google.common.collect.Maps;
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.event.player.PlayerFreezeEvent;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.util.Map;
+
+public class FreezeCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public FreezeCommand(LandCore plugin) {
+ super("freeze", Rank.SENIOR_MOD);
+ this.plugin = plugin;
+ setAliases("screenshare", "ss");
+ setUsage("/freeze ");
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ if (args.length < 1) {
+ sender.sendMessage(CC.RED + getUsage());
+ return;
+ }
+
+ Player target = Bukkit.getPlayer(args[0]);
+
+ if (target != null) {
+
+ CoreProfile targetProfile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (targetProfile.hasStaff()) {
+ sender.sendMessage(CC.RED + "If you believe a staff member is cheating, please alert higher staff.");
+ return;
+ }
+
+ String server = plugin.getServerName();
+ String targetName = target.getName();
+ String senderName = sender.getName();
+
+ Map map = Maps.newHashMap();
+ map.put("server", server);
+ map.put("frozen", targetName);
+ map.put("sender", senderName);
+
+ if (targetProfile.freeze(sender)) {
+ map.put("isFrozen", true);
+ plugin.getRedisMessenger().send("freeze-listener", map);
+ return;
+ }
+ map.put("isFrozen", false);
+ plugin.getRedisMessenger().send("freeze-listener", map);
+ return;
+ }
+
+ PlayerFreezeEvent event = new PlayerFreezeEvent(target);
+ this.plugin.getServer().getPluginManager().callEvent(event);
+
+ sender.sendMessage(CC.RED + "That player is offline or does not exist.");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/GameModeCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/GameModeCommand.java
new file mode 100644
index 0000000..5256243
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/GameModeCommand.java
@@ -0,0 +1,47 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.GameMode;
+import org.bukkit.entity.Player;
+
+public class GameModeCommand extends PlayerCommand {
+ public GameModeCommand() {
+ super("gamemode", Rank.SENIOR_MOD);
+ setAliases("gm");
+ setUsage(CC.RED + "Usage: /gamemode ");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length < 1) {
+ player.sendMessage(usageMessage);
+ return;
+ }
+
+ switch (args[0].toLowerCase()) {
+ case "1":
+ case "creative":
+ case "c":
+ player.setGameMode(GameMode.CREATIVE);
+ player.sendMessage(CC.GREEN + "Your game mode was set to creative.");
+ break;
+ case "0":
+ case "survival":
+ case "s":
+ player.setGameMode(GameMode.SURVIVAL);
+ player.sendMessage(CC.GREEN + "Your game mode was set to survival.");
+ break;
+ case "2":
+ case "adventure":
+ case "a":
+ player.setGameMode(GameMode.ADVENTURE);
+ player.sendMessage(CC.GREEN + "Your game mode was set to adventure.");
+ break;
+ default:
+ player.sendMessage(usageMessage);
+ break;
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/MisplaceCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/MisplaceCommand.java
new file mode 100644
index 0000000..d717d1d
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/MisplaceCommand.java
@@ -0,0 +1,40 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 23/01/2023 @ 17:57
+ * MisplaceCommand / me.devkevin.landcore.commands.impl.staff / LandCore
+ */
+public class MisplaceCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public MisplaceCommand(LandCore plugin) {
+ super("xp", Rank.MANAGER);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ Player target = this.plugin.getServer().getPlayer(args[0]);
+
+ CoreProfile coreProfile = this.plugin.getProfileManager().getProfile(target.getUniqueId());
+ try {
+ double d = Double.parseDouble(args[1]);
+ if (d > 0.25) {
+ sender.sendMessage(CC.RED + "Warning! " + d + " is over the recommended amount. The recommended amount is 0.25.");
+ }
+ coreProfile.setMisplace(d);
+ sender.sendMessage(CC.GREEN + "Misplace set to " + d + ".");
+ } catch (Exception ex) {
+ sender.sendMessage(CC.RED + "Invalid amount.");
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/MuteChatCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/MuteChatCommand.java
new file mode 100644
index 0000000..764b88c
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/MuteChatCommand.java
@@ -0,0 +1,25 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+public class MuteChatCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public MuteChatCommand(LandCore plugin) {
+ super("mutechat", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ boolean globalChatMuted = !plugin.getServerSettings().isGlobalChatMuted();
+
+ plugin.getServerSettings().setGlobalChatMuted(globalChatMuted);
+ plugin.getServer().broadcastMessage(globalChatMuted ? CC.RED + "Global chat has been muted by " + player.getName() + "."
+ : CC.GREEN + "Global chat has been enabled by " + plugin.getProfileManager().getProfile(player.getUniqueId()).getRank().getColor() + player.getName() + ".");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/ShutdownCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/ShutdownCommand.java
new file mode 100644
index 0000000..00b86d3
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/ShutdownCommand.java
@@ -0,0 +1,63 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.event.server.ServerShutdownCancelEvent;
+import me.devkevin.landcore.event.server.ServerShutdownScheduleEvent;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.task.ShutdownTask;
+import me.devkevin.landcore.utils.NumberUtil;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.command.CommandSender;
+
+public class ShutdownCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public ShutdownCommand(LandCore plugin) {
+ super("shutdown", Rank.ADMIN);
+ this.plugin = plugin;
+ setUsage(CC.RED + "Usage: /shutdown ");
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ if (args.length < 1) {
+ sender.sendMessage(usageMessage);
+ return;
+ }
+
+ String arg = args[0];
+
+ if (arg.equals("cancel")) {
+ ShutdownTask task = plugin.getServerSettings().getShutdownTask();
+
+ if (task == null) {
+ sender.sendMessage(CC.RED + "There is no shutdown in progress.");
+ } else {
+ plugin.getServer().getPluginManager().callEvent(new ServerShutdownCancelEvent());
+
+ task.cancel();
+ plugin.getServerSettings().setShutdownTask(null);
+ plugin.getServer().broadcastMessage(CC.GREEN + "The shutdown in progress has been cancelled by " + sender.getName() + ".");
+ }
+ return;
+ }
+
+ Integer seconds = NumberUtil.getInteger(arg);
+
+ if (seconds == null) {
+ sender.sendMessage(usageMessage);
+ } else {
+ if (seconds >= 5 && seconds <= 300) {
+ plugin.getServer().getPluginManager().callEvent(new ServerShutdownScheduleEvent());
+
+ ShutdownTask task = new ShutdownTask(seconds);
+
+ plugin.getServerSettings().setShutdownTask(task);
+ task.runTaskTimer(plugin, 0L, 20L);
+ } else {
+ sender.sendMessage(CC.RED + "Please enter a time between 5 and 300 seconds.");
+ }
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/SlowChatCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/SlowChatCommand.java
new file mode 100644
index 0000000..ea857d4
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/SlowChatCommand.java
@@ -0,0 +1,67 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.command.CommandSender;
+
+public class SlowChatCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public SlowChatCommand(LandCore plugin) {
+ super("slowchat", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ setUsage(CC.RED + "Usage: /slowchat ");
+ }
+
+ private static Integer getInt(String arg) {
+ try {
+ int i = Integer.parseInt(arg);
+
+ if (i < 4 || i > 60) {
+ return null;
+ }
+
+ return i;
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ if (args.length < 1) {
+ sender.sendMessage(usageMessage);
+ return;
+ }
+
+ String arg = args[0];
+
+ switch (arg.toLowerCase()) {
+ case "off":
+ case "toggle":
+ case "disable":
+ int slowChatTime = plugin.getServerSettings().getSlowChatTime();
+
+ if (slowChatTime == -1) {
+ sender.sendMessage(CC.RED + "Slow chat is already disabled!");
+ } else {
+ plugin.getServerSettings().setSlowChatTime(-1);
+ plugin.getServer().broadcastMessage(CC.RED + "Slow chat has been disabled by " + sender.getName() + ".");
+ }
+ break;
+ default:
+ Integer time = getInt(arg);
+
+ if (time == null) {
+ sender.sendMessage(CC.RED + "You must enter a valid time between 4 and 60 seconds.");
+ } else {
+ plugin.getServerSettings().setSlowChatTime(time);
+ plugin.getServer().broadcastMessage(CC.YELLOW + "Slow chat has been enabled and set to " + time
+ + " seconds by " + sender.getName() + ".");
+ }
+ break;
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/StaffChatCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/StaffChatCommand.java
new file mode 100644
index 0000000..9839f5a
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/StaffChatCommand.java
@@ -0,0 +1,36 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.StringUtil;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+public class StaffChatCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public StaffChatCommand(LandCore plugin) {
+ super("staffchat", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ setAliases("sc");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+
+ if (args.length == 0) {
+ boolean inStaffChat = !profile.isInStaffChat();
+
+ profile.setInStaffChat(inStaffChat);
+
+ player.sendMessage(inStaffChat ? CC.GREEN + "You are now in staff chat." : CC.RED + "You are no longer in staff chat.");
+ } else {
+ String message = StringUtil.buildString(args, 0);
+
+ plugin.getStaffManager().messageStaff(profile.getChatFormat(), message);
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/TeleportCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/TeleportCommand.java
new file mode 100644
index 0000000..de08624
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/TeleportCommand.java
@@ -0,0 +1,68 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import me.devkevin.landcore.utils.message.Messages;
+import org.bukkit.entity.Player;
+
+public class TeleportCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public TeleportCommand(LandCore plugin) {
+ super("tp", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ setAliases("teleport");
+ setUsage(CC.RED + "Usage: /teleport [player]");
+ }
+
+ private static boolean isOffline(Player checker, Player target) {
+ if (target == null) {
+ checker.sendMessage(Messages.PLAYER_NOT_FOUND);
+ return true;
+ }
+
+ return false;
+ }
+
+ private void teleport(Player to, Player from) {
+ to.teleport(from);
+ to.sendMessage(CC.GREEN + "You have been teleported to " + from.getName() + ".");
+
+ CoreProfile fromProfile = plugin.getProfileManager().getProfile(from.getUniqueId());
+
+ if (fromProfile.hasStaff()) {
+ from.sendMessage(CC.GREEN + to.getName() + " has been teleported to you.");
+ }
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length < 1) {
+ player.sendMessage(usageMessage);
+ return;
+ }
+
+ Player target = plugin.getServer().getPlayer(args[0]);
+
+ if (isOffline(player, target)) {
+ return;
+ }
+
+ if (args.length < 2) {
+ teleport(player, target);
+ } else {
+ Player target2 = plugin.getServer().getPlayer(args[1]);
+
+ if (isOffline(player, target2)) {
+ return;
+ }
+
+ teleport(target, target2);
+
+ player.sendMessage(CC.GREEN + "Teleported " + target.getName() + " to " + target2.getName() + ".");
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/VanishCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/VanishCommand.java
new file mode 100644
index 0000000..3008226
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/VanishCommand.java
@@ -0,0 +1,33 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class VanishCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public VanishCommand(LandCore plugin) {
+ super("vanish", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ Player player = (Player) sender;
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+ boolean vanished = !profile.isVanished();
+
+ profile.setVanished(vanished);
+
+ for (Player online : plugin.getServer().getOnlinePlayers()) {
+ plugin.getStaffManager().hideVanishedStaffFromPlayer(online);
+ }
+
+ player.sendMessage(vanished ? CC.GREEN + "Poof, you vanished." : CC.RED + "You're visible again.");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/WhitelistCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/WhitelistCommand.java
new file mode 100644
index 0000000..676d7c0
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/WhitelistCommand.java
@@ -0,0 +1,59 @@
+package me.devkevin.landcore.commands.impl.staff;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.server.ServerSettings;
+import me.devkevin.landcore.server.WhitelistMode;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+public class WhitelistCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public WhitelistCommand(LandCore plugin) {
+ super("whitelist", Rank.ADMIN);
+ this.plugin = plugin;
+ setAliases("wl");
+ setUsage(CC.RED + "Usage: /whitelist ");
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ if (args.length < 1) {
+ sender.sendMessage(usageMessage);
+ return;
+ }
+
+ ServerSettings settings = plugin.getServerSettings();
+
+ switch (args[0].toLowerCase()) {
+ case "none":
+ case "off":
+ settings.setServerWhitelistMode(WhitelistMode.NONE);
+ break;
+ case "ranks":
+ case "donors":
+ settings.setServerWhitelistMode(WhitelistMode.RANKS);
+ break;
+ case "staff":
+ case "on":
+ settings.setServerWhitelistMode(WhitelistMode.STAFF);
+ break;
+ default:
+ sender.sendMessage(CC.RED + "That's not a valid whitelist mode!");
+ return;
+ }
+
+ WhitelistMode whitelistMode = settings.getServerWhitelistMode();
+ Server server = plugin.getServer();
+
+ if (whitelistMode == WhitelistMode.NONE) {
+ server.broadcastMessage(CC.GREEN + "The server is no longer whitelisted!");
+ } else {
+ whitelistMode.activate();
+ server.broadcastMessage(CC.RED + "The server is now whitelisted (Mode: " + whitelistMode + ").");
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/BanCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/BanCommand.java
new file mode 100644
index 0000000..16eb68b
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/BanCommand.java
@@ -0,0 +1,79 @@
+package me.devkevin.landcore.commands.impl.staff.punish;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.punishment.Punishment;
+import me.devkevin.landcore.punishment.PunishmentType;
+import me.devkevin.landcore.utils.Duration;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+import java.util.Objects;
+import java.util.UUID;
+
+public class BanCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public BanCommand(LandCore plugin) {
+ super("ban", Rank.MOD);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ Player target = Bukkit.getPlayer(args[0]);
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (args.length < 3) {
+ sender.sendMessage(CC.RED + "Usage: /ban " + CC.GRAY + "[-s]" + CC.RED + ".");
+ }
+
+ if (profile == null) {
+ sender.sendMessage(CC.RED + "Could no load " + target.getName() + " database. Contact with the developer.");
+ }
+
+ if (Objects.requireNonNull(profile).getActiveBan() != null) {
+ sender.sendMessage(CC.RED + "That player is already banned.");
+ return;
+ }
+
+ long duration = Duration.fromString(args[1]).getValue();
+ boolean silent = args[args.length - 1].equalsIgnoreCase("-s");
+
+ if (duration == -1) {
+ sender.sendMessage(CC.RED + "That duration is not valid.");
+ sender.sendMessage(CC.RED + "Example: [perm/1y1m1w1d]");
+ return;
+ }
+
+ String staffName = sender instanceof Player ? plugin.getProfileManager().getProfile(((Player) sender).getUniqueId()).getGrant().getRank().getColor() + sender.getName() : CC.D_RED + "Console";
+
+ Punishment punishment = new Punishment(UUID.randomUUID(), PunishmentType.BAN, System.currentTimeMillis(),
+ args[1], duration);
+
+ if (sender instanceof Player) {
+ punishment.setAddedBy(((Player) sender).getUniqueId());
+ }
+
+ profile.getPunishments().add(punishment);
+ profile.save(true);
+
+ punishment.broadcast(staffName, target, silent);
+
+ Player player = profile.getPlayer();
+
+ if (player != null) {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ player.kickPlayer(punishment.getKickMessage());
+ }
+ }.runTask(LandCore.getInstance());
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/CheckCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/CheckCommand.java
new file mode 100644
index 0000000..7bf0022
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/CheckCommand.java
@@ -0,0 +1,40 @@
+package me.devkevin.landcore.commands.impl.staff.punish;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.punishment.menu.PunishmentsMenu;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 09/02/2023 @ 15:26
+ * CheckCommand / me.devkevin.landcore.commands.impl.staff.punish / LandCore
+ */
+public class CheckCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public CheckCommand(LandCore plugin) {
+ super("check", Rank.MOD);
+ this.plugin = plugin;
+ setAliases("c");
+ }
+
+
+ @Override
+ public void execute(Player player, String[] args) {
+ OfflinePlayer target = Bukkit.getOfflinePlayer(args[0]);
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (profile == null) {
+ player.sendMessage(CC.RED + "Could no load " + target.getName() + " database. Contact with the developer.");
+ }
+
+ new PunishmentsMenu(profile).openMenu(player);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/KickCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/KickCommand.java
new file mode 100644
index 0000000..bd8d106
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/KickCommand.java
@@ -0,0 +1,69 @@
+package me.devkevin.landcore.commands.impl.staff.punish;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.punishment.Punishment;
+import me.devkevin.landcore.punishment.PunishmentType;
+import me.devkevin.landcore.utils.Duration;
+import me.devkevin.landcore.utils.StringUtil;
+import me.devkevin.landcore.utils.message.CC;
+import me.devkevin.landcore.utils.message.Messages;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import java.util.Objects;
+import java.util.UUID;
+
+public class KickCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public KickCommand(LandCore plugin) {
+ super("kick", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ Player target = Bukkit.getPlayer(args[0]);
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (args.length < 2) {
+ sender.sendMessage(CC.RED + "Usage: /kick " + CC.GRAY + "[-s]" + CC.RED + ".");
+ }
+
+ if (profile == null) {
+ sender.sendMessage(CC.RED + "Could no load " + target.getName() + " database. Contact with the developer.");
+ }
+
+ String staffName = sender instanceof Player ? plugin.getProfileManager().getProfile(((Player) sender).getUniqueId()).getGrant().getRank().getColor() + sender.getName() : CC.D_RED + "Console";
+
+
+ Punishment punishment = new Punishment(target.getUniqueId(), PunishmentType.KICK, System.currentTimeMillis(),
+ args[1], -1);
+
+ if (sender instanceof Player) {
+ punishment.setAddedBy(((Player) sender).getUniqueId());
+ }
+
+ Objects.requireNonNull(profile).getPunishments().add(punishment);
+ profile.save(true);
+
+ punishment.broadcast(staffName, target, true);
+
+ Player player = profile.getPlayer();
+
+ if (player != null) {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ player.kickPlayer(punishment.getKickMessage());
+ }
+ }.runTask(LandCore.getInstance());
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/MuteCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/MuteCommand.java
new file mode 100644
index 0000000..06622fa
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/MuteCommand.java
@@ -0,0 +1,81 @@
+package me.devkevin.landcore.commands.impl.staff.punish;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.punishment.Punishment;
+import me.devkevin.landcore.punishment.PunishmentType;
+import me.devkevin.landcore.utils.Duration;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import java.util.Objects;
+import java.util.UUID;
+
+public class MuteCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public MuteCommand(LandCore plugin) {
+ super("mute", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ Player target = Bukkit.getPlayer(args[0]);
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+
+ if (args.length < 3) {
+ sender.sendMessage(CC.RED + "Usage: /mute " + CC.GRAY + "[-s]" + CC.RED + ".");
+ }
+
+ if (profile == null) {
+ sender.sendMessage(CC.RED + "Could no load " + target.getName() + " database. Contact with the developer.");
+ }
+
+ if (Objects.requireNonNull(profile).getActiveMute() != null) {
+ sender.sendMessage(CC.RED + "That player is already muted.");
+ return;
+ }
+
+ long duration = Duration.fromString(args[1]).getValue();
+ boolean silent = args[args.length - 1].equalsIgnoreCase("-s");
+
+ if (duration == -1) {
+ sender.sendMessage(CC.RED + "That duration is not valid.");
+ sender.sendMessage(CC.RED + "Example: [perm/1y1m1w1d]");
+ return;
+ }
+
+ String staffName = sender instanceof Player ? plugin.getProfileManager().getProfile(((Player) sender).getUniqueId()).getGrant().getRank().getColor() + sender.getName() : CC.D_RED + "Console";
+
+ Punishment punishment = new Punishment(target.getUniqueId(), PunishmentType.MUTE, System.currentTimeMillis(),
+ args[1], duration);
+
+ if (sender instanceof Player) {
+ punishment.setAddedBy(((Player) sender).getUniqueId());
+ }
+
+ profile.getPunishments().add(punishment);
+ profile.save(true);
+
+ Player player = profile.getPlayer();
+
+
+ if (player != null) {
+ String senderName = sender instanceof Player ? plugin.getProfileManager().getProfiles().get(((Player) sender).getUniqueId()).getGrant().getRank().getColor() : CC.D_RED + "Console";
+ player.sendMessage(CC.RED + "You have been muted by " + senderName + CC.RED + " for: " + CC.YELLOW + args[1]);
+
+ if (!punishment.isPermanent()) {
+ player.sendMessage(CC.RED + "This mute will expire in " + CC.YELLOW + punishment.getTimeRemaining());
+ }
+ }
+
+ punishment.broadcast(staffName, target, silent);
+ }
+
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/UnbanCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/UnbanCommand.java
new file mode 100644
index 0000000..4969c1b
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/UnbanCommand.java
@@ -0,0 +1,58 @@
+package me.devkevin.landcore.commands.impl.staff.punish;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.punishment.Punishment;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class UnbanCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public UnbanCommand(LandCore plugin) {
+ super("unban", Rank.MOD);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ OfflinePlayer target = Bukkit.getOfflinePlayer(args[0]);
+
+ if (args.length < 2) {
+ sender.sendMessage(CC.RED + "Usage: /unban " + CC.GRAY + "[-s]" + CC.RED + ".");
+ }
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (profile == null) {
+ sender.sendMessage(CC.RED + "Could no load " + target.getName() + " database. Contact with the developer.");
+ }
+
+ if ((profile != null ? profile.getActiveBan() : null) == null) {
+ sender.sendMessage(CC.RED + "That player is not banned.");
+ return;
+ }
+
+ boolean silent = args[args.length - 1].equalsIgnoreCase("-s");
+
+ String staffName = sender instanceof Player ? plugin.getProfileManager().getProfile(((Player) sender).getUniqueId()).getGrant().getRank().getColor() + sender.getName() : CC.D_RED + "Console";
+
+ Punishment punishment = profile.getActiveBan();
+ punishment.setPardonedAt(System.currentTimeMillis());
+ punishment.setPardonedReason(args[1]);
+ punishment.setPardoned(true);
+
+ if (sender instanceof Player) {
+ punishment.setPardonedBy(((Player) sender).getUniqueId());
+ }
+
+ profile.save(true);
+
+ punishment.broadcast(staffName, target.getPlayer(), silent);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/UnmuteCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/UnmuteCommand.java
new file mode 100644
index 0000000..e669bab
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/UnmuteCommand.java
@@ -0,0 +1,57 @@
+package me.devkevin.landcore.commands.impl.staff.punish;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.punishment.Punishment;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class UnmuteCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public UnmuteCommand(LandCore plugin) {
+ super("unmute", Rank.MOD);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ Player target = Bukkit.getPlayer(args[0]);
+
+ if (args.length < 2) {
+ sender.sendMessage(CC.RED + "Usage: /unmute " + CC.GRAY + "[-s]" + CC.RED + ".");
+ }
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (profile == null) {
+ sender.sendMessage(CC.RED + "Could no load " + target.getName() + " database. Contact with the developer.");
+ }
+
+ if ((profile != null ? profile.getActiveMute() : null) == null) {
+ sender.sendMessage(CC.RED + "That player is not muted.");
+ return;
+ }
+
+ boolean silent = args[args.length - 1].equalsIgnoreCase("-s");
+
+ String staffName = sender instanceof Player ? plugin.getProfileManager().getProfile(((Player) sender).getUniqueId()).getGrant().getRank().getColor() + sender.getName() : CC.D_RED + "Console";
+
+ Punishment punishment = profile.getActiveMute();
+ punishment.setPardonedAt(System.currentTimeMillis());
+ punishment.setPardonedReason(args[1]);
+ punishment.setPardoned(true);
+
+ if (sender instanceof Player) {
+ punishment.setPardonedBy(((Player) sender).getUniqueId());
+ }
+
+ profile.save(true);
+
+ punishment.broadcast(staffName, target, silent);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/WarnCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/WarnCommand.java
new file mode 100644
index 0000000..b03ef93
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/staff/punish/WarnCommand.java
@@ -0,0 +1,67 @@
+package me.devkevin.landcore.commands.impl.staff.punish;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.punishment.Punishment;
+import me.devkevin.landcore.punishment.PunishmentType;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 09/02/2023 @ 15:52
+ * WarnCommand / me.devkevin.landcore.commands.impl.staff.punish / LandCore
+ */
+public class WarnCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public WarnCommand(LandCore plugin) {
+ super("warn", Rank.TRIAL_MOD);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ Player target = Bukkit.getPlayer(args[0]);
+
+ if (args.length < 2) {
+ sender.sendMessage(CC.RED + "Usage: /warn " + CC.GRAY + "[-s]" + CC.RED + ".");
+ }
+
+ CoreProfile profile = plugin.getProfileManager().getProfile(target.getUniqueId());
+
+ if (profile == null) {
+ sender.sendMessage(CC.RED + "Could no load " + target.getName() + " database. Contact with the developer.");
+ }
+
+ boolean silent = args[args.length - 1].equalsIgnoreCase("-s");
+
+ String staffName = sender instanceof Player ? plugin.getProfileManager().getProfile(((Player) sender).getUniqueId()).getGrant().getRank().getColor() + sender.getName() : CC.D_RED + "Console";
+
+ Punishment punishment = new Punishment(target.getUniqueId(), PunishmentType.WARN, System.currentTimeMillis(),
+ args[1], -1);
+
+ if (sender instanceof Player) {
+ punishment.setAddedBy(((Player) sender).getUniqueId());
+ }
+
+ Objects.requireNonNull(profile).getPunishments().add(punishment);
+ profile.save(true);
+
+ Player player = profile.getPlayer();
+
+ if (player != null) {
+ String senderName = sender instanceof Player ? plugin.getProfileManager().getProfiles().get(((Player) sender).getUniqueId()).getGrant().getRank().getColor() : CC.D_RED + "Console";
+ player.sendMessage(CC.RED + "You have been warned by " + senderName + CC.RED + " for: " + CC.YELLOW + args[1]);
+ }
+
+ punishment.broadcast(staffName, target, silent);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/toggle/ToggleGlobalChat.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/toggle/ToggleGlobalChat.java
new file mode 100644
index 0000000..e3228df
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/toggle/ToggleGlobalChat.java
@@ -0,0 +1,26 @@
+package me.devkevin.landcore.commands.impl.toggle;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+public class ToggleGlobalChat extends PlayerCommand {
+ private final LandCore plugin;
+
+ public ToggleGlobalChat(LandCore plugin) {
+ super("toggleglobalchat");
+ this.plugin = plugin;
+ setAliases("togglechat", "tgc");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+ boolean enabled = !profile.isGlobalChatEnabled();
+
+ profile.setGlobalChatEnabled(enabled);
+ player.sendMessage(enabled ? CC.GREEN + "Global chat enabled." : CC.RED + "Global chat disabled.");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/toggle/ToggleMessagesCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/toggle/ToggleMessagesCommand.java
new file mode 100644
index 0000000..58a870b
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/toggle/ToggleMessagesCommand.java
@@ -0,0 +1,26 @@
+package me.devkevin.landcore.commands.impl.toggle;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+public class ToggleMessagesCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public ToggleMessagesCommand(LandCore plugin) {
+ super("togglemessages");
+ this.plugin = plugin;
+ setAliases("tpm");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+ boolean messaging = !profile.isMessaging();
+
+ profile.setMessaging(messaging);
+ player.sendMessage(messaging ? CC.GREEN + "Messages enabled." : CC.RED + "Messages disabled.");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/commands/impl/toggle/ToggleSoundsCommand.java b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/toggle/ToggleSoundsCommand.java
new file mode 100644
index 0000000..fce2f16
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/commands/impl/toggle/ToggleSoundsCommand.java
@@ -0,0 +1,26 @@
+package me.devkevin.landcore.commands.impl.toggle;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+public class ToggleSoundsCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public ToggleSoundsCommand(LandCore plugin) {
+ super("togglesounds");
+ this.plugin = plugin;
+ setAliases("sounds", "ts");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ CoreProfile profile = plugin.getProfileManager().getProfile(player.getUniqueId());
+ boolean playingSounds = !profile.isPlayingSounds();
+
+ profile.setPlayingSounds(playingSounds);
+ player.sendMessage(playingSounds ? CC.GREEN + "Sounds enabled." : CC.RED + "Sounds disabled.");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/disguise/commands/DisguiseCommand.java b/LandCore/src/main/java/me/devkevin/landcore/disguise/commands/DisguiseCommand.java
new file mode 100644
index 0000000..9838e85
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/disguise/commands/DisguiseCommand.java
@@ -0,0 +1,67 @@
+package me.devkevin.landcore.disguise.commands;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.disguise.manager.DisguiseManager;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import xyz.haoshoku.nick.api.NickAPI;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 09/02/2023 @ 18:58
+ * DisguiseCommand / me.devkevin.landcore.disguise / LandCore
+ */
+public class DisguiseCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public DisguiseCommand(LandCore plugin) {
+ super("disguise", Rank.TRIAL_MOD); // temp rank for test
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void execute(CommandSender sender, String[] args) {
+ Player player = (Player) sender;
+
+ if ("random".equals(args[0])) {
+ String disguiseName;
+ String disguiseSkin = DisguiseManager.generateSkin().split(":")[0];
+
+ if (DisguiseManager.nickData.get(player) != null) {
+ disguiseName = DisguiseManager.nickData.get(player);
+ } else {
+ disguiseName = DisguiseManager.generate();
+ }
+
+ plugin.getDisguiseManager().setPlayerDisguise(player, disguiseName, disguiseSkin);
+
+ // first disguise a player and then after 2 sec open the rank menu
+ plugin.getServer().getScheduler().runTaskLater(plugin, () -> {
+ // check is player in nicked yet so we won't get errors
+ if (NickAPI.isNicked(player)) {
+ player.openInventory(this.plugin.getDisguiseMenu().getRankMenu().getCurrentPage());
+ }
+ }, 20L);
+
+
+ } else {
+ if (NickAPI.nickExists(args[0])) {
+ player.sendMessage(CC.RED + "That name is already used.");
+ return;
+ }
+
+ plugin.getDisguiseManager().setPlayerDisguise(player, args[0], args[1]);
+
+ // first disguise a player and then after 2 sec open the rank menu
+ plugin.getServer().getScheduler().runTaskLater(plugin, () -> {
+ // check is player in nicked yet so we won't get errors
+ if (NickAPI.isNicked(player)) {
+ player.openInventory(this.plugin.getDisguiseMenu().getRankMenu().getCurrentPage());
+ }
+ }, 20L);
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/disguise/commands/UndisguiseCommand.java b/LandCore/src/main/java/me/devkevin/landcore/disguise/commands/UndisguiseCommand.java
new file mode 100644
index 0000000..031f5e0
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/disguise/commands/UndisguiseCommand.java
@@ -0,0 +1,52 @@
+package me.devkevin.landcore.disguise.commands;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.BaseCommand;
+import me.devkevin.landcore.managers.PlayerManager;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import xyz.haoshoku.nick.NickPlugin;
+import xyz.haoshoku.nick.api.NickAPI;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 10/02/2023 @ 0:23
+ * UndisguiseCommand / me.devkevin.landcore.disguise / LandCore
+ */
+public class UndisguiseCommand extends BaseCommand {
+ private final LandCore plugin;
+
+ public UndisguiseCommand(LandCore plugin) {
+ super("undisguise", Rank.TRIAL_MOD); // temp rank for test
+ this.plugin = plugin;
+ }
+
+
+ @Override
+ public void execute(CommandSender sender, String[] args) {
+ Player player = (Player) sender;
+
+ CoreProfile coreProfile = plugin.getProfileManager().getProfile(player.getUniqueId());
+
+ if (NickAPI.isNicked(player)) {
+ NickAPI.resetNick(player);
+ NickAPI.resetSkin(player);
+ NickAPI.resetGameProfileName(player);
+ NickAPI.resetUniqueId(player);
+ NickAPI.refreshPlayer(player);
+ NickAPI.refreshPlayerSync(player);
+
+ coreProfile.setDisguiseRank(null); // when player un disguise we reset the rank
+
+ player.setDisplayName(player.getName());
+ player.setPlayerListName(player.getName());
+
+ player.sendMessage(CC.SECONDARY + "You've been " + CC.RED + "undisguised" + CC.SECONDARY + " and reset to your default skin.");
+ } else {
+ player.sendMessage(CC.RED + "You aren't currently disguised!");
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/disguise/manager/DisguiseManager.java b/LandCore/src/main/java/me/devkevin/landcore/disguise/manager/DisguiseManager.java
new file mode 100644
index 0000000..2bdda0a
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/disguise/manager/DisguiseManager.java
@@ -0,0 +1,265 @@
+package me.devkevin.landcore.disguise.manager;
+
+import lombok.Getter;
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.nametag.impl.InternalNametag;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.message.CC;
+import net.minecraft.server.v1_8_R3.EntityPlayer;
+import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo;
+import net.minecraft.server.v1_8_R3.PacketPlayOutRespawn;
+import net.minecraft.server.v1_8_R3.WorldSettings;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+import xyz.haoshoku.nick.NickPlugin;
+import xyz.haoshoku.nick.api.NickAPI;
+
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 09/02/2023 @ 18:53
+ * DisguiseManager / me.devkevin.landcore.disguise / LandCore
+ */
+@Getter
+public class DisguiseManager {
+ public static HashMap nickData = new HashMap<>();
+
+ private static final List skinNames = Arrays.asList("_rsu:Killer", "E_Girl:E-girl", "MHF_Sheep:Sheep Man", "BackupDancer:L", "Arro:Arabian", "bennyknight:Badman", "MHF_Herobrine:Herobrine",
+ "MHF_Villager:Villager", "CocoDeMedellin:Black Goku", "SheAGoldDigger:Blue Goku", "MHF_Enderman:Enderman", "Marcel:Marcel", "Zwergoor:Emoji",
+ "HikakinGames:Youtuber", "loudoggydog3010:Juice Wrld", "Reinstallation:Rambo Chicken", "SolluxCaptor:Nezuko", "DevKevin:DevKevin", "Brandy:Brandy",
+ "Grief:Grief", "Nimble:Nimble", "fangirl:fangirl", "Pokemon:Pokemon", "icy:icy", "Magista80:Magista80");
+
+
+ private static final List shortWords = Arrays.asList("About", "Active", "Admit", "Advise", "Again", "After", "Agent", "Alive", "Alone", "Beach", "Basket", "Basic", "Bath", "Battle",
+ "Bean", "Beat", "Bed", "Become", "Begin", "Before", "Beer", "Behind", "Blade", "Black", "Blue", "Bomb", "Brush", "Build", "Bunch", "Button", "Biz", "Busy",
+ "Box", "Boy", "Break", "Best", "Better", "Cake", "Camera", "Campus", "Cap", "Card", "Care", "Case", "Catch", "Center", "Chain", "Chair", "Chara", "Charge",
+ "Chase", "Cheap", "Cheese", "Check", "Close", "Choose", "Christ", "Circle", "Dad", "Dance", "Dark", "Data", "Dead", "Defend", "Desert", "Desk", "Device",
+ "Detect", "Dinner", "Direct", "Dirt", "Dirty", "Doctor", "Down", "Drama", "Draw", "Dream", "Drop", "Earth", "Eat", "Easy", "Editor", "Effect", "Eight",
+ "Elect", "Effort", "Emote", "Enter", "Engine", "Enemy", "Empty", "Entry", "Error", "Enough", "Every", "Exact", "Eye", "Expert", "Face", "Fact", "Fade",
+ "Fail", "Family", "Famous", "Farmer", "Father", "Fight", "Find", "Finger", "Fire", "First", "Fit", "Fix", "Fish", "Field", "Floor", "Focus", "Fly",
+ "Forest", "Force", "Frame", "Uber");
+
+ private static final List longWords = Arrays.asList("Actually", "Aircraft", "Backbone", "Blooming", "Brightly", "Building", "Camellia", "Cardinal", "Careless", "Chemical", "Cheerful",
+ "Civilian", "Daughter", "Demolish", "Detector", "Disaster", "Disposal", "Electron", "Elective", "Engaging", "Enormous", "Erection", "Evidence", "Exertion",
+ "External", "Faithful", "Familiar", "Favorite", "Fearless", "Fixation", "Fragment", "Generous", "Grateful", "Grievous", "Hydrogen", "Horrible", "Ignorant",
+ "Industry", "Majority", "Military", "Mountain", "Mythical", "Normally", "Numerous", "Organism", "Overview", "Pacifist", "Pentagon", "Perilous", "Physical",
+ "Precious", "Prestige", "Puzzling", "Railroad", "Reckless");
+
+ private static final List conjuctions = Arrays.asList("The", "Da", "And", "Of", "By", "Is", "El", "Its", "MC", "GANGMEMBER", "xXx", "_", "__");
+
+ private static final List onlyNames = Arrays.asList("Ibirawyr", "Niniel", "Celahan", "Gwysien", "Figovudd", "Zathiel", "Adwiawyth", "Nydinia", "Laraeb", "Eowendasa", "Grendakin",
+ "Werradia", "Cauth", "Umigolian", "Tardond", "Dwearia", "Yeiwyn", "Adraclya", "Zaev", "Thabeth", "Chuven", "Zaredon", "Bob", "Robert", "Johnny", "Joy",
+ "Matthew", "Michael", "Jacob", "Joshua", "Daniel", "Christopher", "Andrew", "Ethan", "Joseph", "William", "Anthony", "David", "Alexander", "Nicholas",
+ "Ryan", "Tyler", "James", "John", "Jonathan", "Noah", "Brandon", "Christian", "Dylan", "Samuel", "Benjamin", "Nathan", "Zachary", "Logan", "Justin",
+ "Gabriel", "Emily", "Madison", "Emma", "Olivia", "Hannah", "Abigail", "Isabella", "Samantha", "Elizabeth", "Ashley", "Alexis", "Sarah", "Sophia",
+ "Alyssa", "Grace", "Ava", "Taylor", "Brianna", "Lauren", "Chloe", "Natalie", "Kayla", "Jessica", "Anna", "Victoria", "Mia", "Hailey", "Sydney", "Jasmine");
+
+ private static final List japaneseNames = Arrays.asList("Ai", "Aya", "Ayako", "Itsuki", "Eita", "Eiko", "Kanta", "Kaito", "Kenta", "Kento", "Kouki", "Kouta", "Kouya", "Kou",
+ "Keito", "Keita", "Saya", "Sayako", "Sara", "Sizuki", "Sizuko", "Sizuno", "Sizuya", "Suzuka", "Suzuki", "Suzuko", "Sumi", "Seiya", "Souta", "Souya",
+ "Sou", "Taichi", "Takuya", "Tatsuki", "Chitose", "Tutomu", "Tumuya", "Tetsuya", "Tetsuto", "Tekuto", "Touya", "Tomi", "Nami", "Nao", "Neo", "Notomi",
+ "Haruya", "Harumi", "Haruto", "Hitomi", "Hitoshi", "Fuuta", "Fuyuki", "Fuuto", "Mami", "Maya", "Mai", "Masaya", "Masahiro", "Masato", "Misaki", "Mitsuki",
+ "Mutsuki", "Mei", "Yae", "Yuuto", "Yuuta", "Yuuya", "Youta", "Youki");
+
+
+ public static String generate() {
+ Random random = new Random();
+ return generate(NicknamePattern.values()[random.nextInt(NicknamePattern.values().length)]);
+ }
+
+ public static String generateSkin() {
+ Random random = new Random();
+
+ return skinNames.get(random.nextInt(skinNames.size()));
+ }
+
+ public static String generate(NicknamePattern pattern) {
+
+ String disguiseNickname = null;
+
+ if (pattern.equals(NicknamePattern.NameWithNumbers)) {
+ Random random = new Random();
+ String name = onlyNames.get(random.nextInt(onlyNames.size()));
+ if (name.length() <= 10 && chance(50.0)) {
+ disguiseNickname = name + "_" + random.nextInt(9999);
+ } else {
+ disguiseNickname = name + random.nextInt(9999);
+ }
+ }
+
+ if (pattern.equals(NicknamePattern.TwoShortsWithConjunction)) {
+ pattern = NicknamePattern.JapaneseNameWithBirth;
+ }
+
+ if (pattern.equals(NicknamePattern.JapaneseNameWithBirth)) {
+ Random random = new Random();
+ String name = japaneseNames.get(random.nextInt(japaneseNames.size()));
+ String birth = random.nextInt(12) + 1 + String.valueOf(random.nextInt(30) + 1);
+ if (chance(50.0)) {
+ disguiseNickname = name + "_" + birth;
+ } else {
+ disguiseNickname = name + birth;
+ }
+ }
+
+ if (pattern.equals(NicknamePattern.LongWithNumbers)) {
+ Random random = new Random();
+ String name = longWords.get(random.nextInt(longWords.size()));
+ if (chance(50.0)) {
+ disguiseNickname = name + "_" + random.nextInt(9999);
+ } else {
+ disguiseNickname = name + random.nextInt(9999);
+ }
+ }
+
+ if (pattern.equals(NicknamePattern.ShortWithConjunction)) {
+ Random random = new Random();
+ String name = conjuctions.get(random.nextInt(conjuctions.size()));
+ String secondName = shortWords.get(random.nextInt(shortWords.size()));
+ if (chance(50.0)) {
+ disguiseNickname = name + "_" + secondName;
+ } else {
+ disguiseNickname = name + secondName;
+ }
+ }
+
+ if (pattern.equals(NicknamePattern.ShortAndLong)) {
+ Random random = new Random();
+ String name = shortWords.get(random.nextInt(shortWords.size()));
+ String secondName = longWords.get(random.nextInt(longWords.size()));
+ disguiseNickname = name + secondName;
+ }
+
+ if (chance(50.0)) {
+ assert disguiseNickname != null;
+ disguiseNickname = disguiseNickname.toLowerCase();
+ }
+
+ return disguiseNickname;
+ }
+
+ private static boolean chance(double percent) {
+ return Math.random() < percent / 100.0;
+ }
+
+ public void setPlayerDisguise(Player player, String disguiseName, String disguiseSkin) {
+ LandCore.getInstance().getStaffManager().messageStaff(Rank.TRIAL_MOD, CC.GRAY + "[Staff] " +
+ LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId()).getGrant().getRank().getColor() +
+ player.getName() + CC.GRAY + " has disguise as " + CC.PRIMARY + disguiseName
+ );
+
+ NickAPI.nick(player, disguiseName);
+ NickAPI.setGameProfileName(player, disguiseName);
+ NickAPI.setUniqueId(player, disguiseName);
+
+ NickAPI.setSkin(player, disguiseSkin);
+ NickAPI.refreshPlayer(player);
+
+
+ Bukkit.getScheduler().runTask(LandCore.getInstance(), () -> {
+ for (Player player1 : Bukkit.getOnlinePlayers()) {
+ player1.hidePlayer(player);
+ player1.showPlayer(player);
+
+ final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
+
+ entityPlayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityPlayer));
+ entityPlayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, entityPlayer));
+ entityPlayer.playerConnection.sendPacket(new PacketPlayOutRespawn(
+ entityPlayer.getWorld().worldProvider.getDimension(),
+ entityPlayer.getWorld().worldData.getDifficulty(),
+ entityPlayer.getWorld().worldData.getType(),
+ WorldSettings.EnumGamemode.valueOf(entityPlayer.getBukkitEntity().getGameMode().name())
+ ));
+
+ updateTablist();
+ updateCache(player);
+
+ player.setDisplayName(player.getName());
+ player.setPlayerListName(player.getName());
+
+ InternalNametag.reloadPlayer(player);
+ InternalNametag.reloadOthersFor(player);
+
+ NickAPI.refreshPlayer(player);
+ NickAPI.refreshPlayerSync(player);
+ }
+ });
+
+ player.sendMessage(CC.SECONDARY + "You've disguised as " + CC.PRIMARY + disguiseName + CC.GRAY + " (with a random skin)" + CC.SECONDARY + ".");
+ }
+
+ public boolean isNameUsed(String[] args, Player player) {
+ for (Player p : LandCore.getInstance().getServer().getOnlinePlayers()) {
+ if (p.getName().equalsIgnoreCase(args[0])) {
+ player.sendMessage(CC.RED + "That name is already used.");
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // Make it check if the name contains a filtered word in between, before or after the text
+ boolean isFiltered(String[] args, Player player) {
+ List filteredWord = LandCore.getInstance().getConfig().getStringList("FILTERED-WORDS");
+ if (filteredWord.contains(args[0].toLowerCase())) {
+ player.sendMessage(CC.RED + "You can't use that name because it contains a filtered word in it!");
+ return true;
+ }
+
+ return false;
+ }
+
+ public void updateTablist() {
+ final List playerList = new ArrayList<>(net.minecraft.server.v1_8_R3.MinecraftServer.getServer().getPlayerList().players);
+ final List finalList = playerList.stream()
+ .sorted(Comparator.comparingInt(potPlayer -> -(LandCore.getInstance().getProfileManager().getProfile(potPlayer.getUniqueID()).getDisguiseRank() != null ? LandCore.getInstance().getProfileManager().getProfile(potPlayer.getUniqueID()).getDisguiseRank().getWeight() : LandCore.getInstance().getProfileManager().getProfile(potPlayer.getUniqueID()).getGrant().getRank().getWeight())))
+ .collect(Collectors.toList());
+
+ try {
+ final Object list = net.minecraft.server.v1_8_R3.MinecraftServer.getServer().getPlayerList().getClass()
+ .getMethod("playerList", ((Class>[]) null))
+ .invoke(net.minecraft.server.v1_8_R3.MinecraftServer.getServer().getPlayerList());
+ final Class> playerListClass = list.getClass().getSuperclass();
+ final Field declaredField = playerListClass.getDeclaredField("players");
+
+ declaredField.set(list, finalList);
+ } catch (Exception ignored) {
+ }
+ }
+
+ public void updateCache(Player player) {
+ final List playerList = new ArrayList<>(net.minecraft.server.v1_8_R3.MinecraftServer.getServer().getPlayerList().players);
+ final EntityPlayer entityPlayer = playerList.stream()
+ .filter(entityPlayer1 -> entityPlayer1.getUniqueID().equals(player.getUniqueId()))
+ .findFirst().orElse(null);
+
+ playerList.remove(entityPlayer);
+ playerList.add(((CraftPlayer) player).getHandle());
+
+ try {
+ final Object list = net.minecraft.server.v1_8_R3.MinecraftServer.getServer().getPlayerList().getClass()
+ .getMethod("playerList", ((Class>[]) null))
+ .invoke(net.minecraft.server.v1_8_R3.MinecraftServer.getServer().getPlayerList());
+ final Class> playerListClass = list.getClass().getSuperclass();
+ final Field declaredField = playerListClass.getDeclaredField("players");
+
+ declaredField.set(list, playerList);
+ } catch (Exception ignored) {
+ }
+ }
+
+ public enum NicknamePattern {
+ ShortAndLong,
+ NameWithNumbers,
+ LongWithNumbers,
+ ShortWithConjunction,
+ JapaneseNameWithBirth,
+ TwoShortsWithConjunction
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/disguise/menu/DisguiseMenu.java b/LandCore/src/main/java/me/devkevin/landcore/disguise/menu/DisguiseMenu.java
new file mode 100644
index 0000000..49172d5
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/disguise/menu/DisguiseMenu.java
@@ -0,0 +1,252 @@
+package me.devkevin.landcore.disguise.menu;
+
+import lombok.Getter;
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.nametag.impl.InternalNametag;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.rank.Rank;
+import me.devkevin.landcore.utils.inventory.InventoryUI;
+import me.devkevin.landcore.utils.item.ItemBuilder;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.Bukkit;
+import org.bukkit.Color;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import xyz.haoshoku.nick.api.NickAPI;
+
+import java.util.Arrays;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 09/02/2023 @ 19:00
+ * DisguiseMenu / me.devkevin.landcore.disguise / LandCore
+ */
+@Getter
+public class DisguiseMenu {
+ private final InventoryUI rankMenu = new InventoryUI(CC.GRAY + "Pick a Rank -> (Disguise)", 1);
+
+ public DisguiseMenu() {
+ setup();
+ }
+
+ private void setup() {
+ this.rankMenu.setItem(0, new InventoryUI.AbstractClickableItem(
+ new ItemBuilder(Material.LEATHER_CHESTPLATE).color(Color.BLUE)
+ .name(CC.BLUE + "✦" + CC.GREEN + "Basic")
+ .lore(Arrays.asList(
+ "",
+ CC.GRAY + CC.B + "In disguise mode",
+ CC.GRAY + CC.B + "you can only choose",
+ CC.GRAY + CC.B + "donor ranks or member.",
+ ""
+ ))
+ .build()) {
+ @Override
+ public void onClick(InventoryClickEvent event) {
+ Player player = (Player)event.getWhoClicked();
+
+ CoreProfile coreProfile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ coreProfile.setDisguiseRank(Rank.BASIC);
+ player.sendMessage(CC.GREEN + "You has choose " + CC.BLUE + "✦" + CC.GREEN + "Basic" + CC.GREEN + " rank.");
+
+ player.closeInventory();
+
+ Bukkit.getScheduler().runTask(LandCore.getInstance(), () -> {
+ for (Player player1 : Bukkit.getOnlinePlayers()) {
+ player1.hidePlayer(player);
+ player1.showPlayer(player);
+
+ LandCore.getInstance().getDisguiseManager().updateTablist();
+
+ InternalNametag.reloadPlayer(player);
+ InternalNametag.reloadOthersFor(player);
+ }
+ });
+ }
+ });
+
+ this.rankMenu.setItem(1, new InventoryUI.AbstractClickableItem(
+ new ItemBuilder(Material.LEATHER_CHESTPLATE).color(Color.YELLOW)
+ .name(CC.YELLOW + "✯" + CC.GOLD + "Gold")
+ .lore(Arrays.asList(
+ "",
+ CC.GRAY + CC.B + "In disguise mode",
+ CC.GRAY + CC.B + "you can only choose",
+ CC.GRAY + CC.B + "donor ranks or member.",
+ ""
+ ))
+ .build()) {
+ @Override
+ public void onClick(InventoryClickEvent event) {
+ Player player = (Player)event.getWhoClicked();
+
+ CoreProfile coreProfile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ coreProfile.setDisguiseRank(Rank.GOLD);
+ player.sendMessage(CC.GREEN + "You has choose " + CC.YELLOW + "✯" + CC.GOLD + "Gold" + CC.GREEN + " rank.");
+
+ player.closeInventory();
+
+ Bukkit.getScheduler().runTask(LandCore.getInstance(), () -> {
+ for (Player player1 : Bukkit.getOnlinePlayers()) {
+ player1.hidePlayer(player);
+ player1.showPlayer(player);
+
+ LandCore.getInstance().getDisguiseManager().updateTablist();
+
+ InternalNametag.reloadPlayer(player);
+ InternalNametag.reloadOthersFor(player);
+ }
+ });
+ }
+ });
+
+ this.rankMenu.setItem(2, new InventoryUI.AbstractClickableItem(
+ new ItemBuilder(Material.LEATHER_CHESTPLATE).color(Color.LIME)
+ .name(CC.GREEN + "✵" + CC.DARK_GREEN + "Emerald")
+ .lore(Arrays.asList(
+ "",
+ CC.GRAY + CC.B + "In disguise mode",
+ CC.GRAY + CC.B + "you can only choose",
+ CC.GRAY + CC.B + "donor ranks or member.",
+ ""
+ ))
+ .build()) {
+ @Override
+ public void onClick(InventoryClickEvent event) {
+ Player player = (Player)event.getWhoClicked();
+
+ CoreProfile coreProfile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ coreProfile.setDisguiseRank(Rank.EMERALD);
+ player.sendMessage(CC.GREEN + "You has choose " + CC.GREEN + "✵" + CC.DARK_GREEN + "Emerald" + CC.GREEN + " rank.");
+
+ player.closeInventory();
+
+ Bukkit.getScheduler().runTask(LandCore.getInstance(), () -> {
+ for (Player player1 : Bukkit.getOnlinePlayers()) {
+ player1.hidePlayer(player);
+ player1.showPlayer(player);
+
+ LandCore.getInstance().getDisguiseManager().updateTablist();
+
+ InternalNametag.reloadPlayer(player);
+ InternalNametag.reloadOthersFor(player);
+ }
+ });
+ }
+ });
+
+ this.rankMenu.setItem(3, new InventoryUI.AbstractClickableItem(
+ new ItemBuilder(Material.LEATHER_CHESTPLATE).color(Color.AQUA)
+ .name(CC.AQUA + "❇" + CC.D_AQUA + "Diamond")
+ .lore(Arrays.asList(
+ "",
+ CC.GRAY + CC.B + "In disguise mode",
+ CC.GRAY + CC.B + "you can only choose",
+ CC.GRAY + CC.B + "donor ranks or member.",
+ ""
+ ))
+ .build()) {
+ @Override
+ public void onClick(InventoryClickEvent event) {
+ Player player = (Player)event.getWhoClicked();
+
+ CoreProfile coreProfile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ coreProfile.setDisguiseRank(Rank.DIAMOND);
+ player.sendMessage(CC.GREEN + "You has choose " + CC.AQUA + "❇" + CC.D_AQUA + "Diamond" + CC.GREEN + " rank.");
+
+ player.closeInventory();
+
+ Bukkit.getScheduler().runTask(LandCore.getInstance(), () -> {
+ for (Player player1 : Bukkit.getOnlinePlayers()) {
+ player1.hidePlayer(player);
+ player1.showPlayer(player);
+
+ LandCore.getInstance().getDisguiseManager().updateTablist();
+
+ InternalNametag.reloadPlayer(player);
+ InternalNametag.reloadOthersFor(player);
+ }
+ });
+ }
+ });
+
+ this.rankMenu.setItem(4, new InventoryUI.AbstractClickableItem(
+ new ItemBuilder(Material.LEATHER_CHESTPLATE).color(Color.ORANGE)
+ .name(CC.GOLD + "❊" + CC.YELLOW + "LOL")
+ .lore(Arrays.asList(
+ "",
+ CC.GRAY + CC.B + "In disguise mode",
+ CC.GRAY + CC.B + "you can only choose",
+ CC.GRAY + CC.B + "donor ranks or member.",
+ ""
+ ))
+ .build()) {
+ @Override
+ public void onClick(InventoryClickEvent event) {
+ Player player = (Player)event.getWhoClicked();
+
+ CoreProfile coreProfile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ coreProfile.setDisguiseRank(Rank.LOL);
+ player.sendMessage(CC.GREEN + "You has choose " + CC.GOLD + "❊" + CC.YELLOW + "LOL" + CC.GREEN + " rank.");
+
+ player.closeInventory();
+
+ Bukkit.getScheduler().runTask(LandCore.getInstance(), () -> {
+ for (Player player1 : Bukkit.getOnlinePlayers()) {
+ player1.hidePlayer(player);
+ player1.showPlayer(player);
+
+ LandCore.getInstance().getDisguiseManager().updateTablist();
+
+ InternalNametag.reloadPlayer(player);
+ InternalNametag.reloadOthersFor(player);
+ }
+ });
+ }
+ });
+
+ this.rankMenu.setItem(8, new InventoryUI.AbstractClickableItem(
+ new ItemBuilder(Material.LEATHER_CHESTPLATE).color(Color.GREEN)
+ .name(CC.GREEN + "Member")
+ .lore(Arrays.asList(
+ "",
+ CC.GRAY + CC.B + "In disguise mode",
+ CC.GRAY + CC.B + "you can only choose",
+ CC.GRAY + CC.B + "donor ranks or member.",
+ ""
+ ))
+ .build()) {
+ @Override
+ public void onClick(InventoryClickEvent event) {
+ Player player = (Player)event.getWhoClicked();
+
+ CoreProfile coreProfile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ coreProfile.setDisguiseRank(Rank.MEMBER);
+ player.sendMessage(CC.GREEN + "You has choose " + CC.GREEN + "Member" + CC.GREEN + " rank.");
+
+ player.closeInventory();
+
+ Bukkit.getScheduler().runTask(LandCore.getInstance(), () -> {
+ for (Player player1 : Bukkit.getOnlinePlayers()) {
+ player1.hidePlayer(player);
+ player1.showPlayer(player);
+
+ LandCore.getInstance().getDisguiseManager().updateTablist();
+
+ InternalNametag.reloadPlayer(player);
+ InternalNametag.reloadOthersFor(player);
+
+ NickAPI.refreshPlayerSync(player);
+ }
+ });
+ }
+ });
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/BanEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/BanEvent.java
new file mode 100644
index 0000000..aed9dd9
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/BanEvent.java
@@ -0,0 +1,39 @@
+package me.devkevin.landcore.event;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+import java.util.UUID;
+
+@RequiredArgsConstructor
+@Getter
+public class BanEvent extends Event implements Cancellable {
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final CommandSender punisher;
+ private final UUID punishedId;
+ private boolean cancelled;
+
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/BaseEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/BaseEvent.java
new file mode 100644
index 0000000..a9cbbad
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/BaseEvent.java
@@ -0,0 +1,31 @@
+package me.devkevin.landcore.event;
+
+import me.devkevin.landcore.LandCore;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 16/01/2023 @ 12:36
+ * BaseEvent / land.pvp.core.event / LandCore
+ */
+public class BaseEvent extends Event {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public boolean call() {
+ LandCore.getInstance().getServer().getPluginManager().callEvent(this);
+ return this instanceof Cancellable && ((Cancellable) this).isCancelled();
+ }
+
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/CoreEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/CoreEvent.java
new file mode 100644
index 0000000..feae9ff
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/CoreEvent.java
@@ -0,0 +1,24 @@
+package me.devkevin.landcore.event;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/01/2023 @ 18:31
+ * CoreEvent / me.devkevin.landcore.event / LandCore
+ */
+public class CoreEvent extends Event {
+
+ private static HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+}
+
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/CoreProfileEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/CoreProfileEvent.java
new file mode 100644
index 0000000..e342927
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/CoreProfileEvent.java
@@ -0,0 +1,22 @@
+package me.devkevin.landcore.event;
+
+import me.devkevin.landcore.player.CoreProfile;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.UUID;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 16/01/2023 @ 12:34
+ * CoreProfileEvent / land.pvp.core.event / LandCore
+ */
+@Getter
+@RequiredArgsConstructor
+public class CoreProfileEvent extends BaseEvent {
+ private final CoreProfile profile;
+
+ public UUID getUniqueId() {
+ return this.profile.getId();
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/PlayerFakeEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/PlayerFakeEvent.java
new file mode 100644
index 0000000..b36e1db
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/PlayerFakeEvent.java
@@ -0,0 +1,28 @@
+package me.devkevin.landcore.event;
+
+import lombok.Getter;
+import org.bukkit.entity.Player;
+
+import java.util.UUID;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 18/01/2023 @ 15:14
+ * PlayerFakeEvent / land.pvp.core.event / LandCore
+ */
+@Getter
+public class PlayerFakeEvent extends BaseEvent {
+ private Player player;
+
+ public PlayerFakeEvent(Player player) {
+ this.player = player;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ public UUID getUniqueId() {
+ return player.getUniqueId();
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/disguise/PreDisguiseEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/disguise/PreDisguiseEvent.java
new file mode 100644
index 0000000..4ad5ed9
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/disguise/PreDisguiseEvent.java
@@ -0,0 +1,44 @@
+package me.devkevin.landcore.event.disguise;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 19/01/2023 @ 17:19
+ * PreDisguiseEvent / land.pvp.core.event.disguise / LandCore
+ */
+@Getter
+@RequiredArgsConstructor
+public class PreDisguiseEvent extends Event implements Cancellable {
+
+ private static final HandlerList HANDLERS = new HandlerList();
+
+ private final Player player;
+
+ private boolean cancelled;
+
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLERS;
+ }
+
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return this.cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean b) {
+ this.cancelled = b;
+ }
+}
+
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/disguise/UnDisguiseEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/disguise/UnDisguiseEvent.java
new file mode 100644
index 0000000..0b26573
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/disguise/UnDisguiseEvent.java
@@ -0,0 +1,30 @@
+package me.devkevin.landcore.event.disguise;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 19/01/2023 @ 17:20
+ * UnDisguiseEvent / land.pvp.core.event.disguise / LandCore
+ */
+@Getter
+@RequiredArgsConstructor
+public class UnDisguiseEvent extends Event {
+
+ private static final HandlerList HANDLERS = new HandlerList();
+
+ private final Player player;
+
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLERS;
+ }
+
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/player/PlayerFreezeEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/player/PlayerFreezeEvent.java
new file mode 100644
index 0000000..471020f
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/player/PlayerFreezeEvent.java
@@ -0,0 +1,28 @@
+package me.devkevin.landcore.event.player;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import me.devkevin.landcore.event.CoreEvent;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/01/2023 @ 18:27
+ * PlayerFreezeEvent / me.devkevin.landcore.event.player / LandCore
+ */
+@Getter
+@Setter
+public class PlayerFreezeEvent extends PlayerEvent {
+
+ public PlayerFreezeEvent(Player who) {
+ super(who);
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return null;
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/player/PlayerMessageEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/player/PlayerMessageEvent.java
new file mode 100644
index 0000000..945f399
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/player/PlayerMessageEvent.java
@@ -0,0 +1,28 @@
+package me.devkevin.landcore.event.player;
+
+import lombok.Getter;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+
+@Getter
+public class PlayerMessageEvent extends PlayerEvent {
+ private static final HandlerList HANDLERS = new HandlerList();
+ private final Player receiver;
+ private final String message;
+
+ public PlayerMessageEvent(Player sender, Player receiver, String message) {
+ super(sender);
+ this.receiver = receiver;
+ this.message = message;
+ }
+
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLERS;
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/player/PlayerRankChangeEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/player/PlayerRankChangeEvent.java
new file mode 100644
index 0000000..32b6be6
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/player/PlayerRankChangeEvent.java
@@ -0,0 +1,32 @@
+package me.devkevin.landcore.event.player;
+
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.player.grant.Grant;
+import lombok.Getter;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+
+@Getter
+public class PlayerRankChangeEvent extends PlayerEvent {
+ private static final HandlerList HANDLERS = new HandlerList();
+ private final CoreProfile profile;
+ private final Grant newRank;
+ private final long duration;
+
+ public PlayerRankChangeEvent(Player who, CoreProfile profile, Grant newRank, long duration) {
+ super(who);
+ this.profile = profile;
+ this.newRank = newRank;
+ this.duration = duration;
+ }
+
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLERS;
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/server/ServerShutdownCancelEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/server/ServerShutdownCancelEvent.java
new file mode 100644
index 0000000..218cf82
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/server/ServerShutdownCancelEvent.java
@@ -0,0 +1,17 @@
+package me.devkevin.landcore.event.server;
+
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.server.ServerEvent;
+
+public class ServerShutdownCancelEvent extends ServerEvent {
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/event/server/ServerShutdownScheduleEvent.java b/LandCore/src/main/java/me/devkevin/landcore/event/server/ServerShutdownScheduleEvent.java
new file mode 100644
index 0000000..f79a8fe
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/event/server/ServerShutdownScheduleEvent.java
@@ -0,0 +1,17 @@
+package me.devkevin.landcore.event.server;
+
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.server.ServerEvent;
+
+public class ServerShutdownScheduleEvent extends ServerEvent {
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/Faction.java b/LandCore/src/main/java/me/devkevin/landcore/faction/Faction.java
new file mode 100644
index 0000000..0a6060b
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/Faction.java
@@ -0,0 +1,49 @@
+package me.devkevin.landcore.faction;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 0:38
+ * Faction / me.devkevin.landcore.faction / LandCore
+ */
+@Getter
+@Setter
+@RequiredArgsConstructor
+public class Faction {
+ private final String name;
+ private final UUID leader;
+
+ private int limit = 12;
+
+ private List members = new ArrayList<>();
+ private List captains = new ArrayList<>();
+
+ private String description;
+ private String password;
+ private String dateCreated;
+ private int elo = 1000;
+ private int wins;
+ private int losses;
+ private int winStreak;
+
+ private boolean factionChat;
+
+ public void broadcast(String message) {
+ members.forEach(users -> {
+ Player player = (Player) Bukkit.getOfflinePlayer(users);
+
+ if (player != null) {
+ player.sendMessage(message);
+ }
+ });
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/FactionHelpCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/FactionHelpCommand.java
new file mode 100644
index 0000000..66a4ef7
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/FactionHelpCommand.java
@@ -0,0 +1,51 @@
+package me.devkevin.landcore.faction.commands;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 2:11
+ * FactionHelpCommand / me.devkevin.landcore.faction.commands / LandCore
+ */
+public class FactionHelpCommand extends PlayerCommand {
+
+ public FactionHelpCommand(LandCore plugin) {
+ super("faction");
+ setAliases(Arrays.asList("f", "f help", "faction help"));
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ player.sendMessage(new String[] {
+ CC.GRAY + CC.BOARD_SEPARATOR,
+ CC.GOLD + CC.B + "Factions Help " + CC.GRAY + "-" + CC.GRAY + " Information on how to use faction commands",
+ CC.GRAY + CC.BOARD_SEPARATOR,
+ CC.GOLD + "General Commands:",
+ CC.YELLOW + "/faction create " + CC.GRAY + "- Create a new faction",
+ CC.YELLOW + "/faction leave " + CC.GRAY + "- Leave your current faction",
+ CC.YELLOW + "/faction accept [faction|player] " + CC.GRAY + "- Accept clan invitation",
+ CC.YELLOW + "/faction info [faction|player] " + CC.GRAY + "- View a clan's information",
+ "",
+ CC.GOLD + "Leader Commands:",
+ CC.YELLOW + "/faction disband " + CC.GRAY + "- Disband your faction",
+ CC.YELLOW + "/faction description " + CC.GRAY + "- Set your faction's description",
+ CC.YELLOW + "/faction password " + CC.GRAY + "- Sets faction password",
+ CC.YELLOW + "/faction promote " + CC.GRAY + "- Promote a player",
+ CC.YELLOW + "/faction demote " + CC.GRAY + "- Demote a player",
+ "",
+ CC.GOLD + "Captain Commands:",
+ CC.YELLOW + "/faction invite " + CC.GRAY + "- Invite a player to join your faction",
+ CC.YELLOW + "/faction kick " + CC.GRAY + "- Kick a player from your faction",
+ "",
+ CC.GOLD + "Other Help:",
+ CC.YELLOW + "To use " + CC.PINK + "faction chat" + CC.YELLOW + " /factionchat or /fc",
+ CC.YELLOW + "Factions are limited to " + CC.PINK + "12 members" + CC.YELLOW + ".",
+ CC.GRAY + CC.BOARD_SEPARATOR
+ });
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionDemoteCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionDemoteCommand.java
new file mode 100644
index 0000000..c5e2404
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionDemoteCommand.java
@@ -0,0 +1,66 @@
+package me.devkevin.landcore.faction.commands.captain;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 13:50
+ * FactionDemoteCommand / me.devkevin.landcore.faction.commands.captain / LandCore
+ */
+public class FactionDemoteCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionDemoteCommand(LandCore plugin) {
+ super("faction.demote");
+ this.plugin = plugin;
+ setAliases("f.demote");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length != 1) {
+ player.sendMessage(CC.RED + "Usage: /faction demote ");
+ return;
+ }
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile.getFaction() == null) {
+ player.sendMessage(CC.RED + "You are not in a faction!");
+ return;
+ }
+
+ Faction faction = factionProfile.getFaction();
+
+ if (!faction.getLeader().equals(player.getUniqueId())) {
+ player.sendMessage(CC.RED + "You are not the faction leader!");
+ return;
+ }
+
+ OfflinePlayer offlinePlayer = this.plugin.getServer().getOfflinePlayer(args[0]);
+
+ if (offlinePlayer.getPlayer() != null && offlinePlayer.getPlayer() == player) {
+ player.sendMessage(CC.RED + "You may not demote yourself!");
+ return;
+ }
+
+ if (!faction.getMembers().contains(offlinePlayer.getUniqueId())) {
+ player.sendMessage(player.getName() + CC.RED + " is not in your faction!");
+ return;
+ }
+
+ if (!faction.getCaptains().contains(offlinePlayer.getUniqueId())) {
+ player.sendMessage(player.getName() + CC.RED + " is not a faction captain!");
+ return;
+ }
+
+ faction.getCaptains().remove(offlinePlayer.getUniqueId());
+ faction.broadcast(player.getName() + CC.YELLOW + " has been demoted to faction member!");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionInviteCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionInviteCommand.java
new file mode 100644
index 0000000..0128ebb
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionInviteCommand.java
@@ -0,0 +1,94 @@
+package me.devkevin.landcore.faction.commands.captain;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.invite.FactionInvite;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+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 net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 13:53
+ * FactionInviteCommand / me.devkevin.landcore.faction.commands.captain / LandCore
+ */
+public class FactionInviteCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionInviteCommand(LandCore plugin) {
+ super("faction.invite");
+ this.plugin = plugin;
+ setAliases("f.invite");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length != 1) {
+ player.sendMessage(CC.RED + "Usage: /faction invite ");
+ return;
+ }
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+ if (factionProfile.getFaction() == null) {
+ player.sendMessage(CC.RED + "You are not in a faction!");
+ return;
+ }
+
+ Faction faction = factionProfile.getFaction();
+
+ if (faction.getMembers().size() >= faction.getLimit()) {
+ player.sendMessage(CC.RED + "Your faction has exceeded the max member limit, you are unable to invite no one currently!");
+ return;
+ }
+
+ if (!faction.getCaptains().contains(player.getUniqueId()) && !faction.getLeader().equals(player.getUniqueId())) {
+ player.sendMessage(CC.RED + "You are not a faction captain!");
+ return;
+ }
+
+ Player target = this.plugin.getServer().getPlayer(args[0]);
+ if (target == null) {
+ player.sendMessage(CC.RED + "Could not find player.");
+ return;
+ }
+
+ if (target == player) {
+ player.sendMessage(CC.RED + "Yoy may not invite yourself to a faction!");
+ return;
+ }
+
+ if (faction.getMembers().contains(target.getUniqueId())) {
+ player.sendMessage(target.getDisplayName() + CC.RED + " is already in your faction!");
+ return;
+ }
+
+ FactionProfile targetProfile = this.plugin.getFactionManager().getProfile(target);
+ if (targetProfile.getFaction() != null) {
+ player.sendMessage(target.getDisplayName() + CC.RED + " already belongs to a faction. They must first leave their faction to be able to receive invites.");
+ return;
+ }
+
+ FactionInvite factionInvite = targetProfile.getInviteList().stream().filter(ci -> ci.getFaction() == faction && System.currentTimeMillis() - ci.getTimestamp() <= 60000).findFirst().orElse(null);
+ if (factionInvite != null) {
+ player.sendMessage(target.getDisplayName() + CC.RED + " has already been invited to the faction within the last 60 seconds.");
+ return;
+ }
+ targetProfile.getInviteList().add(new FactionInvite(faction));
+ faction.broadcast(target.getDisplayName() + CC.YELLOW + " has been invited to the faction.");
+
+ TextComponent textComponent = new TextComponent(CC.YELLOW + "Click ");
+ TextComponent clickable = new TextComponent(CC.GOLD + "here");
+ textComponent.addExtra(clickable);
+ textComponent.addExtra(CC.YELLOW + " to accept the invite");
+ clickable.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(CC.GREEN + "Click to join " + target.getDisplayName() + CC.GREEN + "'s faction").create()));
+ clickable.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/faction join " + player.getName()));
+
+ target.sendMessage(player.getDisplayName() + CC.YELLOW + " has invited you to join their faction " + CC.GRAY + "'" + CC.DARK_GREEN + faction.getName() + CC.GRAY + "'");
+ target.spigot().sendMessage(textComponent);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionKickCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionKickCommand.java
new file mode 100644
index 0000000..3a74155
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionKickCommand.java
@@ -0,0 +1,74 @@
+package me.devkevin.landcore.faction.commands.captain;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 13:59
+ * FactionKickCommand / me.devkevin.landcore.faction.commands.captain / LandCore
+ */
+public class FactionKickCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionKickCommand(LandCore plugin) {
+ super("faction.kick");
+ this.plugin = plugin;
+ setAliases("f.kick");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length != 1) {
+ player.sendMessage(CC.RED + "Usage: /faction kick ");
+ return;
+ }
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+ if (factionProfile.getFaction() == null) {
+ player.sendMessage(CC.RED + "You are not in a faction!");
+ return;
+ }
+
+ Faction faction = factionProfile.getFaction();
+ if (!faction.getCaptains().contains(player.getUniqueId()) && !faction.getLeader().equals(player.getUniqueId())) {
+ player.sendMessage(CC.RED + "You are not a faction captain!");
+ return;
+ }
+
+ OfflinePlayer offlinePlayer = this.plugin.getServer().getOfflinePlayer(args[0]);
+ if (offlinePlayer.getPlayer() != null && offlinePlayer.getPlayer() == player) {
+ player.sendMessage(CC.RED + "You may not kick yourself from the faction!");
+ return;
+ }
+
+ if (!faction.getMembers().contains(offlinePlayer.getUniqueId())) {
+ player.sendMessage(player.getName() + CC.RED + " is not in your faction!");
+ return;
+ }
+
+ if ((faction.getCaptains().contains(offlinePlayer.getUniqueId()) && !faction.getLeader().equals(player.getUniqueId())) || faction.getLeader() == offlinePlayer.getUniqueId()) {
+ player.sendMessage(CC.RED + "You may only kick faction members.");
+ return;
+ }
+
+ faction.getMembers().remove(offlinePlayer.getUniqueId());
+ faction.getCaptains().remove(offlinePlayer.getUniqueId());
+
+ if (offlinePlayer.getPlayer() != null && offlinePlayer.getPlayer().isOnline()) {
+ Player target = offlinePlayer.getPlayer();
+
+ FactionProfile targetProfile = this.plugin.getFactionManager().getProfile(target);
+ targetProfile.setFaction(null);
+
+ target.sendMessage(CC.RED + CC.B + "You have been kicked from the faction!");
+ }
+
+ faction.broadcast(player.getName() + CC.YELLOW + " has been kicked from the faction!");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionPasswordCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionPasswordCommand.java
new file mode 100644
index 0000000..5f8079e
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionPasswordCommand.java
@@ -0,0 +1,48 @@
+package me.devkevin.landcore.faction.commands.captain;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 14:02
+ * FactionPasswordCommand / me.devkevin.landcore.faction.commands.captain / LandCore
+ */
+public class FactionPasswordCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionPasswordCommand(LandCore plugin) {
+ super("faction.password");
+ this.plugin = plugin;
+ setAliases("f.password");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length != 1) {
+ player.sendMessage(CC.RED + "Usage: /faction password ");
+ return;
+ }
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+ if (factionProfile.getFaction() == null) {
+ player.sendMessage(CC.RED + "You are not in a faction!");
+ return;
+ }
+
+ Faction faction = factionProfile.getFaction();
+ if (!faction.getLeader().equals(player.getUniqueId())) {
+ player.sendMessage(CC.RED + "You are not the faction leader!");
+ return;
+ }
+
+ String password = args[0];
+ faction.setPassword(password);
+
+ player.sendMessage(CC.YELLOW + "Your faction password is now " + CC.GRAY + "'" + CC.DARK_GREEN + password + CC.GRAY + "'" + CC.YELLOW + ".");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionPromoteCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionPromoteCommand.java
new file mode 100644
index 0000000..7065525
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/captain/FactionPromoteCommand.java
@@ -0,0 +1,65 @@
+package me.devkevin.landcore.faction.commands.captain;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 14:04
+ * FactionPromoteCommand / me.devkevin.landcore.faction.commands.captain / LandCore
+ */
+public class FactionPromoteCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionPromoteCommand(LandCore plugin) {
+ super("faction.promote");
+ this.plugin = plugin;
+ setAliases("f.promote");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length != 1) {
+ player.sendMessage(CC.RED + "Usage: /faction promote ");
+ return;
+ }
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+ if (factionProfile.getFaction() == null) {
+ player.sendMessage(CC.RED + "You are not in a faction!");
+ return;
+ }
+
+ Faction faction = factionProfile.getFaction();
+
+ if (!faction.getLeader().equals(player.getUniqueId())) {
+ player.sendMessage(CC.RED + "You are not the faction leader!");
+ return;
+ }
+
+ OfflinePlayer offlinePlayer = this.plugin.getServer().getOfflinePlayer(args[0]);
+
+ if (offlinePlayer.getPlayer() != null && offlinePlayer.getPlayer() == player) {
+ player.sendMessage(CC.RED + "You may not promote yourself!");
+ return;
+ }
+
+ if (!faction.getMembers().contains(offlinePlayer.getUniqueId())) {
+ player.sendMessage(player.getName() + CC.RED + " is not in your faction!");
+ return;
+ }
+
+ if (faction.getCaptains().contains(offlinePlayer.getUniqueId())) {
+ player.sendMessage(player.getName() + CC.RED + " is already a faction captain!");
+ return;
+ }
+
+ faction.getCaptains().add(offlinePlayer.getUniqueId());
+ faction.broadcast(player.getName() + CC.YELLOW + " has been promoted to faction captain!");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/leader/FactionDescriptionCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/leader/FactionDescriptionCommand.java
new file mode 100644
index 0000000..0818b45
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/leader/FactionDescriptionCommand.java
@@ -0,0 +1,50 @@
+package me.devkevin.landcore.faction.commands.leader;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.StringUtil;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 13:38
+ * FactionDescriptionCommand / me.devkevin.landcore.faction.commands.leader / LandCore
+ */
+public class FactionDescriptionCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionDescriptionCommand(LandCore plugin) {
+ super("faction.description");
+ this.plugin = plugin;
+ setAliases("f.description");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length < 1) {
+ player.sendMessage(CC.RED + "Usage: /faction description ");
+ return;
+ }
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile.getFaction() == null) {
+ player.sendMessage(CC.RED + "You are not in a faction!");
+ return;
+ }
+
+ Faction faction = factionProfile.getFaction();
+
+ if (faction.getLeader() != player.getUniqueId()) {
+ player.sendMessage(CC.RED + "You are not the faction leader!");
+ return;
+ }
+
+ String description = StringUtil.buildString(args, 0);
+ faction.setDescription(description);
+ faction.broadcast(player.getDisplayName() + CC.YELLOW + " has set the faction's description to " + CC.GRAY + "'" + CC.DARK_GREEN + description + CC.GRAY + "'" + CC.YELLOW + ".");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/leader/FactionDisbandCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/leader/FactionDisbandCommand.java
new file mode 100644
index 0000000..327612e
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/leader/FactionDisbandCommand.java
@@ -0,0 +1,57 @@
+package me.devkevin.landcore.faction.commands.leader;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 13:46
+ * FactionDisbandCommand / me.devkevin.landcore.faction.commands.leader / LandCore
+ */
+public class FactionDisbandCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionDisbandCommand(LandCore plugin) {
+ super("faction.disband");
+ this.plugin = plugin;
+ setAliases("f.disband");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile.getFaction() == null) {
+ player.sendMessage(CC.RED + "You are not in a faction!");
+ return;
+ }
+
+ Faction faction = factionProfile.getFaction();
+
+ if (!faction.getLeader().equals(player.getUniqueId())) {
+ player.sendMessage(CC.RED + "You are not the faction leader!");
+ return;
+ }
+
+ player.sendMessage(CC.RED + CC.B + "You have successfully disbanded your faction!");
+
+ faction.getMembers().remove(player.getUniqueId());
+ factionProfile.setFaction(null);
+ faction.broadcast(CC.RED + CC.B + "Your faction has been disbanded.");
+
+ faction.getMembers().forEach(u -> {
+ Player member = this.plugin.getServer().getPlayer(u);
+
+ if (member != null) {
+ FactionProfile memberProfile = this.plugin.getFactionManager().getProfile(member);
+ memberProfile.setFaction(null);
+ }
+ });
+
+ this.plugin.getFactionManager().getFactions().remove(faction);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionAcceptCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionAcceptCommand.java
new file mode 100644
index 0000000..693ad80
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionAcceptCommand.java
@@ -0,0 +1,83 @@
+package me.devkevin.landcore.faction.commands.player;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.invite.FactionInvite;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 2:17
+ * FactionAcceptCommand / me.devkevin.landcore.faction.commands.player / LandCore
+ */
+public class FactionAcceptCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionAcceptCommand(LandCore plugin) {
+ super("faction.accept");
+ this.plugin = plugin;
+ setAliases(Arrays.asList("f.accept", "faction.join", "f.join"));
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length < 1) {
+ player.sendMessage(CC.RED + "Usage: /faction ");
+ return;
+ }
+
+ String name = args[0];
+ FactionInvite factionInvite = getInvite(player, name);
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile.getFaction() != null) {
+ player.sendMessage(CC.RED + "You are already in a faction!");
+ return;
+ }
+
+ if (factionInvite == null && (getFaction(name) == null || getFaction(name).getPassword() == null)) {
+ player.sendMessage(CC.RED + "You weren't invited to a faction with this name or a faction with a member with this name.");
+ return;
+ }
+
+ if (factionInvite == null && getFaction(name).getPassword() != null && args.length < 2) {
+ player.sendMessage(CC.RED + "You need the password or an invitation to join this faction.");
+ player.sendMessage(CC.YELLOW + "To join with a password, use " + CC.PINK + "/faction join " + name + " ");
+ return;
+ }
+
+ Faction faction = getFaction(name);
+
+ if (faction.getPassword() != null && args.length >= 2 && factionInvite == null) {
+ String password = args[1];
+
+ if (!faction.getPassword().equalsIgnoreCase(password)) {
+ player.sendMessage(CC.RED + "The password you have entered is incorrect.");
+ return;
+ }
+ }
+
+ factionProfile.setFaction(faction);
+ faction.getMembers().add(player.getUniqueId());
+
+ if (factionInvite != null) factionProfile.getInviteList().remove(factionInvite);
+
+ faction.broadcast(player.getDisplayName() + CC.YELLOW + " has joined the faction!");
+ }
+
+ private FactionInvite getInvite(Player player, String name) {
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ return factionProfile.getInviteList().stream().filter(ci -> ci.getFaction() == getFaction(name) && System.currentTimeMillis() - ci.getTimestamp() <= 60000 && !ci.isCancelled()).findFirst().orElse(null);
+ }
+
+ private Faction getFaction(String name) {
+ return this.plugin.getFactionManager().getFactions().stream().filter(c -> c.getName().equalsIgnoreCase(name) || c.getMembers().contains(this.plugin.getServer().getOfflinePlayer(name).getUniqueId())).findFirst().orElse(null);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionChatCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionChatCommand.java
new file mode 100644
index 0000000..6528faa
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionChatCommand.java
@@ -0,0 +1,33 @@
+package me.devkevin.landcore.faction.commands.player;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 22/03/2023 @ 12:42
+ * FactionChatCommand / me.devkevin.landcore.faction.commands.player / LandCore
+ */
+public class FactionChatCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionChatCommand(LandCore plugin) {
+ super("factionchat");
+ this.plugin = plugin;
+ setAliases("fc");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ boolean inFactionChat = !factionProfile.getFaction().isFactionChat();
+
+ factionProfile.getFaction().setFactionChat(inFactionChat);
+
+ player.sendMessage(inFactionChat ? CC.GREEN + "You are now in faction chat." : CC.RED + "You are no longer in faction chat.");
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionCreateCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionCreateCommand.java
new file mode 100644
index 0000000..9bbe4aa
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionCreateCommand.java
@@ -0,0 +1,77 @@
+package me.devkevin.landcore.faction.commands.player;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.LandCoreAPI;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.TaskUtil;
+import me.devkevin.landcore.utils.message.CC;
+import org.apache.commons.lang.StringUtils;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 2:28
+ * FactionCreateCommand / me.devkevin.landcore.faction.commands.player / LandCore
+ */
+public class FactionCreateCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionCreateCommand(LandCore plugin) {
+ super("faction.create");
+ this.plugin = plugin;
+ setAliases("f create");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length != 1) {
+ player.sendMessage(CC.RED + "Usage: /faction create ");
+ return;
+ }
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile.getFaction() != null) {
+ player.sendMessage(CC.RED + "You are already in a faction.");
+ return;
+ }
+
+ String name = args[0];
+
+ if (name.length() < 2) {
+ player.sendMessage(CC.RED + "Faction names must be greater than or equal to 2 characters long.");
+ return;
+ }
+
+ if (!StringUtils.isAlpha(name)) {
+ player.sendMessage(CC.RED + "Faction names must only contain alpha characters (letters only).");
+ return;
+ }
+
+ if (name.length() > 8) {
+ player.sendMessage(CC.RED + "Faction names must be less than or equal to 8 characters long.");
+ return;
+ }
+
+ Faction faction = this.plugin.getFactionManager().getFaction(name);
+
+ if (faction != null) {
+ player.sendMessage(CC.RED + "A faction with that name already exists!");
+ return;
+ }
+
+ Faction createdFaction = new Faction(name, player.getUniqueId());
+ createdFaction.getMembers().add(player.getUniqueId());
+ factionProfile.setFaction(createdFaction);
+ createdFaction.setDescription("This is the default description...");
+ createdFaction.setDateCreated(LandCoreAPI.getTodayDate() + " " + LandCoreAPI.getCurrentTime());
+ this.plugin.getFactionManager().getFactions().add(createdFaction);
+
+ player.sendMessage(CC.GREEN + "You have successfully created a new faction!");
+
+ TaskUtil.runAsync(plugin.getFactionManager()::save);
+ this.plugin.getFactionManager().savePlayerFaction(player);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionInfoCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionInfoCommand.java
new file mode 100644
index 0000000..b1bea68
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionInfoCommand.java
@@ -0,0 +1,89 @@
+package me.devkevin.landcore.faction.commands.player;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.member.FactionMember;
+import me.devkevin.landcore.faction.member.FactionMemberType;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.craftbukkit.libs.joptsimple.internal.Strings;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 13:32
+ * FactionInfoCommand / me.devkevin.landcore.faction.commands.player / LandCore
+ */
+public class FactionInfoCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionInfoCommand(LandCore plugin) {
+ super("faction.info");
+ this.plugin = plugin;
+ setAliases("f info");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ if (args.length == 0) {
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile.getFaction() == null) {
+ player.sendMessage(CC.RED + "You are not in a faction!");
+ return;
+ }
+ describeFaction(player, factionProfile.getFaction());
+ return;
+ }
+
+ String name = args[0];
+ Faction faction = this.plugin.getFactionManager().getFaction(name);
+ Faction playerFaction = playerFaction(name);
+
+ if (faction == null && playerFaction == null) {
+ player.sendMessage(CC.RED + "No faction found with the name or member with the name '" + name + "'");
+ return;
+ }
+ if (playerFaction != null && faction == playerFaction) {
+ describeFaction(player, faction);
+ return;
+ }
+ if (faction != null) describeFaction(player, faction);
+ if (playerFaction != null) describeFaction(player, playerFaction);
+ }
+
+ private void describeFaction(Player player, Faction faction) {
+ List factionMembers = new ArrayList<>();
+ faction.getMembers().forEach(u -> factionMembers.add(new FactionMember(u, faction.getLeader().equals(u) ? FactionMemberType.LEADER : faction.getCaptains().contains(u) ? FactionMemberType.CAPTAIN : FactionMemberType.MEMBER)));
+ factionMembers.sort(Comparator.comparing(cm -> cm.getType().getWeight()));
+
+ List playerNames = new ArrayList<>();
+ factionMembers.forEach(cm -> playerNames.add((faction.getLeader().equals(cm.getUuid()) ? CC.DARK_GREEN + "***" : faction.getCaptains().contains(cm.getUuid()) ? CC.DARK_GREEN + "*" : "") + colorName(cm.getUuid())));
+
+ player.sendMessage(CC.GRAY + CC.BOARD_SEPARATOR);
+ player.sendMessage(CC.DARK_GREEN + CC.B + faction.getName() + CC.GRAY + " [" + faction.getMembers().size() + "/12]");
+ player.sendMessage(CC.YELLOW + "Description: " + CC.GRAY + faction.getDescription());
+ player.sendMessage(CC.YELLOW + "Members: " + Strings.join(playerNames, CC.GRAY + ", "));
+ player.sendMessage(CC.YELLOW + "Elo: " + CC.DARK_GREEN + (faction.getElo() == 0 ? "[N/A]" : faction.getElo()));
+ player.sendMessage(CC.YELLOW + "Date Created: " + CC.GREEN + faction.getDateCreated());
+ player.sendMessage(CC.GOLD + "View this faction on our site: " + CC.GRAY + "www.prac.lol/faction/" + faction.getName());
+ player.sendMessage(CC.GRAY + CC.BOARD_SEPARATOR);
+ }
+
+ private Faction playerFaction(String name) {
+ OfflinePlayer offlinePlayer = this.plugin.getServer().getOfflinePlayer(name);
+ return this.plugin.getFactionManager().getFactions().stream().filter(faction -> faction.getMembers().contains(offlinePlayer.getUniqueId())).findFirst().orElse(null);
+ }
+
+ private String colorName(UUID uuid) {
+ OfflinePlayer offlinePlayer = this.plugin.getServer().getOfflinePlayer(uuid);
+ return offlinePlayer.isOnline() ? CC.GREEN + offlinePlayer.getName() : CC.RED + offlinePlayer.getName();
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionLeaveCommand.java b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionLeaveCommand.java
new file mode 100644
index 0000000..b8e7ed2
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/commands/player/FactionLeaveCommand.java
@@ -0,0 +1,51 @@
+package me.devkevin.landcore.faction.commands.player;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.commands.PlayerCommand;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.TaskUtil;
+import me.devkevin.landcore.utils.message.CC;
+import org.bukkit.entity.Player;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 2:36
+ * FactionLeaveCommand / me.devkevin.landcore.faction.commands.player / LandCore
+ */
+public class FactionLeaveCommand extends PlayerCommand {
+ private final LandCore plugin;
+
+ public FactionLeaveCommand(LandCore plugin) {
+ super("faction.leave");
+ this.plugin = plugin;
+ setAliases("f.leave");
+ }
+
+ @Override
+ public void execute(Player player, String[] args) {
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile.getFaction() != null) {
+ player.sendMessage(CC.RED + "You are already in a faction.");
+ return;
+ }
+
+ Faction faction = factionProfile.getFaction();
+
+ if (faction.getLeader().equals(player.getUniqueId())) {
+ player.sendMessage(CC.RED + "You are the faction leader. You must disband the faction or promote someone else.");
+ return;
+ }
+
+ faction.getMembers().remove(player.getUniqueId());
+ faction.getCaptains().remove(player.getUniqueId());
+ factionProfile.setFaction(null);
+ faction.broadcast(player.getDisplayName() + CC.YELLOW + " has left the faction!");
+
+ player.sendMessage(CC.RED + CC.B + "You have left the faction!");
+
+ TaskUtil.runAsync(plugin.getFactionManager()::save);
+ this.plugin.getFactionManager().savePlayerFaction(player);
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/invite/FactionInvite.java b/LandCore/src/main/java/me/devkevin/landcore/faction/invite/FactionInvite.java
new file mode 100644
index 0000000..858e5f5
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/invite/FactionInvite.java
@@ -0,0 +1,20 @@
+package me.devkevin.landcore.faction.invite;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import me.devkevin.landcore.faction.Faction;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 0:38
+ * FactionInvite / me.devkevin.landcore.faction.invite / LandCore
+ */
+@Getter
+@Setter
+@RequiredArgsConstructor
+public class FactionInvite {
+ private final Faction faction;
+ private long timestamp = System.currentTimeMillis();
+ private boolean cancelled;
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/listener/FactionListener.java b/LandCore/src/main/java/me/devkevin/landcore/faction/listener/FactionListener.java
new file mode 100644
index 0000000..62c081c
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/listener/FactionListener.java
@@ -0,0 +1,84 @@
+package me.devkevin.landcore.faction.listener;
+
+import com.google.common.collect.Maps;
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.message.Messages;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.AsyncPlayerChatEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerLoginEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import java.util.Map;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 1:29
+ * FactionListener / me.devkevin.landcore.faction.listener / LandCore
+ */
+public class FactionListener implements Listener {
+ private final LandCore plugin = LandCore.getInstance();
+
+ @EventHandler
+ public void onPlayerLoginEvent(PlayerLoginEvent event) {
+ Player player = event.getPlayer();
+
+ this.plugin.getFactionManager().addPlayer(player);
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile == null) {
+ event.disallow(PlayerLoginEvent.Result.KICK_BANNED, Messages.DATA_LOAD_FAIL);
+ return;
+ }
+
+ this.plugin.getFactionManager().loadPlayerFaction(player);
+ }
+
+ @EventHandler
+ public void onPlayerJoinEvent(PlayerJoinEvent event) {
+ Player player = event.getPlayer();
+
+ CoreProfile profile = this.plugin.getProfileManager().getProfile(player.getUniqueId());
+
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile != null) {
+ Map message = Maps.newHashMap();
+ message.put("server", this.plugin.getServerName());
+ message.put("sender", profile.getRank().getColor() + player.getName());
+
+ plugin.getRedisMessenger().send("faction-join", message);
+ }
+ }
+
+ @EventHandler
+ public void onPlayerQuitEvent(PlayerQuitEvent event) {
+ Player player = event.getPlayer();
+
+ this.plugin.getFactionManager().removePlayer(player);
+ this.plugin.getFactionManager().savePlayerFaction(player);
+ }
+
+ @EventHandler
+ public void onChat(AsyncPlayerChatEvent event) {
+ Player player = event.getPlayer();
+ String chatMessage = event.getMessage();
+
+ CoreProfile coreProfile = this.plugin.getProfileManager().getProfile(player.getUniqueId());
+ FactionProfile factionProfile = this.plugin.getFactionManager().getProfile(player);
+
+ if (factionProfile != null && factionProfile.getFaction() != null && factionProfile.getFaction().isFactionChat()) {
+ Map message = Maps.newHashMap();
+ message.put("server", plugin.getServerName());
+ message.put("format", coreProfile.getRank().getColor() + player.getName());
+ message.put("message", chatMessage);
+ message.put("sender", event.getPlayer().getName());
+
+ plugin.getRedisMessenger().send("faction-chat", message);
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/manager/FactionManager.java b/LandCore/src/main/java/me/devkevin/landcore/faction/manager/FactionManager.java
new file mode 100644
index 0000000..392ec6a
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/manager/FactionManager.java
@@ -0,0 +1,145 @@
+package me.devkevin.landcore.faction.manager;
+
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.model.Filters;
+import com.mongodb.client.model.ReplaceOptions;
+import lombok.Getter;
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.profile.FactionProfile;
+import me.devkevin.landcore.utils.message.CC;
+import org.bson.Document;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.util.*;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 0:48
+ * FactionManager / me.devkevin.landcore.faction.manager / LandCore
+ */
+@Getter
+public class FactionManager {
+ private final LandCore plugin = LandCore.getInstance();
+
+ private final List factions = new ArrayList<>();
+ private final Map factionProfileMap = new HashMap<>();
+
+ public FactionManager() {
+ load();
+ }
+
+ private void load() {
+ MongoCollection collection = this.plugin.getMongoStorage().getFactionsCollection();
+
+ for (Document document : collection.find()) {
+ Faction faction = new Faction(document.getString("name"), (UUID) document.get("leader"));
+ faction.setMembers((List) document.get("members"));
+ faction.getMembers().add((UUID) document.get("leader"));
+ faction.setCaptains((List) document.get("captains"));
+ faction.setDescription(document.getString("description"));
+ faction.setDateCreated(document.getString("date-created"));
+ faction.setElo(document.getInteger("elo"));
+ faction.setWins(document.getInteger("wins"));
+ faction.setLosses(document.getInteger("losses"));
+ faction.setWinStreak(document.getInteger("winStreak"));
+ if (document.containsKey("description")) {
+ faction.setDescription(document.getString("description"));
+ }
+ if (document.containsKey("password")) {
+ faction.setPassword(document.getString("password"));
+ }
+
+ faction.setFactionChat(document.getBoolean("faction_chat_enabled"));
+
+ factions.add(faction);
+ }
+ }
+
+ public void save() {
+ MongoCollection collection = this.plugin.getMongoStorage().getFactionsCollection();
+ collection.deleteMany(new Document());
+
+ for (Faction faction : factions) {
+ Document document = new Document()
+ .append("name", faction.getName())
+ .append("leader", faction.getLeader())
+ .append("members", faction.getMembers())
+ .append("captains", faction.getCaptains())
+ .append("date-created", faction.getDateCreated())
+ .append("elo", faction.getElo())
+ .append("wins", faction.getWins())
+ .append("losses", faction.getLosses())
+ .append("winStreak", faction.getWinStreak())
+ .append("faction_chat_enabled", faction.isFactionChat());
+
+ if (faction.getDescription() != null) {
+ document.append("description", faction.getDescription());
+ }
+ if (faction.getPassword() != null) {
+ document.append("password", faction.getPassword());
+ }
+
+ collection.insertOne(document);
+ }
+ }
+
+ public void loadPlayerFaction(Player player) {
+ MongoCollection collection = this.plugin.getMongoStorage().getFactionsPlayersCollection();
+ Document document = collection.find(Filters.eq("uuid", player.getUniqueId().toString())).first();
+
+ if (document != null) {
+ FactionProfile factionProfile = this.getProfile(player);
+ Faction faction = this.getFaction(document.getString("faction"));
+
+ factionProfile.setFaction(faction);
+ }
+ }
+
+ public void savePlayerFaction(Player player) {
+ MongoCollection collection = this.plugin.getMongoStorage().getFactionsPlayersCollection();
+ String uuid = player.getUniqueId().toString();
+
+ FactionProfile factionProfile = this.getProfile(player);
+
+ if (factionProfile == null) {
+ collection.deleteOne(Filters.eq("uuid", uuid));
+ } else {
+ Document document = new Document("uuid", uuid)
+ .append("faction", factionProfile.getFaction().getName());
+ collection.replaceOne(Filters.eq("uuid", uuid), document, new ReplaceOptions().upsert(true));
+ }
+ }
+
+ public Faction getFaction(String name) {
+ return factions.stream().filter(faction -> faction.getName().equalsIgnoreCase(name)).findFirst().orElse(null);
+ }
+
+ public void addPlayer(Player player) {
+ factionProfileMap.put(player.getUniqueId(), new FactionProfile());
+ }
+
+ public void removePlayer(Player player) {
+ factionProfileMap.remove(player.getUniqueId());
+ }
+
+ public FactionProfile getProfile(Player player) {
+ return factionProfileMap.get(player.getUniqueId());
+ }
+ public boolean hasProfile(Player player) {
+ return factionProfileMap.containsKey(player.getUniqueId());
+ }
+
+ public void broadcastToFactions(String message, String server) {
+ for (Faction faction : factions) {
+ faction.broadcast(CC.DARK_GREEN + "(Faction) " + message + " " + server);
+ }
+ }
+
+ public void broadcastToFactionsChat(String displayName, String message, String server) {
+ for (Faction faction : factions) {
+ faction.broadcast(CC.DARK_GREEN + "(Faction) " + CC.GOLD + " [" + server + "] " + displayName + CC.GRAY + " : " + CC.R + message);
+ }
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/member/FactionMember.java b/LandCore/src/main/java/me/devkevin/landcore/faction/member/FactionMember.java
new file mode 100644
index 0000000..c60114e
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/member/FactionMember.java
@@ -0,0 +1,20 @@
+package me.devkevin.landcore.faction.member;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.UUID;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 0:39
+ * FactionMember / me.devkevin.landcore.faction.member / LandCore
+ */
+@Getter
+@Setter
+@AllArgsConstructor
+public class FactionMember {
+ private final UUID uuid;
+ private final FactionMemberType type;
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/member/FactionMemberType.java b/LandCore/src/main/java/me/devkevin/landcore/faction/member/FactionMemberType.java
new file mode 100644
index 0000000..84a9fd9
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/member/FactionMemberType.java
@@ -0,0 +1,20 @@
+package me.devkevin.landcore.faction.member;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 0:40
+ * FactionMemberType / me.devkevin.landcore.faction.member / LandCore
+ */
+@Getter
+@AllArgsConstructor
+public enum FactionMemberType {
+ LEADER("Leader", 0),
+ CAPTAIN("Captain", 1),
+ MEMBER("Member", 2);
+
+ private final String name;
+ private final int weight;
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/faction/profile/FactionProfile.java b/LandCore/src/main/java/me/devkevin/landcore/faction/profile/FactionProfile.java
new file mode 100644
index 0000000..a9dcd5b
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/faction/profile/FactionProfile.java
@@ -0,0 +1,21 @@
+package me.devkevin.landcore.faction.profile;
+
+import lombok.Getter;
+import lombok.Setter;
+import me.devkevin.landcore.faction.Faction;
+import me.devkevin.landcore.faction.invite.FactionInvite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 21/03/2023 @ 0:43
+ * FactionProfile / me.devkevin.landcore.faction.profile / LandCore
+ */
+@Getter
+@Setter
+public class FactionProfile {
+ private Faction faction;
+ private List inviteList = new ArrayList<>();
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/gson/CustomLocationTypeAdapterFactory.java b/LandCore/src/main/java/me/devkevin/landcore/gson/CustomLocationTypeAdapterFactory.java
new file mode 100644
index 0000000..abad574
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/gson/CustomLocationTypeAdapterFactory.java
@@ -0,0 +1,77 @@
+package me.devkevin.landcore.gson;
+
+import com.google.common.base.Preconditions;
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.utils.location.CustomLocation;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.io.IOException;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 18/01/2023 @ 15:15
+ * CustomLocationTypeAdapterFactory / land.pvp.core.gson / LandCore
+ */
+public class CustomLocationTypeAdapterFactory implements TypeAdapterFactory {
+
+ public static LocationData serialize(CustomLocation customLocation) {
+ Preconditions.checkNotNull(customLocation);
+
+ return new LocationData(customLocation.getWorld(), customLocation.getX(), customLocation.getY(),
+ customLocation.getZ(), customLocation.getYaw(), customLocation.getPitch());
+ }
+
+ public static CustomLocation deserialize(LocationData locationData) {
+ Preconditions.checkNotNull(locationData);
+
+ return new CustomLocation(locationData.getWorld(), locationData.getX(), locationData.getY(), locationData
+ .getZ(), locationData.getYaw(), locationData.getPitch());
+ }
+
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken typeToken) {
+ if (!CustomLocation.class.isAssignableFrom(typeToken.getRawType())) {
+ return null;
+ }
+
+ return new TypeAdapter() {
+ @Override
+ public void write(JsonWriter jsonWriter, T location) throws IOException {
+ if (location == null) {
+ jsonWriter.nullValue();
+ } else {
+ LandCore.GSON.toJson(serialize((CustomLocation) location), LocationData.class, jsonWriter);
+ }
+ }
+
+ @Override
+ public T read(JsonReader jsonReader) throws IOException {
+ if (jsonReader.peek() == null) {
+ jsonReader.nextNull();
+ return null;
+ } else {
+ return (T) deserialize(LandCore.GSON.fromJson(jsonReader, LocationData.class));
+ }
+ }
+ };
+ }
+
+ @Getter
+ @RequiredArgsConstructor
+ private static class LocationData {
+
+ private final String world;
+ private final double x;
+ private final double y;
+ private final double z;
+ private final float yaw;
+ private final float pitch;
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/gson/ItemStackTypeAdapterFactory.java b/LandCore/src/main/java/me/devkevin/landcore/gson/ItemStackTypeAdapterFactory.java
new file mode 100644
index 0000000..1143b68
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/gson/ItemStackTypeAdapterFactory.java
@@ -0,0 +1,175 @@
+package me.devkevin.landcore.gson;
+
+import com.google.common.base.Preconditions;
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.gson.item.EnchantType;
+import me.devkevin.landcore.gson.item.ItemMetaType;
+import me.devkevin.landcore.gson.item.ItemType;
+import org.bukkit.Color;
+import org.bukkit.Material;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.*;
+import org.bukkit.potion.PotionEffect;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 18/01/2023 @ 15:15
+ * ItemStackTypeAdapterFactory / land.pvp.core.gson / LandCore
+ */
+public class ItemStackTypeAdapterFactory implements TypeAdapterFactory {
+
+ public static ItemType serializeItem(ItemStack itemStack) {
+ Preconditions.checkNotNull(itemStack);
+
+ ItemType item;
+ ItemMeta itemStackMeta;
+ ItemMetaType itemMeta = null;
+ List itemEnchants = null;
+
+ if (itemStack.hasItemMeta()) {
+ itemStackMeta = itemStack.getItemMeta();
+ itemMeta = new ItemMetaType();
+
+ if (itemStackMeta.hasDisplayName()) {
+ itemMeta.setDisplayName(itemStackMeta.getDisplayName());
+ }
+
+ if (itemStackMeta.hasLore()) {
+ itemMeta.setLore(itemStackMeta.getLore());
+ }
+
+ if (itemStackMeta instanceof EnchantmentStorageMeta) {
+ EnchantmentStorageMeta esm = (EnchantmentStorageMeta) itemStackMeta;
+ if (esm.hasStoredEnchants()) {
+ List storedEnchants = new ArrayList<>();
+ for (Map.Entry entry : esm.getStoredEnchants().entrySet()) {
+ storedEnchants.add(new EnchantType(entry.getKey().getName(), entry.getValue()));
+ }
+ itemMeta.setStoredEnchants(storedEnchants);
+ }
+ }
+
+ if (itemStackMeta instanceof Repairable) {
+ itemMeta.setRepairCost(((Repairable) itemStackMeta).getRepairCost());
+ }
+
+ if (itemStackMeta instanceof LeatherArmorMeta) {
+ itemMeta.setLeatherArmorColor(((LeatherArmorMeta) itemStackMeta).getColor().asRGB());
+ }
+
+ if (itemStackMeta instanceof PotionMeta) {
+ PotionMeta potionMeta = (PotionMeta) itemStackMeta;
+ if (potionMeta.hasCustomEffects()) {
+ List potionEffects = new ArrayList<>();
+ potionEffects.addAll(potionMeta.getCustomEffects());
+ itemMeta.setPotionEffects(potionEffects);
+ }
+ }
+ }
+
+ for (Map.Entry e : itemStack.getEnchantments().entrySet()) {
+ if (itemEnchants == null) {
+ itemEnchants = new ArrayList<>();
+ }
+ itemEnchants.add(new EnchantType(e.getKey().getName(), e.getValue()));
+ }
+
+ item = new ItemType(itemStack.getType().toString(), itemStack.getDurability(), itemStack.getAmount(),
+ itemEnchants, itemMeta);
+
+ return item;
+ }
+
+ public static ItemStack deserializeItem(ItemType item) {
+ Preconditions.checkNotNull(item);
+
+ ItemStack itemStack = new ItemStack(Material.matchMaterial(item.getType()), item.getAmount());
+ ItemMeta itemMeta = itemStack.getItemMeta();
+
+ itemStack.setDurability(item.getDurability());
+
+ if (item.getEnchants() != null) {
+ for (EnchantType enchant : item.getEnchants()) {
+ itemMeta.addEnchant(Enchantment.getByName(enchant.getType()), enchant.getTier(), true);
+ }
+ }
+
+ if (item.getMeta() != null) {
+ if (item.getMeta().getDisplayName() != null) {
+ itemMeta.setDisplayName(item.getMeta().getDisplayName());
+ }
+
+ if (item.getMeta().getLore() != null) {
+ itemMeta.setLore(item.getMeta().getLore());
+ }
+
+ if (itemMeta instanceof EnchantmentStorageMeta && item.getMeta().getStoredEnchants() != null) {
+ EnchantmentStorageMeta esm = (EnchantmentStorageMeta) itemMeta;
+ for (EnchantType enchant : item.getMeta().getStoredEnchants()) {
+ esm.addStoredEnchant(Enchantment.getByName(enchant.getType()), enchant.getTier(), true);
+ }
+ }
+
+ if (itemMeta instanceof Repairable && item.getMeta().getRepairCost() != null) {
+ ((Repairable) itemMeta).setRepairCost(item.getMeta().getRepairCost());
+ }
+
+ if (itemMeta instanceof LeatherArmorMeta && item.getMeta().getLeatherArmorColor() != null) {
+ ((LeatherArmorMeta) itemMeta).setColor(Color.fromRGB(item.getMeta().getLeatherArmorColor()));
+ }
+
+ if (itemMeta instanceof PotionMeta && item.getMeta().getPotionEffects() != null) {
+ PotionMeta potionMeta = (PotionMeta) itemMeta;
+ for (PotionEffect effect : item.getMeta().getPotionEffects()) {
+ potionMeta.addCustomEffect(effect, true);
+ }
+ }
+ }
+
+ itemStack.setItemMeta(itemMeta);
+
+ return itemStack;
+ }
+
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken type) {
+ if (!ItemStack.class.isAssignableFrom(type.getRawType())) {
+ return null;
+ }
+
+ return new TypeAdapter() {
+
+ @Override
+ public void write(JsonWriter writer, T item) throws IOException {
+ if (item == null) {
+ writer.nullValue();
+ } else {
+ LandCore.GSON.toJson(serializeItem((ItemStack) item), ItemType.class, writer);
+ }
+ }
+
+ @Override
+ public T read(JsonReader reader) throws IOException {
+ if (reader.peek() == JsonToken.NULL) {
+ reader.nextNull();
+ return null;
+ } else {
+ return (T) deserializeItem(LandCore.GSON.fromJson(reader, ItemType.class));
+ }
+ }
+ };
+ }
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/gson/item/EnchantType.java b/LandCore/src/main/java/me/devkevin/landcore/gson/item/EnchantType.java
new file mode 100644
index 0000000..23d7ffc
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/gson/item/EnchantType.java
@@ -0,0 +1,16 @@
+package me.devkevin.landcore.gson.item;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 18/01/2023 @ 15:17
+ * EnchantType / land.pvp.core.gson.item / LandCore
+ */
+@Getter
+@RequiredArgsConstructor
+public class EnchantType {
+ private final String type;
+ private final int tier;
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/gson/item/ItemMetaType.java b/LandCore/src/main/java/me/devkevin/landcore/gson/item/ItemMetaType.java
new file mode 100644
index 0000000..2b117ec
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/gson/item/ItemMetaType.java
@@ -0,0 +1,23 @@
+package me.devkevin.landcore.gson.item;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.bukkit.potion.PotionEffect;
+
+import java.util.List;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 18/01/2023 @ 15:17
+ * ItemMetaType / land.pvp.core.gson.item / LandCore
+ */
+@Getter
+@Setter
+public class ItemMetaType {
+ private String displayName;
+ private List lore;
+ private List storedEnchants;
+ private Integer repairCost;
+ private Integer leatherArmorColor;
+ private List potionEffects;
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/gson/item/ItemType.java b/LandCore/src/main/java/me/devkevin/landcore/gson/item/ItemType.java
new file mode 100644
index 0000000..446b849
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/gson/item/ItemType.java
@@ -0,0 +1,22 @@
+package me.devkevin.landcore.gson.item;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 18/01/2023 @ 15:17
+ * ItemType / land.pvp.core.gson.item / LandCore
+ */
+@Getter
+@RequiredArgsConstructor
+public class ItemType {
+
+ private final String type;
+ private final short durability;
+ private final int amount;
+ private final List enchants;
+ private final ItemMetaType meta;
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/gson/item/PotionEffectType.java b/LandCore/src/main/java/me/devkevin/landcore/gson/item/PotionEffectType.java
new file mode 100644
index 0000000..0ef036f
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/gson/item/PotionEffectType.java
@@ -0,0 +1,17 @@
+package me.devkevin.landcore.gson.item;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 18/01/2023 @ 15:18
+ * PotionEffectType / land.pvp.core.gson.item / LandCore
+ */
+@Getter
+@RequiredArgsConstructor
+public class PotionEffectType {
+ private final String type;
+ private final int duration;
+ private final int amplifier;
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/handler/PacketListener.java b/LandCore/src/main/java/me/devkevin/landcore/handler/PacketListener.java
new file mode 100644
index 0000000..06408c0
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/handler/PacketListener.java
@@ -0,0 +1,118 @@
+package me.devkevin.landcore.handler;
+
+import me.devkevin.landcore.LandCore;
+import me.devkevin.landcore.player.CoreProfile;
+import me.devkevin.landcore.utils.location.CustomLocation;
+import net.minecraft.server.v1_8_R3.*;
+import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+import xyz.refinedev.spigot.api.handlers.impl.PacketHandler;
+
+/**
+ * @author DevKevin (devkevinggg@gmail.com)
+ * 23/01/2023 @ 17:51
+ * PacketListener / me.devkevin.landcore.handler / LandCore
+ */
+public abstract class PacketListener implements PacketHandler {
+ /*@Override
+ public void handleReceivedPacket(PlayerConnection playerConnection, Packet packet) {
+ Player player = playerConnection.getPlayer();
+ CoreProfile coreProfile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ if ("PacketPlayInFlying".equals(packet.getClass().getSimpleName())) {
+ handleFlyPacket((PacketPlayInFlying) packet, coreProfile);
+ }
+ }
+
+ @Override
+ public void handleSentPacket(PlayerConnection playerConnection, Packet packet) {
+ Player player = playerConnection.getPlayer();
+ CoreProfile coreProfile = LandCore.getInstance().getProfileManager().getProfile(player.getUniqueId());
+
+ switch (packet.getClass().getSimpleName()) {
+ case "PacketPlayOutEntityTeleport": {
+ this.handleTeleportPacket((PacketPlayOutEntityTeleport) packet, coreProfile, player);
+ break;
+ }
+ case "PacketPlayOutEntityLook":
+ case "PacketPlayOutRelEntityMove":
+ case "PacketPlayOutRelEntityMoveLook":
+ case "PacketPlayOutEntity": {
+ this.handleEntityPacket((PacketPlayOutEntity) packet, coreProfile, player);
+ break;
+ }
+ }
+ }
+
+ private void handleTeleportPacket(PacketPlayOutEntityTeleport packet, CoreProfile coreProfile, final Player player) {
+ final Entity targetEntity = ((CraftPlayer) player).getHandle().getWorld().a(packet.getA());
+ if (targetEntity instanceof EntityPlayer) {
+ Player target = (Player) targetEntity.getBukkitEntity();
+ double x = packet.getB() / 32.0;
+ double y = packet.getC() / 32.0;
+ double z = packet.getD() / 32.0;
+ float yaw = packet.getE() * 360.0f / 256.0f;
+ float pitch = packet.getF() * 360.0f / 256.0f;
+ if (coreProfile.getMisplace() != 0.0) {
+ CustomLocation lastLocation = coreProfile.getLastMovePacket();
+ float entityYaw = this.getAngle(x, z, lastLocation);
+ double addX = Math.cos(Math.toRadians(entityYaw + 90.0f)) * coreProfile.getMisplace();
+ double addZ = Math.sin(Math.toRadians(entityYaw + 90.0f)) * coreProfile.getMisplace();
+ x -= addX;
+ z -= addZ;
+ packet.setB(MathHelper.floor(x * 32.0));
+ packet.setD(MathHelper.floor(z * 32.0));
+ }
+ coreProfile.addPlayerPacket(target.getUniqueId(), new CustomLocation(x, y, z, yaw, pitch));
+ }
+ }
+
+ private void handleEntityPacket(final PacketPlayOutEntity packet, final CoreProfile coreProfile, final Player player) {
+ final Entity targetEntity = ((CraftPlayer) player).getHandle().getWorld().a(packet.getA());
+ if (targetEntity instanceof EntityPlayer) {
+ final Player target = (Player) targetEntity.getBukkitEntity();
+ final CustomLocation customLocation = coreProfile.getLastPlayerPacket(target.getUniqueId(), 1);
+ if (customLocation != null) {
+ final double x = packet.getB() / 32.0;
+ final double y = packet.getC() / 32.0;
+ final double z = packet.getD() / 32.0;
+ float yaw = packet.getE() * 360.0f / 256.0f;
+ float pitch = packet.getF() * 360.0f / 256.0f;
+ if (!packet.isH()) {
+ yaw = customLocation.getYaw();
+ pitch = customLocation.getPitch();
+ }
+ coreProfile.addPlayerPacket(target.getUniqueId(), new CustomLocation(customLocation.getX() + x, customLocation.getY() + y, customLocation.getZ() + z, yaw, pitch));
+ }
+ }
+ }
+
+ private void handleFlyPacket(final PacketPlayInFlying packet, final CoreProfile coreProfile) {
+ final CustomLocation customLocation = new CustomLocation(packet.a(), packet.b(), packet.c(), packet.d(), packet.e());
+ final CustomLocation lastLocation = coreProfile.getLastMovePacket();
+ if (lastLocation != null) {
+ if (!packet.g()) {
+ customLocation.setX(lastLocation.getX());
+ customLocation.setY(lastLocation.getY());
+ customLocation.setZ(lastLocation.getZ());
+ }
+ if (!packet.h()) {
+ customLocation.setYaw(lastLocation.getYaw());
+ customLocation.setPitch(lastLocation.getPitch());
+ }
+ }
+ coreProfile.setLastMovePacket(customLocation);
+ }
+
+ private float getAngle(final double posX, final double posZ, final CustomLocation location) {
+ final double x = posX - location.getX();
+ final double z = posZ - location.getZ();
+ float newYaw = (float) Math.toDegrees(-Math.atan(x / z));
+ if (z < 0.0 && x < 0.0) {
+ newYaw = (float) (90.0 + Math.toDegrees(Math.atan(z / x)));
+ } else if (z < 0.0 && x > 0.0) {
+ newYaw = (float) (-90.0 + Math.toDegrees(Math.atan(z / x)));
+ }
+ return newYaw;
+ }*/
+}
diff --git a/LandCore/src/main/java/me/devkevin/landcore/inventory/menu/Menu.java b/LandCore/src/main/java/me/devkevin/landcore/inventory/menu/Menu.java
new file mode 100644
index 0000000..ceacfe5
--- /dev/null
+++ b/LandCore/src/main/java/me/devkevin/landcore/inventory/menu/Menu.java
@@ -0,0 +1,63 @@
+package me.devkevin.landcore.inventory.menu;
+
+import me.devkevin.landcore.inventory.menu.action.Action;
+import lombok.Getter;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public abstract class Menu {
+ @Getter
+ private final Inventory inventory;
+ private final Map actions = new HashMap<>();
+ private final List