diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..50b31b8 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Zoot-1.0-SNAPSHOT \ No newline at end of file diff --git a/.idea/artifacts/zoot_jar.xml b/.idea/artifacts/zoot_jar.xml new file mode 100644 index 0000000..4ec6b26 --- /dev/null +++ b/.idea/artifacts/zoot_jar.xml @@ -0,0 +1,17 @@ + + + $PROJECT_DIR$/out/artifacts/zoot_jar + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..3dc2ea7 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dictionaries/skruf.xml b/.idea/dictionaries/skruf.xml new file mode 100644 index 0000000..ad61e56 --- /dev/null +++ b/.idea/dictionaries/skruf.xml @@ -0,0 +1,35 @@ + + + + addperm + addpermission + clearinv + deletepermission + delperm + deserialized + gamemode + gson + hideplayer + listpermissions + listperms + mojang + setcolor + setmaxslots + setprefix + setslots + setspawn + setsuffix + setweight + setworldspawn + showplayer + teleported + unblacklisted + uninherit + uninherited + unmuted + uuids + worldspawn + zoot + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..66bd79e --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_code_gson_gson_2_8_5.xml b/.idea/libraries/Maven__com_google_code_gson_gson_2_8_5.xml new file mode 100644 index 0000000..2888f96 --- /dev/null +++ b/.idea/libraries/Maven__com_google_code_gson_gson_2_8_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_commons_commons_pool2_2_4_2.xml b/.idea/libraries/Maven__org_apache_commons_commons_pool2_2_4_2.xml new file mode 100644 index 0000000..2970b5e --- /dev/null +++ b/.idea/libraries/Maven__org_apache_commons_commons_pool2_2_4_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_mongodb_mongo_java_driver_3_8_2.xml b/.idea/libraries/Maven__org_mongodb_mongo_java_driver_3_8_2.xml new file mode 100644 index 0000000..e14cbdf --- /dev/null +++ b/.idea/libraries/Maven__org_mongodb_mongo_java_driver_3_8_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__redis_clients_jedis_2_9_0.xml b/.idea/libraries/Maven__redis_clients_jedis_2_9_0.xml new file mode 100644 index 0000000..77144ff --- /dev/null +++ b/.idea/libraries/Maven__redis_clients_jedis_2_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..90d6598 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..fbf9921 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..ab7fe1b --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,1050 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tag + defaultTag + profile = + zoo + static + activetag + getFullDisplayName + profile + getActiveTag + activ + getActiveTag() + get + getActiveRank + activeGrantactiveGrant + pig + va + zootr + zoot + pidg + rage + lom + h + pid + org.bik + ChatColor + color + mongo + cha + onAsyncPlayerChat + MONGO + + + import com.minexd.proton.bootstrap + proton.game + Validate.isTrue( + = " + " + uuid-cache + @CPL( + + + C:\Users\skruf\Documents\Projects\MineXD\proton + C:\Users\skruf\Documents\Projects\MineXD\zoot + C:\Users\steve\Desktop\IntelliJ Workspace\minexd-zoot-premiumsrc\Zoot 12.12.18\Zoot\src\main\java\com\minexd\zoot\profile + C:\Zoot\zoot\src\main\java\com\minexd\zoot\cache + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1537243184518 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + zoot:jar + + + + + + + + No facets are configured + + + + + + + + Zoot + + + + + + + + 1.8 + + + + + + + + zoot + + + + + + + + 1.8 + + + + + + + + Maven: com.google.code.gson:gson:2.8.5 + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index c54c134..89a678f 100644 --- a/README.md +++ b/README.md @@ -1 +1,31 @@ -# zoot \ No newline at end of file +zoot.admin.broadcast +zoot.staff.clearinv +zoot.staff.gamemode +zoot.admin.heal +zoot.admin.hideplayer +zoot.staff.more +zoot.staff.rename +zoot.staff.setslots +zoot.staff.setspawn +zoot.admin.showplayer +zoot.staff.spawn +zoot.staff.alts +zoot.staff.ban +zoot.staff.check +zoot.staff.kick +zoot.staff.mute +zoot.staff.unban +zoot.staff.unmute +zoot.staff.warn +zoot.staff.grant +zoot.staff.grant +zoot.staff +zoot.staff +zoot.staff.mutechat +zoot.admin.rank +zoot.admin.rank +zoot.admin.rank +zoot.admin.rank +zoot.admin.rank +zoot.admin.rank +zoot.admin.rank \ No newline at end of file diff --git a/Zoot-1.0-SNAPSHOT.iml b/Zoot-1.0-SNAPSHOT.iml new file mode 100644 index 0000000..02e59f5 --- /dev/null +++ b/Zoot-1.0-SNAPSHOT.iml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml new file mode 100644 index 0000000..9978221 --- /dev/null +++ b/dependency-reduced-pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + com.minexd + zoot + 1.0-SNAPSHOT + + + + true + src/main/resources + + plugin.yml + + + + src/main/resources + + plugin.yml + + + + + + maven-compiler-plugin + + 1.8 + 1.8 + -parameters + + + + maven-shade-plugin + 2.4.3 + + + package + + shade + + + + + + + + + org.spigotmc + spigot-api + 1.8.8-R0.1-SNAPSHOT + system + ${project.basedir}/libs/solexspigot-1.8.8-R0.1-SNAPSHOT.jar + + + org.projectlombok + lombok + LATEST + system + ${project.basedir}/lib/lombok-1.18.6.jar + + + com.qrakn + honcho + 1.0-SNAPSHOT + system + ${project.basedir}/libs/honcho-1.0-SNAPSHOT.jar + + + com.qrakn + phoenix + 1.0-SNAPSHOT + system + ${project.basedir}/libs/phoenix-lang-1.0-SNAPSHOT.jar + + + ru.tehkode + PermissionsEx + 1.0-SNAPSHOT + system + ${project.basedir}/libs/PermissionsEx-1.23.4.jar + + + net.milkbowl.vault + VaultAPI + 1.7 + system + ${project.basedir}/lib/VaultAPI-1.7.jar + + + + UTF-8 + + + diff --git a/lib/PermissionsEx-1.23.4.jar b/lib/PermissionsEx-1.23.4.jar new file mode 100644 index 0000000..bb4b5f5 Binary files /dev/null and b/lib/PermissionsEx-1.23.4.jar differ diff --git a/lib/VaultAPI-1.7.jar b/lib/VaultAPI-1.7.jar new file mode 100644 index 0000000..a1a179d Binary files /dev/null and b/lib/VaultAPI-1.7.jar differ diff --git a/lib/honcho-1.0-SNAPSHOT.jar b/lib/honcho-1.0-SNAPSHOT.jar new file mode 100644 index 0000000..1ca6e86 Binary files /dev/null and b/lib/honcho-1.0-SNAPSHOT.jar differ diff --git a/lib/lombok-1.18.6.jar b/lib/lombok-1.18.6.jar new file mode 100644 index 0000000..bf5378a Binary files /dev/null and b/lib/lombok-1.18.6.jar differ diff --git a/lib/phoenix-lang-1.0-SNAPSHOT.jar b/lib/phoenix-lang-1.0-SNAPSHOT.jar new file mode 100644 index 0000000..3fa3fee Binary files /dev/null and b/lib/phoenix-lang-1.0-SNAPSHOT.jar differ diff --git a/lib/ragespigot-1.8.8-R0.1-SNAPSHOT.jar b/lib/ragespigot-1.8.8-R0.1-SNAPSHOT.jar new file mode 100644 index 0000000..db31f49 Binary files /dev/null and b/lib/ragespigot-1.8.8-R0.1-SNAPSHOT.jar differ diff --git a/libs/PermissionsEx-1.23.4.jar b/libs/PermissionsEx-1.23.4.jar new file mode 100644 index 0000000..bb4b5f5 Binary files /dev/null and b/libs/PermissionsEx-1.23.4.jar differ diff --git a/libs/honcho-1.0-SNAPSHOT.jar b/libs/honcho-1.0-SNAPSHOT.jar new file mode 100644 index 0000000..1ca6e86 Binary files /dev/null and b/libs/honcho-1.0-SNAPSHOT.jar differ diff --git a/libs/phoenix-lang-1.0-SNAPSHOT.jar b/libs/phoenix-lang-1.0-SNAPSHOT.jar new file mode 100644 index 0000000..3fa3fee Binary files /dev/null and b/libs/phoenix-lang-1.0-SNAPSHOT.jar differ diff --git a/libs/ragespigot-1.8.8-R0.1-SNAPSHOT.jar b/libs/ragespigot-1.8.8-R0.1-SNAPSHOT.jar new file mode 100644 index 0000000..db31f49 Binary files /dev/null and b/libs/ragespigot-1.8.8-R0.1-SNAPSHOT.jar differ diff --git a/libs/solexspigot-1.8.8-R0.1-SNAPSHOT.jar b/libs/solexspigot-1.8.8-R0.1-SNAPSHOT.jar new file mode 100644 index 0000000..cfba3f5 Binary files /dev/null and b/libs/solexspigot-1.8.8-R0.1-SNAPSHOT.jar differ diff --git a/out/artifacts/zoot_jar/zoot.jar b/out/artifacts/zoot_jar/zoot.jar new file mode 100644 index 0000000..1705522 Binary files /dev/null and b/out/artifacts/zoot_jar/zoot.jar differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9be199d --- /dev/null +++ b/pom.xml @@ -0,0 +1,122 @@ + + + 4.0.0 + + com.minexd + zoot + 1.0-SNAPSHOT + + + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + -parameters + + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.3 + + + package + + shade + + + + + + + + src/main/resources + true + + plugin.yml + + + + src/main/resources + false + + plugin.yml + + + + + + + + + org.spigotmc + spigot-api + 1.8.8-R0.1-SNAPSHOT + system + ${project.basedir}/libs/solexspigot-1.8.8-R0.1-SNAPSHOT.jar + + + org.projectlombok + lombok + LATEST + system + ${project.basedir}/lib/lombok-1.18.6.jar + + + com.google.code.gson + gson + LATEST + compile + + + org.mongodb + mongo-java-driver + 3.8.2 + compile + + + redis.clients + jedis + 2.9.0 + compile + + + com.qrakn + honcho + 1.0-SNAPSHOT + system + ${project.basedir}/libs/honcho-1.0-SNAPSHOT.jar + + + com.qrakn + phoenix + 1.0-SNAPSHOT + system + ${project.basedir}/libs/phoenix-lang-1.0-SNAPSHOT.jar + + + ru.tehkode + PermissionsEx + 1.0-SNAPSHOT + system + ${project.basedir}/libs/PermissionsEx-1.23.4.jar + + + net.milkbowl.vault + VaultAPI + 1.7 + system + ${project.basedir}/lib/VaultAPI-1.7.jar + + + + \ No newline at end of file diff --git a/src/main/java/com/minexd/zoot/Locale.java b/src/main/java/com/minexd/zoot/Locale.java new file mode 100644 index 0000000..9616e92 --- /dev/null +++ b/src/main/java/com/minexd/zoot/Locale.java @@ -0,0 +1,53 @@ +package com.minexd.zoot; + +import java.text.MessageFormat; +import lombok.AllArgsConstructor; +import org.bukkit.ChatColor; + +@AllArgsConstructor +public enum Locale { + + FAILED_TO_LOAD_PROFILE("COMMON_ERRORS.FAILED_TO_LOAD_PROFILE"), + COULD_NOT_RESOLVE_PLAYER("COMMON_ERRORS.COULD_NOT_RESOLVE_PLAYER"), + PLAYER_NOT_FOUND("COMMON_ERRORS.PLAYER_NOT_FOUND"), + RANK_NOT_FOUND("COMMON_ERRORS.RANK_NOT_FOUND"), + STAFF_CHAT("STAFF.CHAT"), + STAFF_BROADCAST_PREFIX("STAFF.BROADCAST_PREFIX"), + STAFF_JOIN_NETWORK("STAFF.JOIN_NETWORK"), + STAFF_SWITCH_SERVER("STAFF.SWITCH_SERVER"), + STAFF_LEAVE_NETWORK("STAFF.LEAVE_NETWORK"), + CLEAR_CHAT_BROADCAST("CHAT.CLEAR_CHAT_BROADCAST"), + MUTE_CHAT_BROADCAST("CHAT.MUTE_CHAT_BROADCAST"), + DELAY_CHAT_ENABLED_BROADCAST("CHAT.DELAY_CHAT_ENABLED_BROADCAST"), + DELAY_CHAT_DISABLED_BROADCAST("CHAT.DELAY_CHAT_DISABLED_BROADCAST"), + CHAT_DELAYED("CHAT.CHAT_DELAYED"), + NETWORK_BROADCAST_PREFIX("NETWORK.BROADCAST_PREFIX"), + NETWORK_RANK_REFRESHED("NETWORK.RANK_REFRESH"), + NETWORK_RANK_DELETED("NETWORK.RANK_DELETE"), + CONVERSATION_SEND_MESSAGE("CONVERSATION.SEND_MESSAGE"), + CONVERSATION_RECEIVE_MESSAGE("CONVERSATION.RECEIVE_MESSAGE"), + OPTIONS_PRIVATE_MESSAGES_ENABLED("OPTIONS.PRIVATE_MESSAGES_ENABLED"), + OPTIONS_PRIVATE_MESSAGES_DISABLED("OPTIONS.PRIVATE_MESSAGES_DISABLED"), + OPTIONS_PRIVATE_MESSAGE_SOUND_ENABLED("OPTIONS.PRIVATE_MESSAGE_SOUNDS_ENABLED"), + OPTIONS_PRIVATE_MESSAGE_SOUND_DISABLED("OPTIONS.PRIVATE_MESSAGE_SOUNDS_DISABLED"), + OPTIONS_GLOBAL_CHAT_ENABLED("OPTIONS.GLOBAL_CHAT_ENABLED"), + OPTIONS_GLOBAL_CHAT_DISABLED("OPTIONS.GLOBAL_CHAT_DISABLED"); + + private String path; + + public String format(Object... objects) { + return new MessageFormat(ChatColor.translateAlternateColorCodes('&', + Zoot.get().getMainConfig().getString(path))).format(objects); + } + +// public static final String PUBLIC_CHAT_MUTE_APPLIED = "&bThe public chat has been muted by {actor}"; +// public static final String PUBLIC_CHAT_DELAY_APPLIED = "&bThe public chat has been delayed by {actor}"; +// public static final String CHAT_ATTEMPT_FILTERED = "&cYour message was filtered."; +// public static final String CHAT_ATTEMPT_PLAYER_MUTED = "&cYou are currently muted for another {time-remaining}."; +// public static final String CHAT_ATTEMPT_PUBLIC_CHAT_MUTED = "&cThe public chat is currently muted."; +// public static final String CHAT_ATTEMPT_PUBLIC_CHAT_DELAYED = "&cYou may chat again in {time-remaining}."; +// public static final String OPTIONS_GLOBAL_CHAT_DISABLED = "&cYou have your public chat disabled."; +// public static final String OPTIONS_PRIVATE_CHAT_DISABLED = "&cYou have your private messages disabled."; +// public static final String PTIONS_PRIVATE_CHAT_DISABLED_OTHER = "&cThat player has their private messages disabled."; + +} diff --git a/src/main/java/com/minexd/zoot/Zoot.java b/src/main/java/com/minexd/zoot/Zoot.java new file mode 100644 index 0000000..c6cdf25 --- /dev/null +++ b/src/main/java/com/minexd/zoot/Zoot.java @@ -0,0 +1,316 @@ +package com.minexd.zoot; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.minexd.zoot.chat.Chat; +import com.minexd.zoot.chat.command.ClearChatCommand; +import com.minexd.zoot.chat.command.MuteChatCommand; +import com.minexd.zoot.chat.ChatListener; +import com.minexd.zoot.chat.command.SlowChatCommand; +import com.minexd.zoot.config.ConfigValidation; +import com.minexd.zoot.essentials.Essentials; +import com.minexd.zoot.essentials.command.*; +import com.minexd.zoot.essentials.EssentialsListener; +import com.minexd.zoot.network.NetworkPacketListener; +import com.minexd.zoot.network.packet.PacketAddGrant; +import com.minexd.zoot.network.packet.PacketBroadcastPunishment; +import com.minexd.zoot.network.packet.PacketDeleteGrant; +import com.minexd.zoot.network.packet.PacketDeleteRank; +import com.minexd.zoot.network.packet.PacketRefreshRank; +import com.minexd.zoot.network.packet.PacketStaffChat; +import com.minexd.zoot.network.packet.PacketStaffJoinNetwork; +import com.minexd.zoot.network.packet.PacketStaffLeaveNetwork; +import com.minexd.zoot.network.packet.PacketStaffSwitchServer; +import com.minexd.zoot.pidgin.Pidgin; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.ProfileTypeAdapter; +import com.minexd.zoot.profile.option.command.OptionsCommand; +import com.minexd.zoot.profile.conversation.command.MessageCommand; +import com.minexd.zoot.profile.conversation.command.ReplyCommand; +import com.minexd.zoot.profile.grant.command.GrantCommand; +import com.minexd.zoot.profile.grant.command.GrantsCommand; +import com.minexd.zoot.profile.grant.GrantListener; +import com.minexd.zoot.profile.ProfileListener; +import com.minexd.zoot.profile.option.command.ToggleGlobalChatCommand; +import com.minexd.zoot.profile.option.command.TogglePrivateMessagesCommand; +import com.minexd.zoot.profile.option.command.ToggleSoundsCommand; +import com.minexd.zoot.profile.punishment.command.BanCommand; +import com.minexd.zoot.profile.punishment.command.CheckCommand; +import com.minexd.zoot.profile.punishment.command.KickCommand; +import com.minexd.zoot.profile.punishment.command.MuteCommand; +import com.minexd.zoot.profile.punishment.command.UnbanCommand; +import com.minexd.zoot.profile.punishment.command.UnmuteCommand; +import com.minexd.zoot.profile.punishment.command.WarnCommand; +import com.minexd.zoot.profile.staff.command.AltsCommand; +import com.minexd.zoot.profile.punishment.listener.PunishmentListener; +import com.minexd.zoot.profile.staff.command.StaffModeCommand; +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.rank.RankTypeAdapter; +import com.minexd.zoot.profile.staff.command.StaffChatCommand; +import com.minexd.zoot.rank.command.RankAddPermissionCommand; +import com.minexd.zoot.rank.command.RankCreateCommand; +import com.minexd.zoot.rank.command.RankDeleteCommand; +import com.minexd.zoot.rank.command.RankHelpCommand; +import com.minexd.zoot.rank.command.RankInfoCommand; +import com.minexd.zoot.rank.command.RankInheritCommand; +import com.minexd.zoot.rank.command.RankRemovePermissionCommand; +import com.minexd.zoot.rank.command.RankSetColorCommand; +import com.minexd.zoot.rank.command.RankSetPrefixCommand; +import com.minexd.zoot.rank.command.RankSetSuffixCommand; +import com.minexd.zoot.rank.command.RankSetWeightCommand; +import com.minexd.zoot.rank.command.RankUninheritCommand; +import com.minexd.zoot.rank.command.RanksCommand; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.adapter.ChatColorTypeAdapter; +import com.minexd.zoot.util.duration.Duration; +import com.minexd.zoot.util.duration.DurationTypeAdapter; +import com.minexd.zoot.util.menu.MenuListener; +import com.minexd.zoot.cache.RedisCache; +import com.mongodb.MongoClient; +import com.mongodb.MongoClientOptions; +import com.mongodb.MongoCredential; +import com.mongodb.ServerAddress; +import com.mongodb.client.MongoDatabase; +import com.qrakn.honcho.Honcho; +import com.qrakn.phoenix.lang.file.type.BasicConfigurationFile; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Level; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +public class Zoot extends JavaPlugin { + + public static final Gson GSON = new Gson(); + public static final Type LIST_STRING_TYPE = new TypeToken>() {}.getType(); + + private static Zoot zoot; + + @Getter private BasicConfigurationFile mainConfig; + + @Getter private Honcho honcho; + @Getter private Pidgin pidgin; + + @Getter private MongoDatabase mongoDatabase; + @Getter private JedisPool jedisPool; + @Getter private RedisCache redisCache; + + @Getter private Essentials essentials; + @Getter private Chat chat; + + @Getter @Setter private boolean debug; + + @Override + public void onEnable() { + zoot = this; + + mainConfig = new BasicConfigurationFile(this, "config"); + + new ConfigValidation(mainConfig.getFile(), mainConfig.getConfiguration(), 3).check(); + + loadMongo(); + loadRedis(); + + redisCache = new RedisCache(this); + essentials = new Essentials(this); + chat = new Chat(this); + + honcho = new Honcho(this); + + Arrays.asList( + new BroadcastCommand(), + new ClearCommand(), + new DayCommand(), + new GameModeCommand(), + new HealCommand(), + new HidePlayerCommand(), + new LocationCommand(), + new MoreCommand(), + new NightCommand(), + new RenameCommand(), + new SetSlotsCommand(), + new SetSpawnCommand(), + new ShowPlayerCommand(), + new SpawnCommand(), + new SunsetCommand(), + new ClearChatCommand(), + new SlowChatCommand(), + new AltsCommand(), + new BanCommand(), + new CheckCommand(), + new KickCommand(), + new MuteCommand(), + new UnbanCommand(), + new UnmuteCommand(), + new WarnCommand(), + new GrantCommand(), + new GrantsCommand(), + new StaffChatCommand(), + new StaffModeCommand(), + new MuteChatCommand(), + new OptionsCommand(), + new RankAddPermissionCommand(), + new RankCreateCommand(), + new RankDeleteCommand(), + new RankHelpCommand(), + new RankInfoCommand(), + new RankInheritCommand(), + new RankRemovePermissionCommand(), + new RanksCommand(), + new RankSetColorCommand(), + new RankSetPrefixCommand(), + new RankSetSuffixCommand(), + new RankSetWeightCommand(), + new RankUninheritCommand(), + new ZootDebugCommand(), + new TeleportWorldCommand(), + new MessageCommand(), + new ReplyCommand(), + new ToggleGlobalChatCommand(), + new TogglePrivateMessagesCommand(), + new ToggleSoundsCommand(), + new PingCommand(), + new ListCommand() + ).forEach(honcho::registerCommand); + + honcho.registerTypeAdapter(Rank.class, new RankTypeAdapter()); + honcho.registerTypeAdapter(Profile.class, new ProfileTypeAdapter()); + honcho.registerTypeAdapter(Duration.class, new DurationTypeAdapter()); + honcho.registerTypeAdapter(ChatColor.class, new ChatColorTypeAdapter()); + + pidgin = new Pidgin("zoot", + mainConfig.getString("REDIS.HOST"), + mainConfig.getInteger("REDIS.PORT"), + mainConfig.getBoolean("REDIS.AUTHENTICATION.ENABLED") ? + mainConfig.getString("REDIS.AUTHENTICATION.PASSWORD") : null + ); + + Arrays.asList( + PacketAddGrant.class, + PacketBroadcastPunishment.class, + PacketDeleteGrant.class, + PacketDeleteRank.class, + PacketRefreshRank.class, + PacketStaffChat.class, + PacketStaffJoinNetwork.class, + PacketStaffLeaveNetwork.class, + PacketStaffSwitchServer.class + ).forEach(pidgin::registerPacket); + + pidgin.registerListener(new NetworkPacketListener(this)); + + Arrays.asList( + new ProfileListener(this), + new MenuListener(this), + new EssentialsListener(this), + new ChatListener(this), + new GrantListener(this), + new PunishmentListener(this) + ).forEach(listener -> getServer().getPluginManager().registerEvents(listener, this)); + + Rank.init(); + Profile.init(); + + new BukkitRunnable() { + @Override + public void run() { + for (Profile profile : Profile.getProfiles().values()) { + profile.checkGrants(); + } + } + }.runTaskTimerAsynchronously(this, 20L, 20L); + } + + @Override + public void onDisable() { + try { + jedisPool.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Prints a message and exception to console. If the server is not in debug mode, the messages will be suppressed. + * + * @param level The log level. + * @param message The message. + * @param exception The thrown exception. + */ + public void debug(Level level, String message, Exception exception) { + getLogger().log(level, message); + exception.printStackTrace(); + } + + /** + * Prints a message to console and server operators. + * + * @param message The message. + */ + public void debug(String message) { + if (debug) { + broadcastOps(CC.translate("&e(Debug) &r" + message)); + } + } + + /** + * Prints a message triggered by an action a player performed to console and server operators. + * + * @param player The player that triggered this log. + * @param message The message. + */ + public void debug(Player player, String message) { + if (debug) { + broadcastOps(CC.translate("&e(Debug) &r" + player.getDisplayName() + ": " + message)); + } + } + + /** + * Broadcasts a message to all server operators. + * + * @param message The message. + */ + public static void broadcastOps(String message) { + Bukkit.getOnlinePlayers().stream().filter(Player::isOp).forEach(op -> op.sendMessage(message)); + } + + private void loadMongo() { + if (mainConfig.getBoolean("MONGO.AUTHENTICATION.ENABLED")) { + ServerAddress serverAddress = new ServerAddress(mainConfig.getString("MONGO.HOST"), + mainConfig.getInteger("MONGO.PORT")); + + MongoCredential credential = MongoCredential.createCredential( + mainConfig.getString("MONGO.AUTHENTICATION.USERNAME"), "admin", + mainConfig.getString("MONGO.AUTHENTICATION.PASSWORD").toCharArray()); + + mongoDatabase = new MongoClient(serverAddress, credential, MongoClientOptions.builder().build()) + .getDatabase("zoot"); + } else { + mongoDatabase = new MongoClient(mainConfig.getString("MONGO.HOST"), + mainConfig.getInteger("MONGO.PORT")).getDatabase("zoot"); + } + } + + private void loadRedis() { + jedisPool = new JedisPool(mainConfig.getString("REDIS.HOST"), mainConfig.getInteger("REDIS.PORT")); + + if (mainConfig.getBoolean("REDIS.AUTHENTICATION.ENABLED")) { + try (Jedis jedis = jedisPool.getResource()) { + jedis.auth(mainConfig.getString("REDIS.AUTHENTICATION.PASSWORD")); + } + } + } + + public static Zoot get() { + return zoot; + } + +} diff --git a/src/main/java/com/minexd/zoot/ZootAPI.java b/src/main/java/com/minexd/zoot/ZootAPI.java new file mode 100644 index 0000000..030eac2 --- /dev/null +++ b/src/main/java/com/minexd/zoot/ZootAPI.java @@ -0,0 +1,30 @@ +package com.minexd.zoot; + +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.rank.Rank; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class ZootAPI { + + public static ChatColor getColorOfPlayer(Player player) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + return profile == null ? ChatColor.WHITE : ChatColor.getByChar(profile.getActiveRank().getColor()); + } + + public static String getColoredName(Player player) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + return (profile == null ? ChatColor.WHITE : profile.getActiveRank().getColor()) + player.getName(); + } + + public static Rank getRankOfPlayer(Player player) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + return profile == null ? Rank.getDefaultRank() : profile.getActiveRank(); + } + + public static boolean isInStaffMode(Player player) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + return profile != null && player.hasPermission("zoot.staff") && profile.getStaffOptions().staffModeEnabled(); + } + +} diff --git a/src/main/java/com/minexd/zoot/bootstrap/Bootstrapped.java b/src/main/java/com/minexd/zoot/bootstrap/Bootstrapped.java new file mode 100644 index 0000000..55c3412 --- /dev/null +++ b/src/main/java/com/minexd/zoot/bootstrap/Bootstrapped.java @@ -0,0 +1,15 @@ +package com.minexd.zoot.bootstrap; + +import com.minexd.zoot.Zoot; +import lombok.Getter; + +@Getter +public class Bootstrapped { + + protected final Zoot zoot; + + public Bootstrapped(Zoot zoot) { + this.zoot = zoot; + } + +} diff --git a/src/main/java/com/minexd/zoot/bootstrap/BootstrappedListener.java b/src/main/java/com/minexd/zoot/bootstrap/BootstrappedListener.java new file mode 100644 index 0000000..28fd253 --- /dev/null +++ b/src/main/java/com/minexd/zoot/bootstrap/BootstrappedListener.java @@ -0,0 +1,12 @@ +package com.minexd.zoot.bootstrap; + +import com.minexd.zoot.Zoot; +import org.bukkit.event.Listener; + +public class BootstrappedListener extends Bootstrapped implements Listener { + + public BootstrappedListener(Zoot zoot) { + super(zoot); + } + +} diff --git a/src/main/java/com/minexd/zoot/cache/RedisCache.java b/src/main/java/com/minexd/zoot/cache/RedisCache.java new file mode 100644 index 0000000..96afe63 --- /dev/null +++ b/src/main/java/com/minexd/zoot/cache/RedisCache.java @@ -0,0 +1,114 @@ +package com.minexd.zoot.cache; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.Bootstrapped; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.UUID; +import java.util.logging.Level; +import org.bukkit.Bukkit; +import org.json.simple.parser.ParseException; +import redis.clients.jedis.Jedis; + +public class RedisCache extends Bootstrapped { + + public RedisCache(Zoot zoot) { + super(zoot); + } + + public UUID getUuid(String name) { + if (zoot.getServer().isPrimaryThread()) { + throw new IllegalStateException("Cannot query on main thread (Redis profile cache)"); + } + + try (Jedis jedis = zoot.getJedisPool().getResource()) { + String uuid = jedis.hget("uuid-cache:name-to-uuid", name.toLowerCase()); + + if (uuid != null) { + return UUID.fromString(uuid); + } + } catch (Exception e) { + zoot.debug(Level.WARNING, "Could not connect to redis", e); + } + + try { + UUID uuid = getFromMojang(name); + + if (uuid != null) { + updateNameAndUUID(name, uuid); + return uuid; + } + } catch (Exception e) { + zoot.debug(Level.WARNING, "Could not fetch from Mojang API", e); + } + + return null; + } + + public void updateNameAndUUID(String name, UUID uuid) { + if (Bukkit.isPrimaryThread()) { + throw new IllegalStateException("Cannot query redis on main thread!"); + } + + try (Jedis jedis = zoot.getJedisPool().getResource()) { + jedis.hset("uuid-cache:name-to-uuid", name.toLowerCase(), uuid.toString()); + jedis.hset("uuid-cache:uuid-to-name", uuid.toString(), name); + } + } + + public RedisPlayerData getPlayerData(UUID uuid) { + if (Bukkit.isPrimaryThread()) { + throw new IllegalStateException("Cannot query redis on main thread!"); + } + + try (Jedis jedis = zoot.getJedisPool().getResource()) { + String data = jedis.hget("player-data", uuid.toString()); + + if (data == null) { + return null; + } + + try { + JsonObject dataJson = new JsonParser().parse(data).getAsJsonObject(); + return new RedisPlayerData(dataJson); + } catch (Exception e) { + e.printStackTrace(); + } + } + + return null; + } + + public void updatePlayerData(RedisPlayerData playerData) { + try (Jedis jedis = zoot.getJedisPool().getResource()) { + jedis.hset("player-data", playerData.getUuid().toString(), playerData.getJson().toString()); + } + } + + private static UUID getFromMojang(String name) throws IOException, ParseException { + URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + name); + URLConnection conn = url.openConnection(); + conn.setDoOutput(true); + + BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String line = reader.readLine(); + + if (line == null) { + return null; + } + + String[] id = line.split(","); + + String part = id[0]; + part = part.substring(7, 39); + + return UUID.fromString(String.valueOf(part).replaceAll("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", + "$1-$2-$3-$4-$5")); + } + +} diff --git a/src/main/java/com/minexd/zoot/cache/RedisPlayerData.java b/src/main/java/com/minexd/zoot/cache/RedisPlayerData.java new file mode 100644 index 0000000..18ff225 --- /dev/null +++ b/src/main/java/com/minexd/zoot/cache/RedisPlayerData.java @@ -0,0 +1,50 @@ +package com.minexd.zoot.cache; + +import com.google.gson.JsonObject; +import com.minexd.zoot.util.TimeUtil; +import com.minexd.zoot.util.json.JsonChain; +import java.util.UUID; +import lombok.Data; + +@Data +public class RedisPlayerData { + + private UUID uuid; + private String username; + private LastAction lastAction; + private String lastSeenServer; + private long lastSeenAt; + + public RedisPlayerData(JsonObject object) { + this.uuid = UUID.fromString(object.get("uuid").getAsString()); + this.username = object.get("username").getAsString(); + this.lastAction = LastAction.valueOf(object.get("lastAction").getAsString()); + this.lastSeenServer = object.get("lastSeenServer").getAsString(); + this.lastSeenAt = object.get("lastSeenAt").getAsLong(); + } + + public RedisPlayerData(UUID uuid, String username) { + this.uuid = uuid; + this.username = username; + } + + public JsonObject getJson() { + return new JsonChain() + .addProperty("uuid", uuid.toString()) + .addProperty("username", username) + .addProperty("lastAction", lastAction.name()) + .addProperty("lastSeenServer", lastSeenServer) + .addProperty("lastSeenAt", lastSeenAt) + .get(); + } + + public String getTimeAgo() { + return TimeUtil.millisToRoundedTime(System.currentTimeMillis() - lastSeenAt) + " ago"; + } + + public enum LastAction { + LEAVING_SERVER, + JOINING_SERVER + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/Chat.java b/src/main/java/com/minexd/zoot/chat/Chat.java new file mode 100644 index 0000000..b205301 --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/Chat.java @@ -0,0 +1,80 @@ +package com.minexd.zoot.chat; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.Bootstrapped; +import com.minexd.zoot.chat.filter.ChatFilter; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.punishment.PunishmentType; +import java.util.ArrayList; +import java.util.List; + +import com.minexd.zoot.util.Cooldown; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; + +public class Chat extends Bootstrapped { + + public Chat(Zoot zoot) { + super(zoot); + } + + @Getter @Setter private int delayTime = 3; + @Getter private boolean publicChatMuted = false; + @Getter private boolean publicChatDelayed = false; + @Getter private final List filters = new ArrayList<>(); + @Getter private List filteredPhrases = new ArrayList<>(); + @Getter private List linkWhitelist = new ArrayList<>(); + + public void togglePublicChatMute() { + publicChatMuted = !publicChatMuted; + } + + public void togglePublicChatDelay() { + publicChatDelayed = !publicChatDelayed; + } + + public ChatAttempt attemptChatMessage(Player player, String message) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + + if (profile.getActivePunishmentByType(PunishmentType.MUTE) != null) { + return new ChatAttempt(ChatAttempt.Response.PLAYER_MUTED, profile.getActivePunishmentByType(PunishmentType.MUTE)); + } + + if (publicChatMuted && !player.hasPermission("zoot.staff")) { + return new ChatAttempt(ChatAttempt.Response.CHAT_MUTED); + } + + if (publicChatDelayed && !profile.getChatCooldown().hasExpired() && !player.hasPermission("zoot.staff")) { + ChatAttempt attempt = new ChatAttempt(ChatAttempt.Response.CHAT_DELAYED); + attempt.setValue(profile.getChatCooldown().getRemaining()); + return attempt; + } + + String msg = message.toLowerCase() + .replace("3", "e") + .replace("1", "i") + .replace("!", "i") + .replace("@", "a") + .replace("7", "t") + .replace("0", "o") + .replace("5", "s") + .replace("8", "b") + .replaceAll("\\p{Punct}|\\d", "").trim(); + + String[] words = msg.trim().split(" "); + + for (ChatFilter chatFilter : filters) { + if (chatFilter.isFiltered(msg, words)) { + return new ChatAttempt(ChatAttempt.Response.MESSAGE_FILTERED); + } + } + + if (publicChatDelayed) { + profile.setChatCooldown(new Cooldown(delayTime * 1000L)); + } + + return new ChatAttempt(ChatAttempt.Response.ALLOWED); + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/ChatAttempt.java b/src/main/java/com/minexd/zoot/chat/ChatAttempt.java new file mode 100644 index 0000000..51236db --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/ChatAttempt.java @@ -0,0 +1,39 @@ +package com.minexd.zoot.chat; + +import com.minexd.zoot.chat.filter.ChatFilter; +import com.minexd.zoot.profile.punishment.Punishment; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ChatAttempt { + + private Response response; + private ChatFilter filterFlagged; + private Punishment punishment; + private Object value; + + public ChatAttempt(Response response) { + this.response = response; + } + + public ChatAttempt(Response response, ChatFilter filterFlagged) { + this.response = response; + this.filterFlagged = filterFlagged; + } + + public ChatAttempt(Response response, Punishment punishment) { + this.response = response; + this.punishment = punishment; + } + + public enum Response { + ALLOWED, + MESSAGE_FILTERED, + PLAYER_MUTED, + CHAT_MUTED, + CHAT_DELAYED + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/ChatListener.java b/src/main/java/com/minexd/zoot/chat/ChatListener.java new file mode 100644 index 0000000..ea2a99a --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/ChatListener.java @@ -0,0 +1,63 @@ +package com.minexd.zoot.chat; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.BootstrappedListener; +import com.minexd.zoot.chat.event.ChatAttemptEvent; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.TimeUtil; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +public class ChatListener extends BootstrappedListener { + + public ChatListener(Zoot zoot) { + super(zoot); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onAsyncPlayerChatEvent(AsyncPlayerChatEvent event) { + ChatAttempt chatAttempt = zoot.getChat().attemptChatMessage(event.getPlayer(), event.getMessage()); + ChatAttemptEvent chatAttemptEvent = new ChatAttemptEvent(event.getPlayer(), chatAttempt, event.getMessage()); + + zoot.getServer().getPluginManager().callEvent(chatAttemptEvent); + + if (!chatAttemptEvent.isCancelled()) { + switch (chatAttempt.getResponse()) { + case ALLOWED: { + event.setFormat("%1$s" + CC.RESET + ": %2$s"); + } + break; + case MESSAGE_FILTERED: { + event.setCancelled(true); + chatAttempt.getFilterFlagged().punish(event.getPlayer()); + } + break; + case PLAYER_MUTED: { + event.setCancelled(true); + + if (chatAttempt.getPunishment().isPermanent()) { + event.getPlayer().sendMessage(CC.RED + "You are muted for forever."); + } else { + event.getPlayer().sendMessage(CC.RED + "You are muted for another " + + chatAttempt.getPunishment().getTimeRemaining() + "."); + } + } + break; + case CHAT_MUTED: { + event.setCancelled(true); + event.getPlayer().sendMessage(CC.RED + "The public chat is currently muted."); + } + break; + case CHAT_DELAYED: { + event.setCancelled(true); + event.getPlayer().sendMessage(Locale.CHAT_DELAYED.format( + TimeUtil.millisToSeconds((int) chatAttempt.getValue())) + " seconds"); + } + break; + } + } + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/command/ClearChatCommand.java b/src/main/java/com/minexd/zoot/chat/command/ClearChatCommand.java new file mode 100644 index 0000000..572adb7 --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/command/ClearChatCommand.java @@ -0,0 +1,40 @@ +package com.minexd.zoot.chat.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.profile.Profile; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "clearchat", "cc" }, permission = "zoot.staff.clearchat") +public class ClearChatCommand { + + public void execute(CommandSender sender) { + String[] strings = new String[101]; + + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.hasPermission("zoot.staff")) { + if (Zoot.get().getMainConfig().getBoolean("CHAT.CLEAR_CHAT_FOR_STAFF")) { + player.sendMessage(strings); + } + } else { + player.sendMessage(strings); + } + } + + String senderName; + + if (sender instanceof Player) { + Profile profile = Profile.getProfiles().get(((Player) sender).getUniqueId()); + senderName = profile.getActiveRank().getColor() + sender.getName(); + } else { + senderName = ChatColor.DARK_RED + "Console"; + } + + Bukkit.broadcastMessage(Locale.CLEAR_CHAT_BROADCAST.format(senderName)); + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/command/MuteChatCommand.java b/src/main/java/com/minexd/zoot/chat/command/MuteChatCommand.java new file mode 100644 index 0000000..38deeaf --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/command/MuteChatCommand.java @@ -0,0 +1,32 @@ +package com.minexd.zoot.chat.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.profile.Profile; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = "mutechat", permission = "zoot.staff.mutechat") +public class MuteChatCommand { + + public void execute(CommandSender sender) { + Zoot.get().getChat().togglePublicChatMute(); + + String senderName; + + if (sender instanceof Player) { + Profile profile = Profile.getProfiles().get(((Player) sender).getUniqueId()); + senderName = profile.getActiveRank().getColor() + sender.getName(); + } else { + senderName = ChatColor.DARK_RED + "Console"; + } + + String context = Zoot.get().getChat().isPublicChatMuted() ? "muted" : "unmuted"; + + Bukkit.broadcastMessage(Locale.MUTE_CHAT_BROADCAST.format(context, senderName)); + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/command/SlowChatCommand.java b/src/main/java/com/minexd/zoot/chat/command/SlowChatCommand.java new file mode 100644 index 0000000..980caa6 --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/command/SlowChatCommand.java @@ -0,0 +1,48 @@ +package com.minexd.zoot.chat.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.ZootAPI; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = "slowchat", permission = "zoot.staff.slowchat") +public class SlowChatCommand { + + public void execute(CommandSender sender) { + Zoot.get().getChat().togglePublicChatDelay(); + + String senderName; + + if (sender instanceof Player) { + senderName = ZootAPI.getColoredName((Player) sender); + } else { + senderName = ChatColor.DARK_RED + "Console"; + } + + String context = Zoot.get().getChat().getDelayTime() == 1 ? "" : "s"; + + if (Zoot.get().getChat().isPublicChatDelayed()) { + Bukkit.broadcastMessage(Locale.DELAY_CHAT_ENABLED_BROADCAST.format(senderName, + Zoot.get().getChat().getDelayTime(), context)); + } else { + Bukkit.broadcastMessage(Locale.DELAY_CHAT_DISABLED_BROADCAST.format(senderName)); + } + } + + public void execute(CommandSender sender, Integer seconds) { + if (seconds < 0 || seconds > 60) { + sender.sendMessage(ChatColor.RED + "A delay can only be between 1-60 seconds."); + return; + } + + String context = seconds == 1 ? "" : "s"; + + sender.sendMessage(ChatColor.GREEN + "You have updated the chat delay to " + seconds + " second" + context + "."); + Zoot.get().getChat().setDelayTime(seconds); + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/event/ChatAttemptEvent.java b/src/main/java/com/minexd/zoot/chat/event/ChatAttemptEvent.java new file mode 100644 index 0000000..2b54c34 --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/event/ChatAttemptEvent.java @@ -0,0 +1,25 @@ +package com.minexd.zoot.chat.event; + +import com.minexd.zoot.chat.ChatAttempt; +import com.minexd.zoot.util.BaseEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +@Getter +public class ChatAttemptEvent extends BaseEvent implements Cancellable { + + private final Player player; + private final ChatAttempt chatAttempt; + @Setter private String chatMessage; + @Setter private boolean cancelled; + @Setter private String cancelReason = ""; + + public ChatAttemptEvent(Player player, ChatAttempt chatAttempt, String chatMessage) { + this.player = player; + this.chatAttempt = chatAttempt; + this.chatMessage = chatMessage; + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/filter/ChatFilter.java b/src/main/java/com/minexd/zoot/chat/filter/ChatFilter.java new file mode 100644 index 0000000..1ec5139 --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/filter/ChatFilter.java @@ -0,0 +1,27 @@ +package com.minexd.zoot.chat.filter; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.Bootstrapped; +import org.bukkit.entity.Player; + +public abstract class ChatFilter extends Bootstrapped { + + private String command; + + public ChatFilter(Zoot zoot, String command) { + super(zoot); + + this.command = command; + } + + public abstract boolean isFiltered(String message, String[] words); + + public void punish(Player player) { + if (command != null) { + zoot.getServer().dispatchCommand(zoot.getServer().getConsoleSender(), command + .replace("{player}", player.getName()) + .replace("{player-uuid}", player.getUniqueId().toString())); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/filter/impl/ContainsFilter.java b/src/main/java/com/minexd/zoot/chat/filter/impl/ContainsFilter.java new file mode 100644 index 0000000..550a8f5 --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/filter/impl/ContainsFilter.java @@ -0,0 +1,30 @@ +package com.minexd.zoot.chat.filter.impl; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.chat.filter.ChatFilter; + +public class ContainsFilter extends ChatFilter { + + private final String phrase; + + public ContainsFilter(Zoot zoot, String phrase) { + this(zoot, phrase, null); + } + + public ContainsFilter(Zoot zoot, String phrase, String command) { + super(zoot, command); + this.phrase = phrase; + } + + @Override + public boolean isFiltered(String message, String[] words) { + for (String word : words) { + if (word.contains(this.phrase)) { + return true; + } + } + + return false; + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/filter/impl/LinkFilter.java b/src/main/java/com/minexd/zoot/chat/filter/impl/LinkFilter.java new file mode 100644 index 0000000..9e7fe58 --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/filter/impl/LinkFilter.java @@ -0,0 +1,49 @@ +package com.minexd.zoot.chat.filter.impl; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.chat.filter.ChatFilter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class LinkFilter extends ChatFilter { + + private static final Pattern URL_REGEX = Pattern.compile( + "^(http://www\\.|https://www\\.|http://|https://)?[a-z0-9]+([\\-.][a-z0-9]+)*\\.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?$"); + private static final Pattern IP_REGEX = Pattern.compile( + "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])([.,])){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); + + public LinkFilter(Zoot zoot) { + super(zoot, null); + } + + @Override + public boolean isFiltered(String message, String[] words) { + for (String word : message.replace("(dot)", ".").replace("[dot]", ".").trim().split(" ")) { + boolean continueIt = false; + + for (String phrase : this.zoot.getChat().getLinkWhitelist()) { + if (word.toLowerCase().contains(phrase)) { + continueIt = true; + break; + } + } + + if (!continueIt) { + Matcher matcher = IP_REGEX.matcher(word); + + if (matcher.matches()) { + return true; + } + + matcher = URL_REGEX.matcher(word); + + if (matcher.matches()) { + return true; + } + } + } + + return false; + } + +} diff --git a/src/main/java/com/minexd/zoot/chat/util/ChatComponentBuilder.java b/src/main/java/com/minexd/zoot/chat/util/ChatComponentBuilder.java new file mode 100644 index 0000000..9fbdcda --- /dev/null +++ b/src/main/java/com/minexd/zoot/chat/util/ChatComponentBuilder.java @@ -0,0 +1,219 @@ +package com.minexd.zoot.chat.util; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; + +public class ChatComponentBuilder extends ComponentBuilder { + + private static Field partsField; + private static Field currField; + + static { + try { + currField = ComponentBuilder.class.getDeclaredField("current"); + partsField = ComponentBuilder.class.getDeclaredField("parts"); + + currField.setAccessible(true); + partsField.setAccessible(true); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + } + + public ChatComponentBuilder(String text) { + super(""); + this.parse(text); + } + + public TextComponent getCurrent() { + try { + return (TextComponent) currField.get(this); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return null; + } + + public void setCurrent(TextComponent tc) { + try { + currField.set(this, tc); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + public List getParts() { + try { + return (List) partsField.get(this); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + + return null; + } + + public ChatComponentBuilder setCurrentHoverEvent(HoverEvent hoverEvent) { + this.getCurrent().setHoverEvent(hoverEvent); + + return this; + } + + public ChatComponentBuilder setCurrentClickEvent(ClickEvent clickEvent) { + this.getCurrent().setClickEvent(clickEvent); + + return this; + } + + public ChatComponentBuilder attachToEachPart(HoverEvent hoverEvent) { + for (Object part : getParts()) { + TextComponent component = (TextComponent) part; + + if (component.getHoverEvent() == null) { + component.setHoverEvent(hoverEvent); + } + } + + this.getCurrent().setHoverEvent(hoverEvent); + + return this; + } + + public ChatComponentBuilder attachToEachPart(ClickEvent clickEvent) { + for (Object part : getParts()) { + TextComponent component = (TextComponent) part; + + if (component.getClickEvent() == null) { + component.setClickEvent(clickEvent); + } + } + + this.getCurrent().setClickEvent(clickEvent); + + return this; + } + + public ChatComponentBuilder parse(String text) { + String regex = "[&§]{1}([a-fA-Fl-oL-O0-9-r]){1}"; + text = text.replaceAll(regex, "§$1"); + + if (!Pattern.compile(regex).matcher(text).find()) { + if (getParts().isEmpty() && getCurrent() != null && getCurrent().getText().isEmpty()) { + getCurrent().setText(text); + } else { + this.append(text); + } + + return this; + } + + String[] words = text.split(regex); + int index = words[0].length(); + + for (String word : words) { + try { + if (index != words[0].length()) { + if (getParts().isEmpty() && getCurrent() != null && getCurrent().getText().isEmpty()) { + getCurrent().setText(word); + } else { + this.append(word); + } + + ChatColor color = ChatColor.getByChar(text.charAt(index - 1)); + + if (color == ChatColor.BOLD) { + this.bold(true); + } else if (color == ChatColor.STRIKETHROUGH) { + this.strikethrough(true); + } else if (color == ChatColor.MAGIC) { + this.obfuscated(true); + } else if (color == ChatColor.UNDERLINE) { + this.underlined(true); + } else if (color == ChatColor.RESET) { + this.bold(false); + this.strikethrough(false); + this.obfuscated(false); + this.underlined(false); + } else { + this.color(color); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + index += word.length() + 2; + } + + return this; + } + + public ChatComponentBuilder append(BaseComponent[] components) { + for (BaseComponent component : components) { + append((TextComponent) component); + } + + return this; + } + + public ChatComponentBuilder append(TextComponent textComponent) { + if (textComponent == null) { + return this; + } + + String text = textComponent.getText(); + ChatColor color = textComponent.getColor(); + boolean bold = textComponent.isBold(); + boolean underline = textComponent.isUnderlined(); + boolean italic = textComponent.isUnderlined(); + boolean strike = textComponent.isStrikethrough(); + HoverEvent he = textComponent.getHoverEvent(); + ClickEvent ce = textComponent.getClickEvent(); + + append(text); + color(color); + underlined(underline); + italic(italic); + strikethrough(strike); + event(he); + event(ce); + + if (textComponent.getExtra() != null) { + for (BaseComponent bc : textComponent.getExtra()) { + if (bc instanceof TextComponent) { + append((TextComponent) bc); + } + } + } + + return this; + } + + @Override + public BaseComponent[] create() { + List components = new ArrayList<>(getParts()); + components.add(getCurrent()); + + TextComponent first = components.get(0); + + if (first.getText().isEmpty()) { + components.remove(0); + } + + TextComponent last = components.get(components.size() - 1); + + if (last.getText().isEmpty()) { + components.remove(components.size() - 1); + } + + return components.toArray(new BaseComponent[components.size()]); + } + +} diff --git a/src/main/java/com/minexd/zoot/config/ConfigConversion.java b/src/main/java/com/minexd/zoot/config/ConfigConversion.java new file mode 100644 index 0000000..4257d0e --- /dev/null +++ b/src/main/java/com/minexd/zoot/config/ConfigConversion.java @@ -0,0 +1,10 @@ +package com.minexd.zoot.config; + +import java.io.File; +import org.bukkit.configuration.file.FileConfiguration; + +public interface ConfigConversion { + + void convert(File file, FileConfiguration fileConfiguration); + +} diff --git a/src/main/java/com/minexd/zoot/config/ConfigValidation.java b/src/main/java/com/minexd/zoot/config/ConfigValidation.java new file mode 100644 index 0000000..28e9599 --- /dev/null +++ b/src/main/java/com/minexd/zoot/config/ConfigValidation.java @@ -0,0 +1,36 @@ +package com.minexd.zoot.config; + +import java.io.File; +import org.bukkit.configuration.file.FileConfiguration; + +public class ConfigValidation { + + private final File file; + private final FileConfiguration fileConfiguration; + private final int version; + + public ConfigValidation(File file, FileConfiguration fileConfiguration, int version) { + this.file = file; + this.fileConfiguration = fileConfiguration; + this.version = version; + } + + public void check() { + if (fileConfiguration.contains("CONFIG_VERSION")) { + if (fileConfiguration.getInt("CONFIG_VERSION") != version) { + for (ConfigVersion version : ConfigVersion.values()) { + if (fileConfiguration.getInt("CONFIG_VERSION") < version.getNumber()) { + System.out.println("Converting current configuration into version " + version.name()); + version.getConversion().convert(file, fileConfiguration); + } + } + } + } else { + for (ConfigVersion version : ConfigVersion.values()) { + System.out.println("Converting current configuration into version " + version.name()); + version.getConversion().convert(file, fileConfiguration); + } + } + } + +} diff --git a/src/main/java/com/minexd/zoot/config/ConfigVersion.java b/src/main/java/com/minexd/zoot/config/ConfigVersion.java new file mode 100644 index 0000000..e6a7534 --- /dev/null +++ b/src/main/java/com/minexd/zoot/config/ConfigVersion.java @@ -0,0 +1,20 @@ +package com.minexd.zoot.config; + +import com.minexd.zoot.config.impl.ConfigConversion1; +import com.minexd.zoot.config.impl.ConfigConversion2; +import com.minexd.zoot.config.impl.ConfigConversion3; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum ConfigVersion { + + VERSION_1(1, new ConfigConversion1()), + VERSION_2(2, new ConfigConversion2()), + VERSION_3(3, new ConfigConversion3()); + + private int number; + private ConfigConversion conversion; + +} diff --git a/src/main/java/com/minexd/zoot/config/impl/ConfigConversion1.java b/src/main/java/com/minexd/zoot/config/impl/ConfigConversion1.java new file mode 100644 index 0000000..6bc8cee --- /dev/null +++ b/src/main/java/com/minexd/zoot/config/impl/ConfigConversion1.java @@ -0,0 +1,25 @@ +package com.minexd.zoot.config.impl; + +import com.minexd.zoot.config.ConfigConversion; +import java.io.File; +import java.io.IOException; +import org.bukkit.configuration.file.FileConfiguration; + +public class ConfigConversion1 implements ConfigConversion { + + @Override + public void convert(File file, FileConfiguration fileConfiguration) { + fileConfiguration.set("CONFIG_VERSION", 1); + fileConfiguration.set("CHAT.FORMAT", "%1$s&r: %2$s"); + fileConfiguration.set("CHAT.CLEAR_CHAT_BROADCAST", "&eThe chat has been cleared by &r{0}"); + fileConfiguration.set("CHAT.CLEAR_CHAT_FOR_STAFF", false); + fileConfiguration.set("CHAT.MUTE_CHAT_BROADCAST", "&eThe chat has been {0} by &r{1}"); + + try { + fileConfiguration.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/config/impl/ConfigConversion2.java b/src/main/java/com/minexd/zoot/config/impl/ConfigConversion2.java new file mode 100644 index 0000000..951d142 --- /dev/null +++ b/src/main/java/com/minexd/zoot/config/impl/ConfigConversion2.java @@ -0,0 +1,22 @@ +package com.minexd.zoot.config.impl; + +import com.minexd.zoot.config.ConfigConversion; +import java.io.File; +import java.io.IOException; +import org.bukkit.configuration.file.FileConfiguration; + +public class ConfigConversion2 implements ConfigConversion { + + @Override + public void convert(File file, FileConfiguration fileConfiguration) { + fileConfiguration.set("CONFIG_VERSION", 2); + fileConfiguration.set("SETTINGS.UPDATE_PLAYER_LIST_NAME", true); + + try { + fileConfiguration.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/config/impl/ConfigConversion3.java b/src/main/java/com/minexd/zoot/config/impl/ConfigConversion3.java new file mode 100644 index 0000000..df373b0 --- /dev/null +++ b/src/main/java/com/minexd/zoot/config/impl/ConfigConversion3.java @@ -0,0 +1,30 @@ +package com.minexd.zoot.config.impl; + +import com.minexd.zoot.config.ConfigConversion; +import org.bukkit.configuration.file.FileConfiguration; + +import java.io.File; +import java.io.IOException; + +public class ConfigConversion3 implements ConfigConversion { + + @Override + public void convert(File file, FileConfiguration fileConfiguration) { + fileConfiguration.set("CONFIG_VERSION", 3); + fileConfiguration.set("CONVERSATION.SEND_MESSAGE", "&7(To &r{5}{3}&7) %MSG%"); + fileConfiguration.set("CONVERSATION.RECEIVE_MESSAGE", "&7(From &r{5}{3}&7) %MSG%"); + fileConfiguration.set("OPTIONS.GLOBAL_CHAT_ENABLED", "&eYou &aenabled &eglobal chat."); + fileConfiguration.set("OPTIONS.GLOBAL_CHAT_DISABLED", "&eYou &cdisabled &eglobal chat."); + fileConfiguration.set("OPTIONS.PRIVATE_MESSAGES_ENABLED", "&aYou can now receive new conversations."); + fileConfiguration.set("OPTIONS.PRIVATE_MESSAGES_DISABLED", "&cYou can no longer receive new conversations. If you start a conversation with a player, they will be able to message you back."); + fileConfiguration.set("OPTIONS.PRIVATE_MESSAGE_SOUNDS_ENABLED", "&eYou &aenabled &eprivate message sounds."); + fileConfiguration.set("OPTIONS.PRIVATE_MESSAGE_SOUNDS_DISABLED", "&eYou &cdisabled &eprivate message sounds."); + + try { + fileConfiguration.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/Essentials.java b/src/main/java/com/minexd/zoot/essentials/Essentials.java new file mode 100644 index 0000000..f70d04d --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/Essentials.java @@ -0,0 +1,88 @@ +package com.minexd.zoot.essentials; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.Bootstrapped; +import com.minexd.zoot.essentials.event.SpawnTeleportEvent; +import com.minexd.zoot.util.LocationUtil; +import java.io.IOException; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +public class Essentials extends Bootstrapped { + + private Location spawn; + + public Essentials(Zoot zoot) { + super(zoot); + + spawn = LocationUtil.deserialize(zoot.getMainConfig().getStringOrDefault("ESSENTIAL.SPAWN_LOCATION", null)); + } + + public void setSpawn(Location location) { + spawn = location; + + if (spawn == null) { + zoot.getMainConfig().getConfiguration().set("ESSENTIAL.SPAWN_LOCATION", null); + } else { + zoot.getMainConfig().getConfiguration().set("ESSENTIAL.SPAWN_LOCATION", LocationUtil.serialize(this.spawn)); + } + + try { + zoot.getMainConfig().getConfiguration().save(zoot.getMainConfig().getFile()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void teleportToSpawn(Player player) { + Location location = spawn == null ? zoot.getServer().getWorlds().get(0).getSpawnLocation() : spawn; + + SpawnTeleportEvent event = new SpawnTeleportEvent(player, location); + event.call(); + + if (!event.isCancelled() && event.getLocation() != null) { + player.teleport(event.getLocation()); + } + } + + public int clearEntities(World world) { + int removed = 0; + + for (Entity entity : world.getEntities()) { + if (entity.getType() == EntityType.PLAYER) { + continue; + } + + removed++; + entity.remove(); + } + + return removed; + } + + public int clearEntities(World world, EntityType... excluded) { + int removed = 0; + + entityLoop: + for (Entity entity : world.getEntities()) { + for (EntityType type : excluded) { + if (entity.getType() == EntityType.PLAYER) { + continue entityLoop; + } + + if (entity.getType() == type) { + continue entityLoop; + } + } + + removed++; + entity.remove(); + } + + return removed; + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/EssentialsListener.java b/src/main/java/com/minexd/zoot/essentials/EssentialsListener.java new file mode 100644 index 0000000..10d7eed --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/EssentialsListener.java @@ -0,0 +1,52 @@ +package com.minexd.zoot.essentials; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.BootstrappedListener; +import com.minexd.zoot.util.CC; +import java.util.Arrays; +import java.util.List; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +public class EssentialsListener extends BootstrappedListener { + + private static List BLOCKED_COMMANDS = Arrays.asList( + "//calc", + "//eval", + "//solve", + "/bukkit:", + "/me", + "/bukkit:me", + "/minecraft:", + "/minecraft:me", + "/version", + "/ver" + ); + + public EssentialsListener(Zoot zoot) { + super(zoot); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onCommandProcess(PlayerCommandPreprocessEvent event) { + Player player = event.getPlayer(); + String message = (event.getMessage().startsWith("/") ? "" : "/") + event.getMessage(); + + for (String blockedCommand : BLOCKED_COMMANDS) { + if (message.startsWith(blockedCommand)) { + if (message.equalsIgnoreCase("/version") || message.equalsIgnoreCase("/ver")) { + if (event.getPlayer().isOp()) { + return; + } + } + + player.sendMessage(CC.RED + "You cannot perform this command."); + event.setCancelled(true); + return; + } + } + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/BroadcastCommand.java b/src/main/java/com/minexd/zoot/essentials/command/BroadcastCommand.java new file mode 100644 index 0000000..2b8932e --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/BroadcastCommand.java @@ -0,0 +1,17 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import com.qrakn.honcho.command.CommandOption; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = { "broadcast", "bc" }, options = "r", permission = "zoot.admin.broadcast") +public class BroadcastCommand { + + public void execute(CommandSender sender, CommandOption option, String broadcast) { + String message = broadcast.replaceAll("(&([a-f0-9l-or]))", "\u00A7$2"); + Bukkit.broadcastMessage(CC.translate((option == null ? "&6[Broadcast] &r" : "") + message)); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/ClearCommand.java b/src/main/java/com/minexd/zoot/essentials/command/ClearCommand.java new file mode 100644 index 0000000..251c00c --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/ClearCommand.java @@ -0,0 +1,26 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +@CommandMeta(label = { "clearinv", "clear", "ci" }, permission = "zoot.admin.clearinv") +public class ClearCommand { + + public void execute(Player player) { + player.getInventory().setContents(new ItemStack[36]); + player.getInventory().setArmorContents(new ItemStack[4]); + player.updateInventory(); + player.sendMessage(CC.GOLD + "You cleared your inventory."); + } + + public void execute(CommandSender sender, Player player) { + player.getInventory().setContents(new ItemStack[36]); + player.getInventory().setArmorContents(new ItemStack[4]); + player.updateInventory(); + player.sendMessage(CC.GOLD + "Your inventory has been cleared by " + sender.getName()); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/DayCommand.java b/src/main/java/com/minexd/zoot/essentials/command/DayCommand.java new file mode 100644 index 0000000..2afc0d3 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/DayCommand.java @@ -0,0 +1,15 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "day") +public class DayCommand { + + public void execute(Player player) { + player.setPlayerTime(6000L, false); + player.sendMessage(CC.GREEN + "It's now day time."); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/GameModeCommand.java b/src/main/java/com/minexd/zoot/essentials/command/GameModeCommand.java new file mode 100644 index 0000000..6bf99e5 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/GameModeCommand.java @@ -0,0 +1,40 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.GameMode; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "gamemode", "gm" }, permission = "zoot.admin.gamemode") +public class GameModeCommand { + + public void execute(Player player, GameMode gameMode) { + if (gameMode == null) { + player.sendMessage(CC.RED + "That game mode is not valid."); + return; + } + + player.setGameMode(gameMode); + player.updateInventory(); + player.sendMessage(CC.GOLD + "You updated your game mode."); + } + + public void execute(CommandSender sender, Player target, GameMode gameMode) { + if (target == null) { + sender.sendMessage(Locale.PLAYER_NOT_FOUND.format()); + return; + } + + if (gameMode == null) { + sender.sendMessage(CC.RED + "That game mode is not valid."); + return; + } + + target.setGameMode(gameMode); + target.updateInventory(); + target.sendMessage(CC.GOLD + "Your game mode has been updated by " + sender.getName()); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/HealCommand.java b/src/main/java/com/minexd/zoot/essentials/command/HealCommand.java new file mode 100644 index 0000000..b3ac120 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/HealCommand.java @@ -0,0 +1,33 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = "heal", permission = "zoot.admin.heal") +public class HealCommand { + + public void execute(Player player) { + player.setHealth(20.0); + player.setFoodLevel(20); + player.setSaturation(5.0F); + player.updateInventory(); + player.sendMessage(CC.GOLD + "You healed yourself."); + } + + public void execute(CommandSender sender, Player player) { + if (player == null) { + sender.sendMessage(Locale.PLAYER_NOT_FOUND.format()); + return; + } + + player.setHealth(20.0); + player.setFoodLevel(20); + player.setSaturation(5.0F); + player.updateInventory(); + player.sendMessage(CC.GOLD + "You have been healed by " + sender.getName()); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/HidePlayerCommand.java b/src/main/java/com/minexd/zoot/essentials/command/HidePlayerCommand.java new file mode 100644 index 0000000..de00d91 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/HidePlayerCommand.java @@ -0,0 +1,13 @@ +package com.minexd.zoot.essentials.command; + +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "hideplayer", permission = "zoot.admin.hideplayer") +public class HidePlayerCommand { + + public void execute(Player player, Player target) { + player.hidePlayer(target); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/ListCommand.java b/src/main/java/com/minexd/zoot/essentials/command/ListCommand.java new file mode 100644 index 0000000..8fa2077 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/ListCommand.java @@ -0,0 +1,53 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.ZootAPI; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.rank.Rank; +import com.qrakn.honcho.command.CommandMeta; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.util.*; + +@CommandMeta(label = "list") +public class ListCommand { + + public void executue(Player sender) { + List sortedPlayers = new ArrayList<>(Bukkit.getOnlinePlayers()); + sortedPlayers.sort(new Comparator() { + @Override + public int compare(Player o1, Player o2) { + Profile p1 = Profile.getByUuid(o1.getUniqueId()); + Profile p2 = Profile.getByUuid(o2.getUniqueId()); + return p2.getActiveRank().getWeight() - p1.getActiveRank().getWeight(); + } + }); + + List playerNames = new ArrayList<>(); + + for (Player player : sortedPlayers) { + playerNames.add(ZootAPI.getColoredName(player)); + } + + List sortedRanks = new ArrayList<>(Rank.getRanks().values()); + sortedRanks.sort(new Comparator() { + @Override + public int compare(Rank o1, Rank o2) { + return o2.getWeight() - o1.getWeight(); + } + }); + + List rankNames = new ArrayList<>(); + + for (Rank rank : sortedRanks) { + rankNames.add(rank.getColor() + rank.getDisplayName()); + } + + sender.sendMessage(StringUtils.join(rankNames, ChatColor.WHITE + ", ")); + sender.sendMessage("(" + Bukkit.getOnlinePlayers().size() + "/" + Bukkit.getMaxPlayers() + "): " + + StringUtils.join(playerNames, ChatColor.WHITE + ", ")); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/LocationCommand.java b/src/main/java/com/minexd/zoot/essentials/command/LocationCommand.java new file mode 100644 index 0000000..3530624 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/LocationCommand.java @@ -0,0 +1,15 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.util.LocationUtil; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "loc", permission = "zoot.admin.loc") +public class LocationCommand { + + public void execute(Player player) { + player.sendMessage(LocationUtil.serialize(player.getLocation())); + System.out.println(LocationUtil.serialize(player.getLocation())); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/MoreCommand.java b/src/main/java/com/minexd/zoot/essentials/command/MoreCommand.java new file mode 100644 index 0000000..b9507d6 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/MoreCommand.java @@ -0,0 +1,21 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "more", permission = "zoot.admin.more") +public class MoreCommand { + + public void execute(Player player) { + if (player.getItemInHand() == null) { + player.sendMessage(CC.RED + "There is nothing in your hand."); + return; + } + + player.getItemInHand().setAmount(64); + player.updateInventory(); + player.sendMessage(CC.GREEN + "You gave yourself more of the item in your hand."); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/NightCommand.java b/src/main/java/com/minexd/zoot/essentials/command/NightCommand.java new file mode 100644 index 0000000..34cd428 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/NightCommand.java @@ -0,0 +1,15 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "night") +public class NightCommand { + + public void execute(Player player) { + player.setPlayerTime(18000L, false); + player.sendMessage(CC.GREEN + "It's now night time."); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/PingCommand.java b/src/main/java/com/minexd/zoot/essentials/command/PingCommand.java new file mode 100644 index 0000000..3029c3d --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/PingCommand.java @@ -0,0 +1,37 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.ZootAPI; +import com.minexd.zoot.util.BukkitReflection; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "ping") +public class PingCommand { + + public void execute(Player player) { + player.sendMessage(CC.YELLOW + "Your Ping: " + colorPing(BukkitReflection.getPing(player))); + } + + public void execute(Player player, Player target) { + if (target == null) { + player.sendMessage(CC.RED + "A player with that name could not be found."); + } else { + player.sendMessage(ZootAPI.getColoredName(target) + CC.YELLOW + "'s Ping: " + + colorPing(BukkitReflection.getPing(target))); + } + } + + private String colorPing(int ping) { + if (ping <= 40) { + return CC.GREEN + ping; + } else if (ping <= 70) { + return CC.YELLOW + ping; + } else if (ping <= 100) { + return CC.GOLD + ping; + } else { + return CC.RED + ping; + } + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/RenameCommand.java b/src/main/java/com/minexd/zoot/essentials/command/RenameCommand.java new file mode 100644 index 0000000..f8b0c5f --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/RenameCommand.java @@ -0,0 +1,26 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +@CommandMeta(label = "rename", permission = "zoot.staff.rename") +public class RenameCommand { + + public void execute(Player player, String name) { + if (player.getItemInHand() != null) { + ItemStack itemStack = player.getItemInHand(); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(CC.translate(name)); + itemStack.setItemMeta(itemMeta); + + player.updateInventory(); + player.sendMessage(CC.GREEN + "You renamed the item in your hand."); + } else { + player.sendMessage(CC.RED + "There is nothing in your hand."); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/SetSlotsCommand.java b/src/main/java/com/minexd/zoot/essentials/command/SetSlotsCommand.java new file mode 100644 index 0000000..93684a0 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/SetSlotsCommand.java @@ -0,0 +1,17 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.util.BukkitReflection; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "setslots", async = true, permission = "zoot.admin.setslots") +public class SetSlotsCommand { + + public void execute(CommandSender sender, int slots) { + BukkitReflection.setMaxPlayers(Zoot.get().getServer(), slots); + sender.sendMessage(CC.GOLD + "You set the max slots to " + slots + "."); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/SetSpawnCommand.java b/src/main/java/com/minexd/zoot/essentials/command/SetSpawnCommand.java new file mode 100644 index 0000000..7f58840 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/SetSpawnCommand.java @@ -0,0 +1,16 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "setspawn", permission = "zoot.admin.setspawn") +public class SetSpawnCommand { + + public void execute(Player player) { + Zoot.get().getEssentials().setSpawn(player.getLocation()); + player.sendMessage(CC.GREEN + "You updated this world's spawn."); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/ShowPlayerCommand.java b/src/main/java/com/minexd/zoot/essentials/command/ShowPlayerCommand.java new file mode 100644 index 0000000..88f7861 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/ShowPlayerCommand.java @@ -0,0 +1,13 @@ +package com.minexd.zoot.essentials.command; + +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "showplayer", permission = "zoot.admin.showplayer") +public class ShowPlayerCommand { + + public void execute(Player player, Player target) { + player.showPlayer(target); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/SpawnCommand.java b/src/main/java/com/minexd/zoot/essentials/command/SpawnCommand.java new file mode 100644 index 0000000..a3f3ec7 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/SpawnCommand.java @@ -0,0 +1,16 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "spawn", permission = "zoot.staff.spawn") +public class SpawnCommand { + + public void execute(Player player) { + Zoot.get().getEssentials().teleportToSpawn(player); + player.sendMessage(CC.GREEN + "You teleported to this world's spawn."); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/SunsetCommand.java b/src/main/java/com/minexd/zoot/essentials/command/SunsetCommand.java new file mode 100644 index 0000000..7f98868 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/SunsetCommand.java @@ -0,0 +1,15 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "sunset") +public class SunsetCommand { + + public void execute(Player player) { + player.setPlayerTime(12000, false); + player.sendMessage(CC.GREEN + "It's now sunset."); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/TeleportWorldCommand.java b/src/main/java/com/minexd/zoot/essentials/command/TeleportWorldCommand.java new file mode 100644 index 0000000..66e9f85 --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/TeleportWorldCommand.java @@ -0,0 +1,29 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.entity.Player; + +@CommandMeta(label = "tpworld", permission = "zoot.admin.tpworld") +public class TeleportWorldCommand { + + public void execute(Player player, String worldName) { + World world = Bukkit.getWorld(worldName); + + if (world == null) { + world = Bukkit.createWorld(new WorldCreator(worldName)); + player.sendMessage(CC.GOLD + "Generating new world \"" + worldName + "\""); + } + + if (world == null) { + player.sendMessage(CC.RED + "A world with that name does not exist."); + } else { + player.teleport(world.getSpawnLocation()); + player.sendMessage(CC.GOLD + "Teleported you to " + world.getName()); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/command/ZootDebugCommand.java b/src/main/java/com/minexd/zoot/essentials/command/ZootDebugCommand.java new file mode 100644 index 0000000..4591bce --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/command/ZootDebugCommand.java @@ -0,0 +1,15 @@ +package com.minexd.zoot.essentials.command; + +import com.minexd.zoot.Zoot; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "zoot debug", permission = "zoot.admin") +public class ZootDebugCommand { + + public void execute(CommandSender sender) { + Zoot.get().setDebug(!Zoot.get().isDebug()); + sender.sendMessage("Debug: " + Zoot.get().isDebug()); + } + +} diff --git a/src/main/java/com/minexd/zoot/essentials/event/SpawnTeleportEvent.java b/src/main/java/com/minexd/zoot/essentials/event/SpawnTeleportEvent.java new file mode 100644 index 0000000..12c9a5f --- /dev/null +++ b/src/main/java/com/minexd/zoot/essentials/event/SpawnTeleportEvent.java @@ -0,0 +1,21 @@ +package com.minexd.zoot.essentials.event; + +import com.minexd.zoot.util.BaseEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +public class SpawnTeleportEvent extends BaseEvent implements Cancellable { + + @Getter private final Player player; + @Getter @Setter private Location location; + @Getter @Setter private boolean cancelled; + + public SpawnTeleportEvent(Player player, Location location) { + this.player = player; + this.location = location; + } + +} diff --git a/src/main/java/com/minexd/zoot/network/NetworkPacketListener.java b/src/main/java/com/minexd/zoot/network/NetworkPacketListener.java new file mode 100644 index 0000000..eae4bc5 --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/NetworkPacketListener.java @@ -0,0 +1,150 @@ +package com.minexd.zoot.network; + +import com.minexd.zoot.pidgin.packet.handler.IncomingPacketHandler; +import com.minexd.zoot.pidgin.packet.listener.PacketListener; +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.event.ReceiveStaffChatEvent; +import com.minexd.zoot.network.packet.PacketAddGrant; +import com.minexd.zoot.network.packet.PacketBroadcastPunishment; +import com.minexd.zoot.network.packet.PacketDeleteGrant; +import com.minexd.zoot.network.packet.PacketDeleteRank; +import com.minexd.zoot.network.packet.PacketRefreshRank; +import com.minexd.zoot.network.packet.PacketStaffChat; +import com.minexd.zoot.network.packet.PacketStaffJoinNetwork; +import com.minexd.zoot.network.packet.PacketStaffLeaveNetwork; +import com.minexd.zoot.network.packet.PacketStaffSwitchServer; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.grant.Grant; +import com.minexd.zoot.profile.grant.event.GrantAppliedEvent; +import com.minexd.zoot.profile.grant.event.GrantExpireEvent; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.rank.Rank; +import java.util.Objects; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class NetworkPacketListener implements PacketListener { + + private Zoot zoot; + + public NetworkPacketListener(Zoot zoot) { + this.zoot = zoot; + } + + @IncomingPacketHandler + public void onAddGrant(PacketAddGrant packet) { + Player player = Bukkit.getPlayer(packet.getPlayerUuid()); + Grant grant = packet.getGrant(); + + if (player != null) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + profile.getGrants().removeIf(other -> Objects.equals(other, grant)); + profile.getGrants().add(grant); + + new GrantAppliedEvent(player, grant); + } + } + + @IncomingPacketHandler + public void onDeleteGrant(PacketDeleteGrant packet) { + Player player = Bukkit.getPlayer(packet.getPlayerUuid()); + Grant grant = packet.getGrant(); + + if (player != null) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + profile.getGrants().removeIf(other -> Objects.equals(other, grant)); + profile.getGrants().add(grant); + + new GrantExpireEvent(player, grant); + } + } + + @IncomingPacketHandler + public void onBroadcastPunishment(PacketBroadcastPunishment packet) { + Punishment punishment = packet.getPunishment(); + punishment.broadcast(packet.getStaff(), packet.getTarget(), packet.isSilent()); + + Player player = Bukkit.getPlayer(packet.getTargetUuid()); + + if (player != null) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + profile.getPunishments().removeIf(other -> Objects.equals(other, punishment)); + profile.getPunishments().add(punishment); + + if (punishment.getType().isBan()) { + new BukkitRunnable() { + @Override + public void run() { + player.kickPlayer(punishment.getKickMessage()); + } + }.runTask(Zoot.get()); + } + } + } + + @IncomingPacketHandler + public void onRankRefresh(PacketRefreshRank packet) { + Rank rank = Rank.getRankByUuid(packet.getUuid()); + + if (rank == null) { + rank = new Rank(packet.getUuid(), packet.getName()); + } + + rank.load(); + + Zoot.broadcastOps(Locale.NETWORK_RANK_REFRESHED.format(Locale.NETWORK_BROADCAST_PREFIX.format(), + rank.getDisplayName())); + } + + @IncomingPacketHandler + public void onRankDelete(PacketDeleteRank packet) { + Rank rank = Rank.getRanks().remove(packet.getUuid()); + + if (rank != null) { + Zoot.broadcastOps(Locale.NETWORK_RANK_DELETED.format(Locale.NETWORK_BROADCAST_PREFIX.format(), + rank.getDisplayName())); + } + } + + @IncomingPacketHandler + public void onStaffChat(PacketStaffChat packet) { + zoot.getServer().getOnlinePlayers().stream() + .filter(onlinePlayer -> onlinePlayer.hasPermission("zoot.staff")) + .forEach(onlinePlayer -> { + ReceiveStaffChatEvent event = new ReceiveStaffChatEvent(onlinePlayer); + + zoot.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + Profile profile = Profile.getProfiles().get(event.getPlayer().getUniqueId()); + + if (profile != null && profile.getStaffOptions().staffModeEnabled()) { + onlinePlayer.sendMessage(Locale.STAFF_CHAT.format(Locale.STAFF_BROADCAST_PREFIX.format(), + packet.getPlayerName(), packet.getServerName(), packet.getChatMessage() + )); + } + } + }); + } + + @IncomingPacketHandler + public void onStaffJoinNetwork(PacketStaffJoinNetwork packet) { + zoot.getServer().broadcast(Locale.STAFF_JOIN_NETWORK.format(Locale.STAFF_BROADCAST_PREFIX.format(), + packet.getPlayerName(), packet.getServerName()), "zoot.staff"); + } + + @IncomingPacketHandler + public void onStaffLeaveNetwork(PacketStaffLeaveNetwork packet) { + zoot.getServer().broadcast(Locale.STAFF_LEAVE_NETWORK.format(Locale.STAFF_BROADCAST_PREFIX.format(), + packet.getPlayerName()), "zoot.staff"); + } + + @IncomingPacketHandler + public void onStaffSwitchServer(PacketStaffSwitchServer packet) { + zoot.getServer().broadcast(Locale.STAFF_SWITCH_SERVER.format(Locale.STAFF_BROADCAST_PREFIX.format(), + packet.getPlayerName(), packet.getToServerName(), packet.getFromServerName()), "zoot.staff"); + } + +} diff --git a/src/main/java/com/minexd/zoot/network/event/ReceiveStaffChatEvent.java b/src/main/java/com/minexd/zoot/network/event/ReceiveStaffChatEvent.java new file mode 100644 index 0000000..8c72f8f --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/event/ReceiveStaffChatEvent.java @@ -0,0 +1,18 @@ +package com.minexd.zoot.network.event; + +import com.minexd.zoot.util.BaseEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +public class ReceiveStaffChatEvent extends BaseEvent implements Cancellable { + + @Getter private Player player; + @Getter @Setter private boolean cancelled; + + public ReceiveStaffChatEvent(Player player) { + this.player = player; + } + +} diff --git a/src/main/java/com/minexd/zoot/network/packet/PacketAddGrant.java b/src/main/java/com/minexd/zoot/network/packet/PacketAddGrant.java new file mode 100644 index 0000000..f146a69 --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/packet/PacketAddGrant.java @@ -0,0 +1,43 @@ +package com.minexd.zoot.network.packet; + +import com.google.gson.JsonObject; +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.profile.grant.Grant; +import com.minexd.zoot.util.json.JsonChain; +import java.util.UUID; +import lombok.Getter; + +public class PacketAddGrant implements Packet { + + @Getter private UUID playerUuid; + @Getter private Grant grant; + + public PacketAddGrant() { + + } + + public PacketAddGrant(UUID playerUuid, Grant grant) { + this.playerUuid = playerUuid; + this.grant = grant; + } + + @Override + public int id() { + return 1; + } + + @Override + public JsonObject serialize() { + return new JsonChain() + .addProperty("playerUuid", playerUuid.toString()) + .add("grant", Grant.SERIALIZER.serialize(grant)) + .get(); + } + + @Override + public void deserialize(JsonObject jsonObject) { + playerUuid = UUID.fromString(jsonObject.get("playerUuid").getAsString()); + grant = Grant.DESERIALIZER.deserialize(jsonObject.get("grant").getAsJsonObject()); + } + +} diff --git a/src/main/java/com/minexd/zoot/network/packet/PacketBroadcastPunishment.java b/src/main/java/com/minexd/zoot/network/packet/PacketBroadcastPunishment.java new file mode 100644 index 0000000..3af5ffa --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/packet/PacketBroadcastPunishment.java @@ -0,0 +1,55 @@ +package com.minexd.zoot.network.packet; + +import com.google.gson.JsonObject; +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.util.json.JsonChain; +import java.util.UUID; +import lombok.Getter; + +public class PacketBroadcastPunishment implements Packet { + + @Getter private Punishment punishment; + @Getter private String staff; + @Getter private String target; + @Getter private UUID targetUuid; + @Getter private boolean silent; + + public PacketBroadcastPunishment() { + + } + + public PacketBroadcastPunishment(Punishment punishment, String staff, String target, UUID targetUuid, boolean silent) { + this.punishment = punishment; + this.staff = staff; + this.target = target; + this.targetUuid = targetUuid; + this.silent = silent; + } + + @Override + public int id() { + return 2; + } + + @Override + public JsonObject serialize() { + return new JsonChain() + .add("punishment", Punishment.SERIALIZER.serialize(punishment)) + .addProperty("staff", staff) + .addProperty("target", target) + .addProperty("targetUuid", targetUuid.toString()) + .addProperty("silent", silent) + .get(); + } + + @Override + public void deserialize(JsonObject object) { + punishment = Punishment.DESERIALIZER.deserialize(object.get("punishment").getAsJsonObject()); + staff = object.get("staff").getAsString(); + target = object.get("target").getAsString(); + targetUuid = UUID.fromString(object.get("targetUuid").getAsString()); + silent = object.get("silent").getAsBoolean(); + } + +} diff --git a/src/main/java/com/minexd/zoot/network/packet/PacketDeleteGrant.java b/src/main/java/com/minexd/zoot/network/packet/PacketDeleteGrant.java new file mode 100644 index 0000000..b2c6e3f --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/packet/PacketDeleteGrant.java @@ -0,0 +1,43 @@ +package com.minexd.zoot.network.packet; + +import com.google.gson.JsonObject; +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.profile.grant.Grant; +import com.minexd.zoot.util.json.JsonChain; +import java.util.UUID; +import lombok.Getter; + +public class PacketDeleteGrant implements Packet { + + @Getter private UUID playerUuid; + @Getter private Grant grant; + + public PacketDeleteGrant() { + + } + + public PacketDeleteGrant(UUID playerUuid, Grant grant) { + this.playerUuid = playerUuid; + this.grant = grant; + } + + @Override + public int id() { + return 3; + } + + @Override + public JsonObject serialize() { + return new JsonChain() + .addProperty("playerUuid", playerUuid.toString()) + .add("grant", Grant.SERIALIZER.serialize(grant)) + .get(); + } + + @Override + public void deserialize(JsonObject jsonObject) { + playerUuid = UUID.fromString(jsonObject.get("playerUuid").getAsString()); + grant = Grant.DESERIALIZER.deserialize(jsonObject.get("grant").getAsJsonObject()); + } + +} diff --git a/src/main/java/com/minexd/zoot/network/packet/PacketDeleteRank.java b/src/main/java/com/minexd/zoot/network/packet/PacketDeleteRank.java new file mode 100644 index 0000000..dca47a4 --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/packet/PacketDeleteRank.java @@ -0,0 +1,37 @@ +package com.minexd.zoot.network.packet; + +import com.google.gson.JsonObject; +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.util.json.JsonChain; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class PacketDeleteRank implements Packet { + + private UUID uuid; + + public PacketDeleteRank() { + + } + + @Override + public int id() { + return 4; + } + + @Override + public JsonObject serialize() { + return new JsonChain() + .addProperty("uuid", uuid.toString()) + .get(); + } + + @Override + public void deserialize(JsonObject jsonObject) { + uuid = UUID.fromString(jsonObject.get("uuid").getAsString()); + } + +} \ No newline at end of file diff --git a/src/main/java/com/minexd/zoot/network/packet/PacketRefreshRank.java b/src/main/java/com/minexd/zoot/network/packet/PacketRefreshRank.java new file mode 100644 index 0000000..5af7f87 --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/packet/PacketRefreshRank.java @@ -0,0 +1,40 @@ +package com.minexd.zoot.network.packet; + +import com.google.gson.JsonObject; +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.util.json.JsonChain; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class PacketRefreshRank implements Packet { + + private UUID uuid; + private String name; + + public PacketRefreshRank() { + + } + + @Override + public int id() { + return 5; + } + + @Override + public JsonObject serialize() { + return new JsonChain() + .addProperty("uuid", uuid.toString()) + .addProperty("name", name) + .get(); + } + + @Override + public void deserialize(JsonObject jsonObject) { + uuid = UUID.fromString(jsonObject.get("uuid").getAsString()); + name = jsonObject.get("name").getAsString(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/minexd/zoot/network/packet/PacketStaffChat.java b/src/main/java/com/minexd/zoot/network/packet/PacketStaffChat.java new file mode 100644 index 0000000..5a49b50 --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/packet/PacketStaffChat.java @@ -0,0 +1,48 @@ +package com.minexd.zoot.network.packet; + +import com.google.gson.JsonObject; + +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.util.json.JsonChain; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PacketStaffChat implements Packet { + + private String playerName; + private String serverName; + private String chatMessage; + + public PacketStaffChat() { + + } + + public PacketStaffChat(String playerName, String serverName, String chatMessage) { + this.playerName = playerName; + this.serverName = serverName; + this.chatMessage = chatMessage; + } + + public int id() { + return 6; + } + + @Override + public JsonObject serialize() { + return new JsonChain() + .addProperty("playerName", playerName) + .addProperty("serverName", serverName) + .addProperty("chatMessage", chatMessage) + .get(); + } + + @Override + public void deserialize(JsonObject jsonObject) { + playerName = jsonObject.get("playerName").getAsString(); + serverName = jsonObject.get("serverName").getAsString(); + chatMessage = jsonObject.get("chatMessage").getAsString(); + } + +} diff --git a/src/main/java/com/minexd/zoot/network/packet/PacketStaffJoinNetwork.java b/src/main/java/com/minexd/zoot/network/packet/PacketStaffJoinNetwork.java new file mode 100644 index 0000000..696d02c --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/packet/PacketStaffJoinNetwork.java @@ -0,0 +1,42 @@ +package com.minexd.zoot.network.packet; + +import com.google.gson.JsonObject; +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.util.json.JsonChain; +import lombok.Getter; + +@Getter +public class PacketStaffJoinNetwork implements Packet { + + private String playerName; + private String serverName; + + public PacketStaffJoinNetwork() { + + } + + public PacketStaffJoinNetwork(String playerName, String serverName) { + this.playerName = playerName; + this.serverName = serverName; + } + + @Override + public int id() { + return 7; + } + + @Override + public JsonObject serialize() { + return new JsonChain() + .addProperty("playerName", playerName) + .addProperty("serverName", serverName) + .get(); + } + + @Override + public void deserialize(JsonObject jsonObject) { + playerName = jsonObject.get("playerName").getAsString(); + serverName = jsonObject.get("serverName").getAsString(); + } + +} diff --git a/src/main/java/com/minexd/zoot/network/packet/PacketStaffLeaveNetwork.java b/src/main/java/com/minexd/zoot/network/packet/PacketStaffLeaveNetwork.java new file mode 100644 index 0000000..c90a473 --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/packet/PacketStaffLeaveNetwork.java @@ -0,0 +1,42 @@ +package com.minexd.zoot.network.packet; + +import com.google.gson.JsonObject; +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.util.json.JsonChain; +import lombok.Getter; + +@Getter +public class PacketStaffLeaveNetwork implements Packet { + + private String playerName; + private String serverName; + + public PacketStaffLeaveNetwork() { + + } + + public PacketStaffLeaveNetwork(String playerName, String serverName) { + this.playerName = playerName; + this.serverName = serverName; + } + + @Override + public int id() { + return 8; + } + + @Override + public JsonObject serialize() { + return new JsonChain() + .addProperty("playerName", playerName) + .addProperty("serverName", serverName) + .get(); + } + + @Override + public void deserialize(JsonObject jsonObject) { + playerName = jsonObject.get("playerName").getAsString(); + serverName = jsonObject.get("serverName").getAsString(); + } + +} diff --git a/src/main/java/com/minexd/zoot/network/packet/PacketStaffSwitchServer.java b/src/main/java/com/minexd/zoot/network/packet/PacketStaffSwitchServer.java new file mode 100644 index 0000000..c1ad414 --- /dev/null +++ b/src/main/java/com/minexd/zoot/network/packet/PacketStaffSwitchServer.java @@ -0,0 +1,46 @@ +package com.minexd.zoot.network.packet; + +import com.google.gson.JsonObject; +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.util.json.JsonChain; +import lombok.Getter; + +@Getter +public class PacketStaffSwitchServer implements Packet { + + private String playerName; + private String fromServerName; + private String toServerName; + + public PacketStaffSwitchServer() { + + } + + public PacketStaffSwitchServer(String playerName, String fromServerName, String toServerName) { + this.playerName = playerName; + this.fromServerName = fromServerName; + this.toServerName = toServerName; + } + + @Override + public int id() { + return 9; + } + + @Override + public JsonObject serialize() { + return new JsonChain() + .addProperty("playerName", playerName) + .addProperty("fromServerName", fromServerName) + .addProperty("toServerName", toServerName) + .get(); + } + + @Override + public void deserialize(JsonObject jsonObject) { + playerName = jsonObject.get("playerName").getAsString(); + fromServerName = jsonObject.get("fromServerName").getAsString(); + toServerName = jsonObject.get("toServerName").getAsString(); + } + +} diff --git a/src/main/java/com/minexd/zoot/pidgin/Pidgin.java b/src/main/java/com/minexd/zoot/pidgin/Pidgin.java new file mode 100644 index 0000000..ce63302 --- /dev/null +++ b/src/main/java/com/minexd/zoot/pidgin/Pidgin.java @@ -0,0 +1,184 @@ +package com.minexd.zoot.pidgin; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.pidgin.packet.Packet; +import com.minexd.zoot.pidgin.packet.handler.IncomingPacketHandler; +import com.minexd.zoot.pidgin.packet.handler.PacketExceptionHandler; +import com.minexd.zoot.pidgin.packet.listener.PacketListener; +import com.minexd.zoot.pidgin.packet.listener.PacketListenerData; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPubSub; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ForkJoinPool; + +public class Pidgin { + + private static JsonParser PARSER = new JsonParser(); + + private final String channel; + private JedisPool jedisPool; + private JedisPubSub jedisPubSub; + private List packetListeners = new ArrayList<>(); + private Map idToType = new HashMap<>(); + private Map typeToId = new HashMap<>(); + + public Pidgin(String channel, String host, int port, String password) { + this.channel = channel; + this.packetListeners = new ArrayList<>(); + + this.jedisPool = new JedisPool(host, port); + + if (password != null && !password.equals("")) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.auth(password); + System.out.println("[Pidgin] Authenticating.."); + } + } + + this.setupPubSub(); + } + + public void sendPacket(Packet packet) { + sendPacket(packet, null); + } + + public void sendPacket(Packet packet, PacketExceptionHandler exceptionHandler) { + try { + + final JsonObject object = packet.serialize(); + + if (object == null) { + throw new IllegalStateException("Packet cannot generate null serialized data"); + } + + try (Jedis jedis = this.jedisPool.getResource()) { + + System.out.println("[Pidgin] Attempting to publish packet.."); + + try { + + if (Zoot.get().getMainConfig().getBoolean("REDIS.AUTHENTICATION.ENABLED")) { + jedis.auth(Zoot.get().getMainConfig().getString("REDIS.AUTHENTICATION.PASSWORD")); + } + + jedis.publish(this.channel, packet.id() + ";" + object.toString()); + System.out.println("[Pidgin] Successfully published packet.."); + + } catch (Exception ex) { + System.out.println("[Pidgin] Failed to publish packet.."); + ex.printStackTrace(); + } + + } + } catch (Exception e) { + if (exceptionHandler != null) { + exceptionHandler.onException(e); + } + } + + } + + public Packet buildPacket(int id) { + if (!idToType.containsKey(id)) { + throw new IllegalStateException("A packet with that ID does not exist"); + } + + try { + return (Packet) idToType.get(id).newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + + throw new IllegalStateException("Could not create new instance of packet type"); + } + + public void registerPacket(Class clazz) { + try { + int id = (int) clazz.getDeclaredMethod("id").invoke(clazz.newInstance(), null); + + if (idToType.containsKey(id) || typeToId.containsKey(clazz)) { + throw new IllegalStateException("A packet with that ID has already been registered"); + } + + idToType.put(id, clazz); + typeToId.put(clazz, id); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void registerListener(PacketListener packetListener) { + methodLoop: + for (Method method : packetListener.getClass().getDeclaredMethods()) { + if (method.getDeclaredAnnotation(IncomingPacketHandler.class) != null) { + Class packetClass = null; + + if (method.getParameters().length > 0) { + if (Packet.class.isAssignableFrom(method.getParameters()[0].getType())) { + packetClass = method.getParameters()[0].getType(); + } + } + + if (packetClass != null) { + this.packetListeners.add(new PacketListenerData(packetListener, method, packetClass)); + } + } + } + } + + private void setupPubSub() { + System.out.println("[Pidgin] Setting up PubSup.."); + + this.jedisPubSub = new JedisPubSub() { + + @Override + public void onMessage(String channel, String message) { + + if (channel.equalsIgnoreCase(Pidgin.this.channel)) { + + try { + + String[] args = message.split(";"); + + Integer id = Integer.valueOf(args[0]); + + Packet packet = buildPacket(id); + + if (packet != null) { + packet.deserialize(PARSER.parse(args[1]).getAsJsonObject()); + + for (PacketListenerData data : packetListeners) { + if (data.matches(packet)) { + data.getMethod().invoke(data.getInstance(), packet); + } + } + } + } catch (Exception e) { + System.out.println("[Pidgin] Failed to handle message"); + e.printStackTrace(); + } + } + } + + }; + + ForkJoinPool.commonPool().execute(() -> { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.subscribe(this.jedisPubSub, channel); + System.out.println("[Pidgin] Successfully subscribing to channel.."); + } catch (Exception exception) { + System.out.println("[Pidgin] Failed to subscribe to channel.."); + exception.printStackTrace(); + } + }); + } + +} diff --git a/src/main/java/com/minexd/zoot/pidgin/packet/Packet.java b/src/main/java/com/minexd/zoot/pidgin/packet/Packet.java new file mode 100644 index 0000000..32f3682 --- /dev/null +++ b/src/main/java/com/minexd/zoot/pidgin/packet/Packet.java @@ -0,0 +1,13 @@ +package com.minexd.zoot.pidgin.packet; + +import com.google.gson.JsonObject; + +public interface Packet { + + int id(); + + JsonObject serialize(); + + void deserialize(JsonObject object); + +} diff --git a/src/main/java/com/minexd/zoot/pidgin/packet/handler/IncomingPacketHandler.java b/src/main/java/com/minexd/zoot/pidgin/packet/handler/IncomingPacketHandler.java new file mode 100644 index 0000000..103cb70 --- /dev/null +++ b/src/main/java/com/minexd/zoot/pidgin/packet/handler/IncomingPacketHandler.java @@ -0,0 +1,17 @@ +package com.minexd.zoot.pidgin.packet.handler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Identifies a method and packet type assigned to the method. + * The only valid parameter types for a method that is annotated + * by this annotation are String and Packet. + */ +@Target({ ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface IncomingPacketHandler { + +} diff --git a/src/main/java/com/minexd/zoot/pidgin/packet/handler/PacketExceptionHandler.java b/src/main/java/com/minexd/zoot/pidgin/packet/handler/PacketExceptionHandler.java new file mode 100644 index 0000000..183bbfb --- /dev/null +++ b/src/main/java/com/minexd/zoot/pidgin/packet/handler/PacketExceptionHandler.java @@ -0,0 +1,10 @@ +package com.minexd.zoot.pidgin.packet.handler; + +public class PacketExceptionHandler { + + public void onException(Exception e) { + System.out.println("Failed to send packet"); + e.printStackTrace(); + } + +} diff --git a/src/main/java/com/minexd/zoot/pidgin/packet/listener/PacketListener.java b/src/main/java/com/minexd/zoot/pidgin/packet/listener/PacketListener.java new file mode 100644 index 0000000..6132294 --- /dev/null +++ b/src/main/java/com/minexd/zoot/pidgin/packet/listener/PacketListener.java @@ -0,0 +1,5 @@ +package com.minexd.zoot.pidgin.packet.listener; + +public interface PacketListener { + +} diff --git a/src/main/java/com/minexd/zoot/pidgin/packet/listener/PacketListenerData.java b/src/main/java/com/minexd/zoot/pidgin/packet/listener/PacketListenerData.java new file mode 100644 index 0000000..db8f053 --- /dev/null +++ b/src/main/java/com/minexd/zoot/pidgin/packet/listener/PacketListenerData.java @@ -0,0 +1,26 @@ +package com.minexd.zoot.pidgin.packet.listener; + +import java.lang.reflect.Method; + +import com.minexd.zoot.pidgin.packet.Packet; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * A wrapper class that holds all the information needed to + * identify and execute a message function. + * + */ +@AllArgsConstructor +@Getter +public class PacketListenerData { + + private Object instance; + private Method method; + private Class packetClass; + + public boolean matches(Packet packet) { + return this.packetClass == packet.getClass(); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/Profile.java b/src/main/java/com/minexd/zoot/profile/Profile.java new file mode 100644 index 0000000..6692f68 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/Profile.java @@ -0,0 +1,330 @@ +package com.minexd.zoot.profile; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.ZootAPI; +import com.minexd.zoot.profile.conversation.ProfileConversations; +import com.minexd.zoot.profile.grant.event.GrantAppliedEvent; +import com.minexd.zoot.profile.grant.event.GrantExpireEvent; +import com.minexd.zoot.profile.option.ProfileOptions; +import com.minexd.zoot.profile.staff.ProfileStaffOptions; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.profile.grant.Grant; +import com.minexd.zoot.profile.punishment.PunishmentType; +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.Cooldown; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoCursor; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.ReplaceOptions; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +import org.bson.Document; +import org.bson.conversions.Bson; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; + +public class Profile { + + @Getter private static Map profiles = new HashMap<>(); + private static MongoCollection collection; + + @Getter @Setter private String username; + @Getter private final UUID uuid; + @Getter @Setter private Long firstSeen; + @Getter @Setter private Long lastSeen; + @Getter @Setter private String currentAddress; + @Getter private List ipAddresses; + @Getter private final List knownAlts; + @Getter private final ProfileOptions options; + @Getter private final ProfileStaffOptions staffOptions; + @Getter private final ProfileConversations conversations; + @Getter private Grant activeGrant; + @Getter private final List grants; + @Getter private final List punishments; + @Getter @Setter private boolean loaded; + @Getter @Setter private Cooldown chatCooldown; + + public Profile(String username, UUID uuid) { + this.username = username; + this.uuid = uuid; + this.grants = new ArrayList<>(); + this.punishments = new ArrayList<>(); + this.ipAddresses = new ArrayList<>(); + this.knownAlts = new ArrayList<>(); + this.options = new ProfileOptions(); + this.staffOptions = new ProfileStaffOptions(); + this.conversations = new ProfileConversations(this); + this.chatCooldown = new Cooldown(0); + + load(); + } + + public Player getPlayer() { + return Bukkit.getPlayer(uuid); + } + + public String getColoredUsername() { + return activeGrant.getRank().getColor() + username; + } + + public Punishment getActivePunishmentByType(PunishmentType type) { + for (Punishment punishment : punishments) { + if (punishment.getType() == type && !punishment.isRemoved() && !punishment.hasExpired()) { + return punishment; + } + } + + return null; + } + + public int getPunishmentCountByType(PunishmentType type) { + int i = 0; + + for (Punishment punishment : punishments) { + if (punishment.getType() == type) i++; + } + + return i; + } + + public Rank getActiveRank() { + return activeGrant.getRank(); + } + + public void activateNextGrant() { + List grants = new ArrayList<>(this.grants); + + grants.sort(Comparator.comparingInt(grant -> grant.getRank().getWeight())); + Collections.reverse(grants); + + for (Grant grant : grants) { + if (!grant.isRemoved() && !grant.hasExpired()) { + if (!grant.equals(activeGrant)) { + Zoot.get().debug(""); + activeGrant = grant; + setupBukkitPlayer(getPlayer()); + return; + } + } + } + } + + public void checkGrants() { + Player player = getPlayer(); + + for (Grant grant : grants) { + if (!grant.isRemoved() && grant.hasExpired()) { + grant.setRemovedAt(System.currentTimeMillis()); + grant.setRemovedReason("Grant expired"); + grant.setRemoved(true); + + if (player != null) { + new GrantExpireEvent(player, grant).call(); + } + + if (grant.equals(activeGrant)) { + activateNextGrant(); + } + } + } + + if (activeGrant == null) { + Grant defaultGrant = new Grant(UUID.randomUUID(), Rank.getDefaultRank(), null, + System.currentTimeMillis(), "Default", Integer.MAX_VALUE); + + grants.add(defaultGrant); + activeGrant = defaultGrant; + + if (player != null) { + new GrantAppliedEvent(player, defaultGrant).call(); + } + } + } + + public void setupBukkitPlayer(Player player) { + if (player == null) { + return; + } + + for (PermissionAttachmentInfo attachmentInfo : player.getEffectivePermissions()) { + if (attachmentInfo.getAttachment() == null) { + continue; + } + + attachmentInfo.getAttachment().getPermissions().forEach((permission, value) -> { + attachmentInfo.getAttachment().unsetPermission(permission); + }); + } + + PermissionAttachment attachment = player.addAttachment(Zoot.get()); + + for (String perm : activeGrant.getRank().getAllPermissions()) { + attachment.setPermission(perm, true); + } + + player.recalculatePermissions(); + + String displayName = activeGrant.getRank().getPrefix() + player.getName() + activeGrant.getRank().getSuffix(); + String coloredName = ZootAPI.getColoredName(player); + + player.setDisplayName(displayName); + + if (Zoot.get().getMainConfig().getBoolean("SETTINGS.UPDATE_PLAYER_LIST_NAME")) { + player.setPlayerListName(coloredName); + } + } + + public void load() { + Document document = collection.find(Filters.eq("uuid", uuid.toString())).first(); + + if (document != null) { + if (username == null) { + username = document.getString("username"); + } + + firstSeen = document.getLong("firstSeen"); + lastSeen = document.getLong("lastSeen"); + currentAddress = document.getString("currentAddress"); + ipAddresses = Zoot.GSON.fromJson(document.getString("ipAddresses"), Zoot.LIST_STRING_TYPE); + + Document optionsDocument = (Document) document.get("options"); + options.publicChatEnabled(optionsDocument.getBoolean("publicChatEnabled")); + options.receivingNewConversations(optionsDocument.getBoolean("receivingNewConversations")); + options.playingMessageSounds(optionsDocument.getBoolean("playingMessageSounds")); + + JsonArray grantList = new JsonParser().parse(document.getString("grants")).getAsJsonArray(); + + for (JsonElement grantData : grantList) { + // Transform into a Grant object + Grant grant = Grant.DESERIALIZER.deserialize(grantData.getAsJsonObject()); + + if (grant != null) { + this.grants.add(grant); + } + } + + JsonArray punishmentList = new JsonParser().parse(document.getString("punishments")).getAsJsonArray(); + + for (JsonElement punishmentData : punishmentList) { + // Transform into a Grant object + Punishment punishment = Punishment.DESERIALIZER.deserialize(punishmentData.getAsJsonObject()); + + if (punishment != null) { + this.punishments.add(punishment); + } + } + } + + // Update active grants + activateNextGrant(); + checkGrants(); + + // Set loaded to true + loaded = true; + } + + public void save() { + Document document = new Document(); + document.put("username", username); + document.put("uuid", uuid.toString()); + document.put("firstSeen", firstSeen); + document.put("lastSeen", lastSeen); + document.put("currentAddress", currentAddress); + document.put("ipAddresses", Zoot.GSON.toJson(ipAddresses, Zoot.LIST_STRING_TYPE)); + + Document optionsDocument = new Document(); + optionsDocument.put("publicChatEnabled", options.publicChatEnabled()); + optionsDocument.put("receivingNewConversations", options.receivingNewConversations()); + optionsDocument.put("playingMessageSounds", options.playingMessageSounds()); + document.put("options", optionsDocument); + + JsonArray grantList = new JsonArray(); + + for (Grant grant : this.grants) { + grantList.add(Grant.SERIALIZER.serialize(grant)); + } + + document.put("grants", grantList.toString()); + + JsonArray punishmentList = new JsonArray(); + + for (Punishment punishment : this.punishments) { + punishmentList.add(Punishment.SERIALIZER.serialize(punishment)); + } + + document.put("punishments", punishmentList.toString()); + + collection.replaceOne(Filters.eq("uuid", uuid.toString()), document, new ReplaceOptions().upsert(true)); + } + + public static void init() { + collection = Zoot.get().getMongoDatabase().getCollection("profiles"); + } + + public static Profile getByUuid(UUID uuid) { + if (profiles.containsKey(uuid)) { + return profiles.get(uuid); + } + + return new Profile(null, uuid); + } + + public static Profile getByUsername(String username) { + Player player = Bukkit.getPlayer(username); + + if (player != null) { + return profiles.get(player.getUniqueId()); + } + + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(username); + + if (offlinePlayer.hasPlayedBefore()) { + if (profiles.containsKey(offlinePlayer.getUniqueId())) { + return profiles.get(offlinePlayer.getUniqueId()); + } + + return new Profile(offlinePlayer.getName(), offlinePlayer.getUniqueId()); + } + + UUID uuid = Zoot.get().getRedisCache().getUuid(username); + + if (uuid != null) { + if (profiles.containsKey(uuid)) { + return profiles.get(uuid); + } + + return new Profile(username, uuid); + } + + return null; + } + + public static List getByIpAddress(String ipAddress) { + List profiles = new ArrayList<>(); + Bson filter = Filters.eq("currentAddress", ipAddress); + + try (MongoCursor cursor = collection.find(filter).iterator()) { + while (cursor.hasNext()) { + Document document = cursor.next(); + profiles.add(new Profile(document.getString("username"), + UUID.fromString(document.getString("uuid")))); + } + } + + return profiles; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/ProfileListener.java b/src/main/java/com/minexd/zoot/profile/ProfileListener.java new file mode 100644 index 0000000..eb3fb88 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/ProfileListener.java @@ -0,0 +1,171 @@ +package com.minexd.zoot.profile; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.BootstrappedListener; +import com.minexd.zoot.cache.RedisPlayerData; +import com.minexd.zoot.network.packet.PacketStaffChat; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.profile.punishment.PunishmentType; +import com.minexd.zoot.util.CC; +import java.util.List; +import java.util.logging.Level; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.scheduler.BukkitRunnable; + +public class ProfileListener extends BootstrappedListener { + + public ProfileListener(Zoot zoot) { + super(zoot); + } + + @EventHandler + public void onAsyncPlayerPreLogin(AsyncPlayerPreLoginEvent event) { + Player player = Bukkit.getPlayer(event.getUniqueId()); + + // Need to check if player is still logged in when receiving another login attempt + // This happens when a player using a custom client can access the server list while in-game (and reconnecting) + if (player != null && player.isOnline()) { + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + event.setKickMessage(CC.RED + "You tried to login too quickly after disconnecting.\nTry again in a few seconds."); + zoot.getServer().getScheduler().runTask(zoot, () -> player.kickPlayer(CC.RED + "Duplicate login kick")); + return; + } + + Profile profile = null; + + try { + profile = new Profile(event.getName(), event.getUniqueId()); + + if (!profile.isLoaded()) { + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + event.setKickMessage(Locale.FAILED_TO_LOAD_PROFILE.format()); + return; + } + + if (profile.getActivePunishmentByType(PunishmentType.BAN) != null) { + handleBan(event, profile.getActivePunishmentByType(PunishmentType.BAN)); + return; + } + + profile.setUsername(event.getName()); + + if (profile.getFirstSeen() == null) { + profile.setFirstSeen(System.currentTimeMillis()); + } + + profile.setLastSeen(System.currentTimeMillis()); + + if (profile.getCurrentAddress() == null) { + profile.setCurrentAddress(event.getAddress().getHostAddress()); + } + + if (!profile.getIpAddresses().contains(event.getAddress().getHostAddress())) { + profile.getIpAddresses().add(event.getAddress().getHostAddress()); + } + + if (!profile.getCurrentAddress().equals(event.getAddress().getHostAddress())) { + List alts = Profile.getByIpAddress(event.getAddress().getHostAddress()); + + for (Profile alt : alts) { + if (alt.getActivePunishmentByType(PunishmentType.BAN) != null) { + handleBan(event, alt.getActivePunishmentByType(PunishmentType.BAN)); + return; + } + } + } + + profile.save(); + } catch (Exception e) { + e.printStackTrace(); + zoot.debug(Level.SEVERE, "Failed to load profile for " + event.getName(), e); + } + + if (profile == null || !profile.isLoaded()) { + event.setKickMessage(Locale.FAILED_TO_LOAD_PROFILE.format()); + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + return; + } + + Profile.getProfiles().put(profile.getUuid(), profile); + + RedisPlayerData playerData = new RedisPlayerData(event.getUniqueId(), event.getName()); + playerData.setLastAction(RedisPlayerData.LastAction.JOINING_SERVER); + playerData.setLastSeenServer(zoot.getMainConfig().getString("SERVER_NAME")); + playerData.setLastSeenAt(System.currentTimeMillis()); + + zoot.getRedisCache().updatePlayerData(playerData); + zoot.getRedisCache().updateNameAndUUID(event.getName(), event.getUniqueId()); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + profile.setupBukkitPlayer(player); + + for (String perm : profile.getActiveGrant().getRank().getAllPermissions()) { + zoot.debug(player, perm); + } + + if (player.hasPermission("zoot.staff")) { + player.sendMessage(CC.GOLD + "Your staff mode is currently: " + + (profile.getStaffOptions().staffModeEnabled() ? CC.GREEN + "Enabled" : CC.RED + "Disabled")); + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + Profile profile = Profile.getProfiles().remove(event.getPlayer().getUniqueId()); + profile.setLastSeen(System.currentTimeMillis()); + + if (profile.isLoaded()) { + new BukkitRunnable() { + @Override + public void run() { + try { + profile.save(); + } catch (Exception e) { + zoot.debug(Level.SEVERE, "Failed to save profile " + event.getPlayer().getName(), e); + } + } + }.runTaskAsynchronously(Zoot.get()); + } + + RedisPlayerData playerData = new RedisPlayerData(event.getPlayer().getUniqueId(), event.getPlayer().getName()); + playerData.setLastAction(RedisPlayerData.LastAction.LEAVING_SERVER); + playerData.setLastSeenServer(zoot.getMainConfig().getString("SERVER_NAME")); + playerData.setLastSeenAt(System.currentTimeMillis()); + + zoot.getRedisCache().updatePlayerData(playerData); + } + + @EventHandler(priority = EventPriority.LOW) + public void onAsyncPlayerChatEvent(AsyncPlayerChatEvent event) { + Profile profile = Profile.getByUuid(event.getPlayer().getUniqueId()); + + if (profile.getStaffOptions().staffChatModeEnabled()) { + if (profile.getStaffOptions().staffModeEnabled()) { + Zoot.get().getPidgin().sendPacket(new PacketStaffChat(event.getPlayer().getDisplayName(), + Zoot.get().getMainConfig().getString("SERVER_NAME"), event.getMessage())); + } else { + event.getPlayer().sendMessage(CC.RED + "You must enable staff mode or disable staff chat mode."); + } + + event.setCancelled(true); + } + } + + private void handleBan(AsyncPlayerPreLoginEvent event, Punishment punishment) { + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + event.setKickMessage(punishment.getKickMessage()); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/ProfileTypeAdapter.java b/src/main/java/com/minexd/zoot/profile/ProfileTypeAdapter.java new file mode 100644 index 0000000..cc4371f --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/ProfileTypeAdapter.java @@ -0,0 +1,28 @@ +package com.minexd.zoot.profile; + +import com.qrakn.honcho.command.adapter.CommandTypeAdapter; +import java.util.ArrayList; +import java.util.List; + +public class ProfileTypeAdapter implements CommandTypeAdapter { + + public T convert(String string, Class type) { + return type.cast(Profile.getByUsername(string)); + } + + @Override + public List tabComplete(String string, Class type) { + List completed = new ArrayList<>(); + + for (Profile profile : Profile.getProfiles().values()) { + if (profile.getUsername() == null) continue; + + if (profile.getUsername().toLowerCase().startsWith(string.toLowerCase())) { + completed.add(profile.getUsername()); + } + } + + return completed; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/conversation/Conversation.java b/src/main/java/com/minexd/zoot/profile/conversation/Conversation.java new file mode 100644 index 0000000..d7a88ce --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/conversation/Conversation.java @@ -0,0 +1,90 @@ +package com.minexd.zoot.profile.conversation; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.ZootAPI; +import com.minexd.zoot.profile.Profile; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class Conversation { + + @Getter private final UUID initiatedBy; + @Getter private final UUID target; + @Getter private long lastMessageSentAt; + @Getter private UUID lastMessageSentBy; + + public Conversation(UUID initiatedBy, UUID target) { + this.initiatedBy = initiatedBy; + this.target = target; + this.lastMessageSentAt = System.currentTimeMillis(); + + Profile initiatorProfile = Profile.getByUuid(initiatedBy); + initiatorProfile.getConversations().getConversations().put(target, this); + + Profile targetProfile = Profile.getByUuid(target); + targetProfile.getConversations().getConversations().put(initiatedBy, this); + } + + public void sendMessage(Player sender, Player target, String message) { + sender.sendMessage(Locale.CONVERSATION_SEND_MESSAGE.format( + sender.getName(), sender.getDisplayName(), ZootAPI.getColorOfPlayer(sender), + target.getName(), target.getDisplayName(), ZootAPI.getColorOfPlayer(target)) + .replace("%MSG%", message)); + + Profile targetProfile = Profile.getByUuid(target.getUniqueId()); + + if (targetProfile.getOptions().playingMessageSounds()) { + target.playSound(target.getLocation(), Sound.SUCCESSFUL_HIT, 1.0F, 1.0F); + } + + target.sendMessage(Locale.CONVERSATION_RECEIVE_MESSAGE.format( + target.getName(), target.getDisplayName(), ZootAPI.getColorOfPlayer(target), + sender.getName(), sender.getDisplayName(), ZootAPI.getColorOfPlayer(sender)) + .replace("%MSG%", message)); + + lastMessageSentAt = System.currentTimeMillis(); + lastMessageSentBy = sender.getUniqueId(); + } + + public boolean validate() { + Player initiator = Bukkit.getPlayer(initiatedBy); + + if (initiator == null || !initiator.isOnline()) { + destroy(); + return false; + } + + Player target = Bukkit.getPlayer(this.target); + + if (target == null || !target.isOnline()) { + destroy(); + return false; + } + + return true; + } + + public void destroy() { + for (Player player : new Player[] { Bukkit.getPlayer(initiatedBy), Bukkit.getPlayer(target) }) { + if (player != null && player.isOnline()) { + Profile profile = Profile.getByUuid(player.getUniqueId()); + profile.getConversations().getConversations().remove(getPartner(player.getUniqueId())); + } + } + } + + public UUID getPartner(UUID compareWith) { + if (initiatedBy.equals(compareWith)) { + return target; + } else if (target.equals(compareWith)) { + return initiatedBy; + } + + return null; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/conversation/ProfileConversations.java b/src/main/java/com/minexd/zoot/profile/conversation/ProfileConversations.java new file mode 100644 index 0000000..d79f81f --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/conversation/ProfileConversations.java @@ -0,0 +1,61 @@ +package com.minexd.zoot.profile.conversation; + +import com.minexd.zoot.profile.Profile; + +import java.util.*; +import java.util.stream.Collectors; + +import lombok.Getter; +import org.bukkit.entity.Player; + +public class ProfileConversations { + + @Getter private final Profile profile; + @Getter private Map conversations; + + public ProfileConversations(Profile profile) { + this.profile = profile; + this.conversations = new HashMap<>(); + } + + public boolean canBeMessagedBy(Player player) { + if (!profile.getOptions().receivingNewConversations()) { + return conversations.containsKey(player.getUniqueId()); + } + + return true; + } + + public Conversation getOrCreateConversation(Player target) { + Player sender = profile.getPlayer(); + + if (sender != null) { + Conversation conversation = conversations.get(target.getUniqueId()); + + if (conversation == null) { + conversation = new Conversation(profile.getUuid(), target.getUniqueId()); + } + + return conversation; + } + + return null; + } + + public Conversation getLastRepliedConversation() { + List list = conversations + .values() + .stream() + .sorted(Comparator.comparingLong(Conversation::getLastMessageSentAt)) + .collect(Collectors.toList()); + + Collections.reverse(list); + + return list.isEmpty() ? null : list.get(0); + } + + public void expireAllConversations() { + this.conversations.clear(); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/conversation/command/MessageCommand.java b/src/main/java/com/minexd/zoot/profile/conversation/command/MessageCommand.java new file mode 100644 index 0000000..6c9bf10 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/conversation/command/MessageCommand.java @@ -0,0 +1,39 @@ +package com.minexd.zoot.profile.conversation.command; + +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.conversation.Conversation; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "message", "msg", "whisper", "tell", "t" }) +public class MessageCommand { + + public void execute(Player player, Player target, String message) { + if (player.equals(target)) { + player.sendMessage(CC.RED + "You cannot message yourself!"); + return; + } + + if (target == null) { + player.sendMessage(CC.RED + "A player with that name could not be found."); + return; + } + + Profile playerProfile = Profile.getByUuid(player.getUniqueId()); + Profile targetProfile = Profile.getByUuid(target.getUniqueId()); + + if (targetProfile.getConversations().canBeMessagedBy(player)) { + Conversation conversation = playerProfile.getConversations().getOrCreateConversation(target); + + if (conversation.validate()) { + conversation.sendMessage(player, target, message); + } else { + player.sendMessage(CC.RED + "That player is not receiving new conversations right now."); + } + } else { + player.sendMessage(CC.RED + "That player is not receiving new conversations right now."); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/conversation/command/ReplyCommand.java b/src/main/java/com/minexd/zoot/profile/conversation/command/ReplyCommand.java new file mode 100644 index 0000000..f6aee42 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/conversation/command/ReplyCommand.java @@ -0,0 +1,28 @@ +package com.minexd.zoot.profile.conversation.command; + +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.conversation.Conversation; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "reply", "r" }) +public class ReplyCommand { + + public void execute(Player player, String message) { + Profile playerProfile = Profile.getByUuid(player.getUniqueId()); + Conversation conversation = playerProfile.getConversations().getLastRepliedConversation(); + + if (conversation != null) { + if (conversation.validate()) { + conversation.sendMessage(player, Bukkit.getPlayer(conversation.getPartner(player.getUniqueId())), message); + } else { + player.sendMessage(CC.RED + "You can no longer reply to that player."); + } + } else { + player.sendMessage(CC.RED + "You have nobody to reply to."); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/Grant.java b/src/main/java/com/minexd/zoot/profile/grant/Grant.java new file mode 100644 index 0000000..775fcac --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/Grant.java @@ -0,0 +1,68 @@ +package com.minexd.zoot.profile.grant; + +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.TimeUtil; +import java.util.Date; +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; + +public class Grant { + + public static GrantJsonSerializer SERIALIZER = new GrantJsonSerializer(); + public static GrantJsonDeserializer DESERIALIZER = new GrantJsonDeserializer(); + + @Getter private final UUID uuid; + @Getter private final Rank rank; + @Getter @Setter private UUID addedBy; + @Getter private final long addedAt; + @Getter private final String addedReason; + @Getter private final long duration; + @Getter @Setter private UUID removedBy; + @Getter @Setter private long removedAt; + @Getter @Setter private String removedReason; + @Getter @Setter private boolean removed; + + public Grant(UUID uuid, Rank rank, UUID addedBy, long addedAt, String addedReason, long duration) { + this.uuid = uuid; + this.rank = rank; + this.addedBy = addedBy; + this.addedAt = addedAt; + this.addedReason = addedReason; + this.duration = duration; + } + + public boolean isPermanent() { + return duration == Integer.MAX_VALUE; + } + + public boolean hasExpired() { + return (!isPermanent()) && (System.currentTimeMillis() >= addedAt + duration); + } + + public String getExpiresAtDate() { + if (duration == Integer.MAX_VALUE) { + return "Never"; + } + + return TimeUtil.dateToString(new Date(addedAt + duration), "&7"); + } + + public String getDurationText() { + if (removed) { + return "Removed"; + } + + if (isPermanent()) { + return "Permanent"; + } + + return TimeUtil.millisToRoundedTime(duration); + } + + @Override + public boolean equals(Object object) { + return object instanceof Grant && ((Grant) object).uuid.equals(uuid); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/GrantJsonDeserializer.java b/src/main/java/com/minexd/zoot/profile/grant/GrantJsonDeserializer.java new file mode 100644 index 0000000..da24be3 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/GrantJsonDeserializer.java @@ -0,0 +1,50 @@ +package com.minexd.zoot.profile.grant; + +import com.google.gson.JsonObject; +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.json.JsonDeserializer; +import java.util.UUID; + +public class GrantJsonDeserializer implements JsonDeserializer { + + @Override + public Grant deserialize(JsonObject object) { + Rank rank = Rank.getRankByUuid(UUID.fromString(object.get("rank").getAsString())); + + if (rank == null) { + return null; + } + + Grant grant = new Grant( + UUID.fromString(object.get("uuid").getAsString()), + rank, + null, + object.get("addedAt").getAsLong(), + object.get("addedReason").getAsString(), + object.get("duration").getAsLong() + ); + + if (!object.get("addedBy").isJsonNull()) { + grant.setAddedBy(UUID.fromString(object.get("addedBy").getAsString())); + } + + if (!object.get("removedBy").isJsonNull()) { + grant.setRemovedBy(UUID.fromString(object.get("removedBy").getAsString())); + } + + if (!object.get("removedAt").isJsonNull()) { + grant.setRemovedAt(object.get("removedAt").getAsLong()); + } + + if (!object.get("removedReason").isJsonNull()) { + grant.setRemovedReason(object.get("removedReason").getAsString()); + } + + if (!object.get("removed").isJsonNull()) { + grant.setRemoved(object.get("removed").getAsBoolean()); + } + + return grant; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/GrantJsonSerializer.java b/src/main/java/com/minexd/zoot/profile/grant/GrantJsonSerializer.java new file mode 100644 index 0000000..5a11f55 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/GrantJsonSerializer.java @@ -0,0 +1,24 @@ +package com.minexd.zoot.profile.grant; + +import com.google.gson.JsonObject; +import com.minexd.zoot.util.json.JsonSerializer; + +public class GrantJsonSerializer implements JsonSerializer { + + @Override + public JsonObject serialize(Grant grant) { + JsonObject object = new JsonObject(); + object.addProperty("uuid", grant.getUuid().toString()); + object.addProperty("rank", grant.getRank().getUuid().toString()); + object.addProperty("addedBy", grant.getAddedBy() == null ? null : grant.getAddedBy().toString()); + object.addProperty("addedAt", grant.getAddedAt()); + object.addProperty("addedReason", grant.getAddedReason()); + object.addProperty("duration", grant.getDuration()); + object.addProperty("removedBy", grant.getRemovedBy() == null ? null : grant.getRemovedBy().toString()); + object.addProperty("removedAt", grant.getRemovedAt()); + object.addProperty("removedReason", grant.getRemovedReason()); + object.addProperty("removed", grant.isRemoved()); + return object; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/GrantListener.java b/src/main/java/com/minexd/zoot/profile/grant/GrantListener.java new file mode 100644 index 0000000..5ab99e9 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/GrantListener.java @@ -0,0 +1,103 @@ +package com.minexd.zoot.profile.grant; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.BootstrappedListener; +import com.minexd.zoot.network.packet.PacketDeleteGrant; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.grant.event.GrantAppliedEvent; +import com.minexd.zoot.profile.grant.event.GrantExpireEvent; +import com.minexd.zoot.profile.grant.procedure.GrantProcedure; +import com.minexd.zoot.profile.grant.procedure.GrantProcedureStage; +import com.minexd.zoot.profile.grant.procedure.GrantProcedureType; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.TimeUtil; +import com.minexd.zoot.util.callback.TypeCallback; +import com.minexd.zoot.util.menu.menus.ConfirmMenu; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +public class GrantListener extends BootstrappedListener { + + public GrantListener(Zoot zoot) { + super(zoot); + } + + @EventHandler + public void onGrantAppliedEvent(GrantAppliedEvent event) { + Player player = event.getPlayer(); + Grant grant = event.getGrant(); + + player.sendMessage(CC.GREEN + ("A `{rank}` grant has been applied to you for {time-remaining}.") + .replace("{rank}", grant.getRank().getDisplayName()) + .replace("{time-remaining}", grant.getDuration() == Integer.MAX_VALUE ? + "forever" : TimeUtil.millisToRoundedTime((grant.getAddedAt() + grant.getDuration()) - + System.currentTimeMillis()))); + + Profile profile = Profile.getByUuid(player.getUniqueId()); + profile.setupBukkitPlayer(player); + } + + @EventHandler + public void onGrantExpireEvent(GrantExpireEvent event) { + Player player = event.getPlayer(); + Grant grant = event.getGrant(); + + player.sendMessage(CC.RED + ("Your `{rank}` grant has expired.") + .replace("{rank}", grant.getRank().getDisplayName())); + + Profile profile = Profile.getByUuid(player.getUniqueId()); + profile.setupBukkitPlayer(player); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onAsyncPlayerChatEvent(AsyncPlayerChatEvent event) { + if (!event.getPlayer().hasPermission("zoot.staff.grant")) { + return; + } + + GrantProcedure procedure = GrantProcedure.getByPlayer(event.getPlayer()); + + if (procedure != null && procedure.getStage() == GrantProcedureStage.REQUIRE_TEXT) { + event.setCancelled(true); + + if (event.getMessage().equalsIgnoreCase("cancel")) { + GrantProcedure.getProcedures().remove(procedure); + event.getPlayer().sendMessage(CC.RED + "You have cancelled the grant procedure."); + return; + } + + if (procedure.getType() == GrantProcedureType.REMOVE) { + new ConfirmMenu(CC.YELLOW + "Delete this grant?", new TypeCallback() { + @Override + public void callback(Boolean data) { + if (data) { + procedure.getGrant().setRemovedBy(event.getPlayer().getUniqueId()); + procedure.getGrant().setRemovedAt(System.currentTimeMillis()); + procedure.getGrant().setRemovedReason(event.getMessage()); + procedure.getGrant().setRemoved(true); + procedure.finish(); + event.getPlayer().sendMessage(CC.GREEN + "The grant has been removed."); + + Zoot.get().getPidgin().sendPacket(new PacketDeleteGrant(procedure.getRecipient().getUuid(), + procedure.getGrant())); + } else { + procedure.cancel(); + event.getPlayer().sendMessage(CC.RED + "You did not confirm to remove the grant."); + } + } + }, true) { + @Override + public void onClose(Player player) { + if (!isClosedByMenu()) { + procedure.cancel(); + event.getPlayer().sendMessage(CC.RED + "You did not confirm to remove the grant."); + } + } + }.openMenu(event.getPlayer()); + } + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/command/GrantCommand.java b/src/main/java/com/minexd/zoot/profile/grant/command/GrantCommand.java new file mode 100644 index 0000000..8727024 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/command/GrantCommand.java @@ -0,0 +1,62 @@ +package com.minexd.zoot.profile.grant.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.packet.PacketAddGrant; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.grant.Grant; +import com.minexd.zoot.profile.grant.event.GrantAppliedEvent; +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.TimeUtil; +import com.minexd.zoot.util.duration.Duration; +import com.qrakn.honcho.command.CPL; +import com.qrakn.honcho.command.CommandMeta; +import java.util.UUID; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = "grant", async = true, permission = "zoot.staff.grant") +public class GrantCommand { + + public void execute(CommandSender sender, @CPL("player") Profile profile, Rank rank, Duration duration, String reason) { + if (rank == null) { + sender.sendMessage(Locale.RANK_NOT_FOUND.format()); + return; + } + + if (profile == null || !profile.isLoaded()) { + sender.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + if (duration.getValue() == -1) { + sender.sendMessage(CC.RED + "That duration is not valid."); + sender.sendMessage(CC.RED + "Example: [perm/1y1m1w1d]"); + return; + } + + UUID addedBy = sender instanceof Player ? ((Player) sender).getUniqueId() : null; + Grant grant = new Grant(UUID.randomUUID(), rank, addedBy, System.currentTimeMillis(), reason, + duration.getValue()); + + profile.getGrants().add(grant); + profile.save(); + profile.activateNextGrant(); + + Zoot.get().getPidgin().sendPacket(new PacketAddGrant(profile.getUuid(), grant)); + + sender.sendMessage(CC.GREEN + "You applied a `{rank}` grant to `{player}` for {time-remaining}." + .replace("{rank}", rank.getDisplayName()) + .replace("{player}", profile.getUsername()) + .replace("{time-remaining}", duration.getValue() == Integer.MAX_VALUE ? "forever" + : TimeUtil.millisToRoundedTime(duration.getValue()))); + + Player player = profile.getPlayer(); + + if (player != null) { + new GrantAppliedEvent(player, grant).call(); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/command/GrantsCommand.java b/src/main/java/com/minexd/zoot/profile/grant/command/GrantsCommand.java new file mode 100644 index 0000000..b2c8d7a --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/command/GrantsCommand.java @@ -0,0 +1,22 @@ +package com.minexd.zoot.profile.grant.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.grant.menu.GrantsListMenu; +import com.qrakn.honcho.command.CPL; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = "grants", async = true, permission = "zoot.staff.grant") +public class GrantsCommand { + + public void execute(Player player, @CPL("player") Profile profile) { + if (profile == null || !profile.isLoaded()) { + player.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + new GrantsListMenu(profile).openMenu(player); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/event/GrantAppliedEvent.java b/src/main/java/com/minexd/zoot/profile/grant/event/GrantAppliedEvent.java new file mode 100644 index 0000000..bdddeb6 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/event/GrantAppliedEvent.java @@ -0,0 +1,16 @@ +package com.minexd.zoot.profile.grant.event; + +import com.minexd.zoot.profile.grant.Grant; +import com.minexd.zoot.util.BaseEvent; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.entity.Player; + +@AllArgsConstructor +@Getter +public class GrantAppliedEvent extends BaseEvent { + + private Player player; + private Grant grant; + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/event/GrantExpireEvent.java b/src/main/java/com/minexd/zoot/profile/grant/event/GrantExpireEvent.java new file mode 100644 index 0000000..ac62a6f --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/event/GrantExpireEvent.java @@ -0,0 +1,16 @@ +package com.minexd.zoot.profile.grant.event; + +import com.minexd.zoot.profile.grant.Grant; +import com.minexd.zoot.util.BaseEvent; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.entity.Player; + +@AllArgsConstructor +@Getter +public class GrantExpireEvent extends BaseEvent { + + private Player player; + private Grant grant; + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/menu/GrantsListMenu.java b/src/main/java/com/minexd/zoot/profile/grant/menu/GrantsListMenu.java new file mode 100644 index 0000000..d5e769d --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/menu/GrantsListMenu.java @@ -0,0 +1,129 @@ +package com.minexd.zoot.profile.grant.menu; + +import com.minexd.zoot.profile.grant.Grant; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.grant.procedure.GrantProcedure; +import com.minexd.zoot.profile.grant.procedure.GrantProcedureStage; +import com.minexd.zoot.profile.grant.procedure.GrantProcedureType; +import com.minexd.zoot.util.ItemBuilder; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.TimeUtil; +import com.minexd.zoot.util.menu.Button; +import com.minexd.zoot.util.menu.pagination.PaginatedMenu; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.AllArgsConstructor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +@AllArgsConstructor +public class GrantsListMenu extends PaginatedMenu { + + private Profile profile; + + @Override + public String getPrePaginatedTitle(Player player) { + return "&6" + profile.getUsername() + "'s Grants (" + profile.getGrants().size() + ")"; + } + + @Override + public Map getAllPagesButtons(Player player) { + Map buttons = new HashMap<>(); + + for (Grant grant : profile.getGrants()) { + buttons.put(buttons.size(), new GrantInfoButton(profile, grant)); + } + + return buttons; + } + + @AllArgsConstructor + private class GrantInfoButton extends Button { + + private Profile profile; + private Grant grant; + + @Override + public ItemStack getButtonItem(Player player) { + int durability; + + if (grant.isRemoved()) { + durability = 5; + } else if (grant.hasExpired()) { + durability = 4; + } else { + durability = 14; + } + + String addedBy = "Console"; + + if (grant.getAddedBy() != null) { + addedBy = "Could not fetch..."; + + Profile addedByProfile = Profile.getByUuid(grant.getAddedBy()); + + if (addedByProfile != null && addedByProfile.isLoaded()) { + addedBy = addedByProfile.getUsername(); + } + } + + String removedBy = "Console"; + + if (grant.getRemovedBy() != null) { + removedBy = "Could not fetch..."; + + Profile removedByProfile = Profile.getByUuid(grant.getRemovedBy()); + + if (removedByProfile != null && removedByProfile.isLoaded()) { + removedBy = removedByProfile.getUsername(); + } + } + + List lore = new ArrayList<>(); + + lore.add(CC.MENU_BAR); + lore.add("&3Rank: &e" + grant.getRank().getDisplayName()); + lore.add("&3Duration: &e" + grant.getDurationText()); + lore.add("&3Issued by: &e" + addedBy); + lore.add("&3Reason: &e" + grant.getAddedReason()); + + if (grant.isRemoved()) { + lore.add(CC.MENU_BAR); + lore.add("&a&lGrant Removed"); + lore.add("&a" + TimeUtil.dateToString(new Date(grant.getRemovedAt()), "&7")); + lore.add("&aRemoved by: &7" + removedBy); + lore.add("&aReason: &7&o\"" + grant.getRemovedReason() + "\""); + } else { + if (!grant.hasExpired()) { + lore.add(CC.MENU_BAR); + lore.add("&aRight click to remove this grant"); + } + } + + lore.add(CC.MENU_BAR); + + return new ItemBuilder(Material.PAPER) + .name("&3" + TimeUtil.dateToString(new Date(grant.getAddedAt()), "&7")) + .durability(durability) + .lore(lore) + .build(); + } + + @Override + public void clicked(Player player, ClickType clickType) { + if (clickType == ClickType.RIGHT && !grant.isRemoved() && !grant.hasExpired()) { + GrantProcedure procedure = new GrantProcedure(player, profile, GrantProcedureType.REMOVE, GrantProcedureStage.REQUIRE_TEXT); + procedure.setGrant(grant); + + player.sendMessage(CC.GREEN + "Type a reason for removing this grant in chat..."); + player.closeInventory(); + } + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/procedure/GrantProcedure.java b/src/main/java/com/minexd/zoot/profile/grant/procedure/GrantProcedure.java new file mode 100644 index 0000000..0cd2982 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/procedure/GrantProcedure.java @@ -0,0 +1,49 @@ +package com.minexd.zoot.profile.grant.procedure; + +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.grant.Grant; +import java.util.HashSet; +import java.util.Set; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; + +public class GrantProcedure { + + @Getter private static final Set procedures = new HashSet<>(); + + @Getter private final Player issuer; + @Getter private final Profile recipient; + @Getter private final GrantProcedureType type; + @Getter private GrantProcedureStage stage; + @Getter @Setter private Grant grant; + + public GrantProcedure(Player issuer, Profile recipient, GrantProcedureType type, GrantProcedureStage stage) { + this.issuer = issuer; + this.recipient = recipient; + this.type = type; + this.stage = stage; + + procedures.add(this); + } + + public void finish() { + this.recipient.save(); + procedures.remove(this); + } + + public void cancel() { + procedures.remove(this); + } + + public static GrantProcedure getByPlayer(Player player) { + for (GrantProcedure procedure : procedures) { + if (procedure.issuer.equals(player)) { + return procedure; + } + } + + return null; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/procedure/GrantProcedureStage.java b/src/main/java/com/minexd/zoot/profile/grant/procedure/GrantProcedureStage.java new file mode 100644 index 0000000..91220d0 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/procedure/GrantProcedureStage.java @@ -0,0 +1,9 @@ +package com.minexd.zoot.profile.grant.procedure; + +public enum GrantProcedureStage { + + REQUIRE_CLICK, + REQUIRE_TEXT, + REQUIRE_CONFIRMATION, + +} diff --git a/src/main/java/com/minexd/zoot/profile/grant/procedure/GrantProcedureType.java b/src/main/java/com/minexd/zoot/profile/grant/procedure/GrantProcedureType.java new file mode 100644 index 0000000..2fdab1a --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/grant/procedure/GrantProcedureType.java @@ -0,0 +1,8 @@ +package com.minexd.zoot.profile.grant.procedure; + +public enum GrantProcedureType { + + GRANT, + REMOVE + +} diff --git a/src/main/java/com/minexd/zoot/profile/menu/ProfileMenuControlHeaderButton.java b/src/main/java/com/minexd/zoot/profile/menu/ProfileMenuControlHeaderButton.java new file mode 100644 index 0000000..0e2a6b7 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/menu/ProfileMenuControlHeaderButton.java @@ -0,0 +1,53 @@ +package com.minexd.zoot.profile.menu; + +import com.minexd.zoot.cache.RedisPlayerData; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.ItemBuilder; +import com.minexd.zoot.util.menu.Button; +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +@AllArgsConstructor +public class ProfileMenuControlHeaderButton extends Button { + + private Profile profile; + private RedisPlayerData playerData; + + @Override + public ItemStack getButtonItem(Player player) { + ItemStack itemStack = new ItemStack(Material.SKULL_ITEM, 1, (short) 3); + SkullMeta skullMeta = (SkullMeta) itemStack.getItemMeta(); + skullMeta.setOwner(profile.getUsername()); + itemStack.setItemMeta(skullMeta); + + List lore = new ArrayList<>(); + lore.add(CC.MENU_BAR); + + if (playerData == null) { + lore.add("&cStatus data not available"); + } else { + if (playerData.getLastAction() == RedisPlayerData.LastAction.JOINING_SERVER) { + lore.add("&aCurrently Online"); + } else if (playerData.getLastAction() == RedisPlayerData.LastAction.LEAVING_SERVER) { + lore.add("&cLast Seen"); + } + + lore.add("&3Server: &e" + playerData.getLastSeenServer()); + lore.add("&3Updated: &e" + playerData.getTimeAgo()); + } + + lore.add(CC.MENU_BAR); + + return new ItemBuilder(itemStack) + .name("&3" + profile.getUsername()) + .lore(lore) + .build(); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/ProfileOptions.java b/src/main/java/com/minexd/zoot/profile/option/ProfileOptions.java new file mode 100644 index 0000000..cd4df92 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/ProfileOptions.java @@ -0,0 +1,14 @@ +package com.minexd.zoot.profile.option; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +@Accessors(fluent = true) +public class ProfileOptions { + + @Getter @Setter private boolean publicChatEnabled = true; + @Getter @Setter private boolean receivingNewConversations = true; + @Getter @Setter private boolean playingMessageSounds = true; + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/command/OptionsCommand.java b/src/main/java/com/minexd/zoot/profile/option/command/OptionsCommand.java new file mode 100644 index 0000000..dc37eab --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/command/OptionsCommand.java @@ -0,0 +1,14 @@ +package com.minexd.zoot.profile.option.command; + +import com.minexd.zoot.profile.option.menu.ProfileOptionsMenu; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "options", "settings" }) +public class OptionsCommand { + + public void execute(Player player) { + new ProfileOptionsMenu().openMenu(player); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/command/ToggleGlobalChatCommand.java b/src/main/java/com/minexd/zoot/profile/option/command/ToggleGlobalChatCommand.java new file mode 100644 index 0000000..e17cb3c --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/command/ToggleGlobalChatCommand.java @@ -0,0 +1,22 @@ +package com.minexd.zoot.profile.option.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.profile.Profile; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "toggleglobalchat", "tgc", "togglepublicchat", "tpc" }) +public class ToggleGlobalChatCommand { + + public void execute(Player player) { + Profile profile = Profile.getByUuid(player.getUniqueId()); + profile.getOptions().publicChatEnabled(!profile.getOptions().publicChatEnabled()); + + if (profile.getOptions().publicChatEnabled()) { + player.sendMessage(Locale.OPTIONS_GLOBAL_CHAT_ENABLED.format()); + } else { + player.sendMessage(Locale.OPTIONS_GLOBAL_CHAT_DISABLED.format()); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/command/TogglePrivateMessagesCommand.java b/src/main/java/com/minexd/zoot/profile/option/command/TogglePrivateMessagesCommand.java new file mode 100644 index 0000000..43886b9 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/command/TogglePrivateMessagesCommand.java @@ -0,0 +1,23 @@ +package com.minexd.zoot.profile.option.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.profile.Profile; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "togglepm", "togglepms", "tpm", "tpms" }) +public class TogglePrivateMessagesCommand { + + public void execute(Player player) { + Profile profile = Profile.getByUuid(player.getUniqueId()); + profile.getOptions().receivingNewConversations(!profile.getOptions().receivingNewConversations()); + profile.getConversations().expireAllConversations(); + + if (profile.getOptions().receivingNewConversations()) { + player.sendMessage(Locale.OPTIONS_PRIVATE_MESSAGES_ENABLED.format()); + } else { + player.sendMessage(Locale.OPTIONS_PRIVATE_MESSAGES_DISABLED.format()); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/command/ToggleSoundsCommand.java b/src/main/java/com/minexd/zoot/profile/option/command/ToggleSoundsCommand.java new file mode 100644 index 0000000..1adf1a1 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/command/ToggleSoundsCommand.java @@ -0,0 +1,22 @@ +package com.minexd.zoot.profile.option.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.profile.Profile; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "togglesounds", "sounds" }) +public class ToggleSoundsCommand { + + public void execute(Player player) { + Profile profile = Profile.getByUuid(player.getUniqueId()); + profile.getOptions().playingMessageSounds(!profile.getOptions().playingMessageSounds()); + + if (profile.getOptions().playingMessageSounds()) { + player.sendMessage(Locale.OPTIONS_PRIVATE_MESSAGE_SOUND_ENABLED.format()); + } else { + player.sendMessage(Locale.OPTIONS_PRIVATE_MESSAGE_SOUND_DISABLED.format()); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/event/OptionsOpenedEvent.java b/src/main/java/com/minexd/zoot/profile/option/event/OptionsOpenedEvent.java new file mode 100644 index 0000000..0381104 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/event/OptionsOpenedEvent.java @@ -0,0 +1,18 @@ +package com.minexd.zoot.profile.option.event; + +import com.minexd.zoot.profile.option.menu.ProfileOptionButton; +import com.minexd.zoot.util.BaseEvent; +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.bukkit.entity.Player; + +@RequiredArgsConstructor +@Getter +public class OptionsOpenedEvent extends BaseEvent { + + private final Player player; + private List buttons = new ArrayList<>(); + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/menu/ProfileOptionButton.java b/src/main/java/com/minexd/zoot/profile/option/menu/ProfileOptionButton.java new file mode 100644 index 0000000..7ed5885 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/menu/ProfileOptionButton.java @@ -0,0 +1,55 @@ +package com.minexd.zoot.profile.option.menu; + +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.ItemBuilder; +import com.minexd.zoot.util.TextSplitter; +import com.minexd.zoot.util.menu.Button; +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringEscapeUtils; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +@AllArgsConstructor +public abstract class ProfileOptionButton extends Button { + + @Override + public ItemStack getButtonItem(Player player) { + ItemBuilder itemBuilder = new ItemBuilder(isEnabled(player) ? getEnabledItem(player) : getDisabledItem(player)); + + List lore = new ArrayList<>(); + lore.add(""); + lore.addAll(TextSplitter.split(40, getDescription(), CC.GRAY, " ")); + lore.add(""); + lore.add((isEnabled(player) ? CC.BLUE + StringEscapeUtils.unescapeJava(" » ") : " ") + "&e" + getEnabledOption()); + lore.add((!isEnabled(player) ? CC.BLUE + StringEscapeUtils.unescapeJava(" » ") : " ") + "&e" + getDisabledOption()); + lore.add(""); + lore.add("&eClick to toggle this option."); + + return itemBuilder.name(getOptionName()) + .lore(lore) + .build(); + } + + public abstract ItemStack getEnabledItem(Player player); + + public abstract ItemStack getDisabledItem(Player player); + + public abstract String getOptionName(); + + public abstract String getDescription(); + + public abstract String getEnabledOption(); + + public abstract String getDisabledOption(); + + public abstract boolean isEnabled(Player player); + + @Override + public boolean shouldUpdate(Player player, ClickType clickType) { + return true; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/menu/ProfileOptionsMenu.java b/src/main/java/com/minexd/zoot/profile/option/menu/ProfileOptionsMenu.java new file mode 100644 index 0000000..9c22399 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/menu/ProfileOptionsMenu.java @@ -0,0 +1,39 @@ +package com.minexd.zoot.profile.option.menu; + +import com.minexd.zoot.profile.option.event.OptionsOpenedEvent; +import com.minexd.zoot.profile.option.menu.button.PrivateChatOptionButton; +import com.minexd.zoot.profile.option.menu.button.PrivateChatSoundsOptionButton; +import com.minexd.zoot.profile.option.menu.button.PublicChatOptionButton; +import com.minexd.zoot.util.menu.Button; +import com.minexd.zoot.util.menu.Menu; +import java.util.HashMap; +import java.util.Map; +import org.bukkit.entity.Player; + +public class ProfileOptionsMenu extends Menu { + + @Override + public String getTitle(Player player) { + return "&6&lOptions"; + } + + @Override + public Map getButtons(Player player) { + Map buttons = new HashMap<>(); + buttons.put(buttons.size(), new PublicChatOptionButton()); + buttons.put(buttons.size(), new PrivateChatOptionButton()); + buttons.put(buttons.size(), new PrivateChatSoundsOptionButton()); + + OptionsOpenedEvent event = new OptionsOpenedEvent(player); + event.call(); + + if (!event.getButtons().isEmpty()) { + for (ProfileOptionButton button : event.getButtons()) { + buttons.put(buttons.size(), button); + } + } + + return buttons; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/menu/button/PrivateChatOptionButton.java b/src/main/java/com/minexd/zoot/profile/option/menu/button/PrivateChatOptionButton.java new file mode 100644 index 0000000..69a43e4 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/menu/button/PrivateChatOptionButton.java @@ -0,0 +1,54 @@ +package com.minexd.zoot.profile.option.menu.button; + +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.option.menu.ProfileOptionButton; +import com.minexd.zoot.util.ItemBuilder; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +public class PrivateChatOptionButton extends ProfileOptionButton { + + @Override + public String getOptionName() { + return "&c&lPrivate Chat"; + } + + @Override + public ItemStack getEnabledItem(Player player) { + return new ItemBuilder(Material.NAME_TAG).build(); + } + + @Override + public ItemStack getDisabledItem(Player player) { + return new ItemBuilder(Material.NAME_TAG).build(); + } + + @Override + public String getDescription() { + return "If enabled, you will receive private chat messages."; + } + + @Override + public String getEnabledOption() { + return "Receive private chat messages"; + } + + @Override + public String getDisabledOption() { + return "Do not receive private chat messages"; + } + + @Override + public boolean isEnabled(Player player) { + return Profile.getProfiles().get(player.getUniqueId()).getOptions().receivingNewConversations(); + } + + @Override + public void clicked(Player player, ClickType clickType) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + profile.getOptions().receivingNewConversations(!profile.getOptions().receivingNewConversations()); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/menu/button/PrivateChatSoundsOptionButton.java b/src/main/java/com/minexd/zoot/profile/option/menu/button/PrivateChatSoundsOptionButton.java new file mode 100644 index 0000000..03241ed --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/menu/button/PrivateChatSoundsOptionButton.java @@ -0,0 +1,54 @@ +package com.minexd.zoot.profile.option.menu.button; + +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.option.menu.ProfileOptionButton; +import com.minexd.zoot.util.ItemBuilder; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +public class PrivateChatSoundsOptionButton extends ProfileOptionButton { + + @Override + public String getOptionName() { + return "&e&lPrivate Chat Sounds"; + } + + @Override + public ItemStack getEnabledItem(Player player) { + return new ItemBuilder(Material.NOTE_BLOCK).build(); + } + + @Override + public ItemStack getDisabledItem(Player player) { + return new ItemBuilder(Material.NOTE_BLOCK).build(); + } + + @Override + public String getDescription() { + return "If enabled, a sound will be played when you receive a private chat message."; + } + + @Override + public String getEnabledOption() { + return "Play private chat message sounds"; + } + + @Override + public String getDisabledOption() { + return "Do not play private chat message sounds"; + } + + @Override + public boolean isEnabled(Player player) { + return Profile.getProfiles().get(player.getUniqueId()).getOptions().playingMessageSounds(); + } + + @Override + public void clicked(Player player, ClickType clickType) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + profile.getOptions().playingMessageSounds(!profile.getOptions().playingMessageSounds()); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/option/menu/button/PublicChatOptionButton.java b/src/main/java/com/minexd/zoot/profile/option/menu/button/PublicChatOptionButton.java new file mode 100644 index 0000000..506acb8 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/option/menu/button/PublicChatOptionButton.java @@ -0,0 +1,54 @@ +package com.minexd.zoot.profile.option.menu.button; + +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.option.menu.ProfileOptionButton; +import com.minexd.zoot.util.ItemBuilder; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +public class PublicChatOptionButton extends ProfileOptionButton { + + @Override + public String getOptionName() { + return "&a&lPublic Chat"; + } + + @Override + public ItemStack getEnabledItem(Player player) { + return new ItemBuilder(Material.BOOK_AND_QUILL).build(); + } + + @Override + public ItemStack getDisabledItem(Player player) { + return new ItemBuilder(Material.BOOK_AND_QUILL).build(); + } + + @Override + public String getDescription() { + return "If enabled, you will receive public chat messages."; + } + + @Override + public String getEnabledOption() { + return "Receive public chat messages"; + } + + @Override + public String getDisabledOption() { + return "Do not receive public chat messages"; + } + + @Override + public boolean isEnabled(Player player) { + return Profile.getProfiles().get(player.getUniqueId()).getOptions().publicChatEnabled(); + } + + @Override + public void clicked(Player player, ClickType clickType) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + profile.getOptions().publicChatEnabled(!profile.getOptions().publicChatEnabled()); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/Punishment.java b/src/main/java/com/minexd/zoot/profile/punishment/Punishment.java new file mode 100644 index 0000000..b5a9ca2 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/Punishment.java @@ -0,0 +1,131 @@ +package com.minexd.zoot.profile.punishment; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.TimeUtil; +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.Bukkit; + +public class Punishment { + + public static PunishmentJsonSerializer SERIALIZER = new PunishmentJsonSerializer(); + public static PunishmentJsonDeserializer DESERIALIZER = new PunishmentJsonDeserializer(); + + @Getter private final UUID uuid; + @Getter private final PunishmentType type; + @Getter @Setter private UUID addedBy; + @Getter final private long addedAt; + @Getter private final String addedReason; + @Getter final private long duration; + @Getter @Setter private UUID removedBy; + @Getter @Setter private long removedAt; + @Getter @Setter private String removedReason; + @Getter @Setter private boolean removed; + + public Punishment(UUID uuid, PunishmentType type, long addedAt, String addedReason, long duration) { + this.uuid = uuid; + this.type = type; + this.addedAt = addedAt; + this.addedReason = addedReason; + this.duration = duration; + } + + public boolean isPermanent() { + return type == PunishmentType.BLACKLIST || duration == Integer.MAX_VALUE; + } + + public boolean hasExpired() { + return (!isPermanent()) && (System.currentTimeMillis() >= addedAt + duration); + } + + public String getDurationText() { + if (removed) { + return "Removed"; + } + + if (isPermanent()) { + return "Permanent"; + } + + return TimeUtil.millisToRoundedTime(duration); + } + + public String getTimeRemaining() { + if (removed) { + return "Removed"; + } + + if (isPermanent()) { + return "Permanent"; + } + + if (hasExpired()) { + return "Expired"; + } + + return TimeUtil.millisToRoundedTime((addedAt + duration) - System.currentTimeMillis()); + } + + public String getContext() { + if (!(type == PunishmentType.BAN || type == PunishmentType.MUTE)) { + return removed ? type.getUndoContext() : type.getContext(); + } + + if (isPermanent()) { + return (removed ? type.getUndoContext() : "permanently " + type.getContext()); + } else { + return (removed ? type.getUndoContext() : "temporarily " + type.getContext()); + } + } + + public void broadcast(String sender, String target, boolean silent) { + if (silent) { + Bukkit.getOnlinePlayers().forEach(player -> { + if (player.hasPermission("zoot.staff")) { + player.sendMessage(Zoot.get().getMainConfig().getString("PUNISHMENTS.BROADCAST_SILENT") + .replace("{context}", getContext()) + .replace("{target}", target) + .replace("{sender}", sender)); + } + }); + } else { + Bukkit.broadcastMessage(Zoot.get().getMainConfig().getString("PUNISHMENTS.BROADCAST") + .replace("{context}", getContext()) + .replace("{target}", target) + .replace("{sender}", sender)); + } + } + + public String getKickMessage() { + String kickMessage; + + if (type == PunishmentType.BAN) { + kickMessage = Zoot.get().getMainConfig().getString("PUNISHMENTS.BAN.KICK"); + String temporary = ""; + + if (!isPermanent()) { + temporary = Zoot.get().getMainConfig().getString("PUNISHMENTS.BAN.TEMPORARY"); + temporary = temporary.replace("{time-remaining}", getTimeRemaining()); + } + + kickMessage = kickMessage.replace("{context}", getContext()) + .replace("{temporary}", temporary); + } else if (type == PunishmentType.KICK) { + kickMessage = Zoot.get().getMainConfig().getString("PUNISHMENTS.KICK.KICK") + .replace("{context}", getContext()) + .replace("{reason}", addedReason); + } else { + kickMessage = null; + } + + return CC.translate(kickMessage); + } + + @Override + public boolean equals(Object object) { + return object != null && object instanceof Punishment && ((Punishment) object).uuid.equals(uuid); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/PunishmentJsonDeserializer.java b/src/main/java/com/minexd/zoot/profile/punishment/PunishmentJsonDeserializer.java new file mode 100644 index 0000000..d7c4ac5 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/PunishmentJsonDeserializer.java @@ -0,0 +1,42 @@ +package com.minexd.zoot.profile.punishment; + +import com.google.gson.JsonObject; +import com.minexd.zoot.util.json.JsonDeserializer; +import java.util.UUID; + +public class PunishmentJsonDeserializer implements JsonDeserializer { + + @Override + public Punishment deserialize(JsonObject object) { + Punishment punishment = new Punishment( + UUID.fromString(object.get("uuid").getAsString()), + PunishmentType.valueOf(object.get("type").getAsString()), + object.get("addedAt").getAsLong(), + object.get("addedReason").getAsString(), + object.get("duration").getAsLong() + ); + + if (!object.get("addedBy").isJsonNull()) { + punishment.setAddedBy(UUID.fromString(object.get("addedBy").getAsString())); + } + + if (!object.get("removedBy").isJsonNull()) { + punishment.setRemovedBy(UUID.fromString(object.get("removedBy").getAsString())); + } + + if (!object.get("removedAt").isJsonNull()) { + punishment.setRemovedAt(object.get("removedAt").getAsLong()); + } + + if (!object.get("removedReason").isJsonNull()) { + punishment.setRemovedReason(object.get("removedReason").getAsString()); + } + + if (!object.get("removed").isJsonNull()) { + punishment.setRemoved(object.get("removed").getAsBoolean()); + } + + return punishment; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/PunishmentJsonSerializer.java b/src/main/java/com/minexd/zoot/profile/punishment/PunishmentJsonSerializer.java new file mode 100644 index 0000000..f2db5bc --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/PunishmentJsonSerializer.java @@ -0,0 +1,24 @@ +package com.minexd.zoot.profile.punishment; + +import com.google.gson.JsonObject; +import com.minexd.zoot.util.json.JsonSerializer; + +public class PunishmentJsonSerializer implements JsonSerializer { + + @Override + public JsonObject serialize(Punishment punishment) { + JsonObject object = new JsonObject(); + object.addProperty("uuid", punishment.getUuid().toString()); + object.addProperty("type", punishment.getType().name()); + object.addProperty("addedBy", punishment.getAddedBy() == null ? null : punishment.getAddedBy().toString()); + object.addProperty("addedAt", punishment.getAddedAt()); + object.addProperty("addedReason", punishment.getAddedReason()); + object.addProperty("duration", punishment.getDuration()); + object.addProperty("removedBy", punishment.getRemovedBy() == null ? null : punishment.getRemovedBy().toString()); + object.addProperty("removedAt", punishment.getRemovedAt()); + object.addProperty("removedReason", punishment.getRemovedReason()); + object.addProperty("removed", punishment.isRemoved()); + return object; + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/PunishmentType.java b/src/main/java/com/minexd/zoot/profile/punishment/PunishmentType.java new file mode 100644 index 0000000..c299628 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/PunishmentType.java @@ -0,0 +1,34 @@ +package com.minexd.zoot.profile.punishment; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.ChatColor; + +@Getter +@AllArgsConstructor +public enum PunishmentType { + + BLACKLIST("Blacklist", "blacklisted", "unblacklisted", true, true, new PunishmentTypeData("Blacklists", ChatColor.DARK_RED, 14)), + BAN("Ban", "banned", "unbanned", true, true, new PunishmentTypeData("Bans", ChatColor.GOLD, 1)), + MUTE("Mute", "muted", "unmuted", false, true, new PunishmentTypeData("Mutes", ChatColor.YELLOW, 4)), + WARN("Warning", "warned", null, false, false, new PunishmentTypeData("Warnings", ChatColor.GREEN, 13)), + KICK("Kick", "kicked", null, false, false, new PunishmentTypeData("Kicks", ChatColor.GRAY, 7)); + + private String readable; + private String context; + private String undoContext; + private boolean ban; + private boolean removable; + private PunishmentTypeData typeData; + + @AllArgsConstructor + @Getter + public static class PunishmentTypeData { + + private String readable; + private ChatColor color; + private int durability; + + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/command/BanCommand.java b/src/main/java/com/minexd/zoot/profile/punishment/command/BanCommand.java new file mode 100644 index 0000000..c2a378e --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/command/BanCommand.java @@ -0,0 +1,67 @@ +package com.minexd.zoot.profile.punishment.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.packet.PacketBroadcastPunishment; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.profile.punishment.PunishmentType; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.duration.Duration; +import com.qrakn.honcho.command.CPL; +import com.qrakn.honcho.command.CommandMeta; +import com.qrakn.honcho.command.CommandOption; +import java.util.UUID; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +@CommandMeta(label = "ban", permission = "zoot.staff.ban", async = true, options = "s") +public class BanCommand { + + public void execute(CommandSender sender, CommandOption option, @CPL("player") Profile profile, Duration duration, String reason) { + if (profile == null || !profile.isLoaded()) { + sender.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + if (profile.getActivePunishmentByType(PunishmentType.BAN) != null) { + sender.sendMessage(CC.RED + "That player is already banned."); + return; + } + + if (duration.getValue() == -1) { + sender.sendMessage(CC.RED + "That duration is not valid."); + sender.sendMessage(CC.RED + "Example: [perm/1y1m1w1d]"); + return; + } + + String staffName = sender instanceof Player ? Profile.getProfiles().get(((Player) sender) + .getUniqueId()).getColoredUsername() : CC.DARK_RED + "Console"; + + Punishment punishment = new Punishment(UUID.randomUUID(), PunishmentType.BAN, System.currentTimeMillis(), + reason, duration.getValue()); + + if (sender instanceof Player) { + punishment.setAddedBy(((Player) sender).getUniqueId()); + } + + profile.getPunishments().add(punishment); + profile.save(); + + Zoot.get().getPidgin().sendPacket(new PacketBroadcastPunishment(punishment, staffName, + profile.getColoredUsername(), profile.getUuid(), option != null)); + + Player player = profile.getPlayer(); + + if (player != null) { + new BukkitRunnable() { + @Override + public void run() { + player.kickPlayer(punishment.getKickMessage()); + } + }.runTask(Zoot.get()); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/command/CheckCommand.java b/src/main/java/com/minexd/zoot/profile/punishment/command/CheckCommand.java new file mode 100644 index 0000000..b8ae666 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/command/CheckCommand.java @@ -0,0 +1,31 @@ +package com.minexd.zoot.profile.punishment.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.cache.RedisPlayerData; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.punishment.menu.PunishmentsListMenu; +import com.qrakn.honcho.command.CPL; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "check", "c" }, permission = "zoot.staff.check", async = true) +public class CheckCommand { + + public void execute(Player player, @CPL("player") Profile profile) { + if (profile == null || !profile.isLoaded()) { + player.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + RedisPlayerData redisPlayerData = Zoot.get().getRedisCache().getPlayerData(profile.getUuid()); + + if (redisPlayerData == null) { + player.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + new PunishmentsListMenu(profile, redisPlayerData).openMenu(player); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/command/KickCommand.java b/src/main/java/com/minexd/zoot/profile/punishment/command/KickCommand.java new file mode 100644 index 0000000..9fa9b58 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/command/KickCommand.java @@ -0,0 +1,57 @@ +package com.minexd.zoot.profile.punishment.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.packet.PacketBroadcastPunishment; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.profile.punishment.PunishmentType; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import com.qrakn.honcho.command.CommandOption; +import java.util.UUID; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +@CommandMeta(label = "kick", permission = "zoot.staff.kick", async = true, options = "s") +public class KickCommand { + + public void execute(CommandSender sender, CommandOption option, Player player, String reason) { + if (player == null) { + sender.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + + if (profile == null || !profile.isLoaded()) { + sender.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + String staffName = sender instanceof Player ? Profile.getProfiles().get(((Player) sender) + .getUniqueId()).getColoredUsername() : CC.DARK_RED + "Console"; + + Punishment punishment = new Punishment(UUID.randomUUID(), PunishmentType.KICK, System.currentTimeMillis(), + reason, -1); + + if (sender instanceof Player) { + punishment.setAddedBy(((Player) sender).getUniqueId()); + } + + profile.getPunishments().add(punishment); + profile.save(); + + Zoot.get().getPidgin().sendPacket(new PacketBroadcastPunishment(punishment, staffName, + profile.getColoredUsername(), profile.getUuid(), option != null)); + + new BukkitRunnable() { + @Override + public void run() { + player.kickPlayer(punishment.getKickMessage()); + } + }.runTask(Zoot.get()); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/command/MuteCommand.java b/src/main/java/com/minexd/zoot/profile/punishment/command/MuteCommand.java new file mode 100644 index 0000000..48c2107 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/command/MuteCommand.java @@ -0,0 +1,70 @@ +package com.minexd.zoot.profile.punishment.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.packet.PacketBroadcastPunishment; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.profile.punishment.PunishmentType; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.duration.Duration; +import com.qrakn.honcho.command.CPL; +import com.qrakn.honcho.command.CommandMeta; +import com.qrakn.honcho.command.CommandOption; +import java.util.UUID; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = "mute", permission = "zoot.staff.mute", async = true, options = "s") +public class MuteCommand { + + public void execute(CommandSender sender, CommandOption option, @CPL("player") Profile profile, Duration duration, String reason) { + if (profile == null || !profile.isLoaded()) { + sender.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + if (profile.getActivePunishmentByType(PunishmentType.MUTE) != null) { + sender.sendMessage(CC.RED + "That player is already muted."); + return; + } + + if (duration.getValue() == -1) { + sender.sendMessage(CC.RED + "That duration is not valid."); + sender.sendMessage(CC.RED + "Example: [perm/1y1m1w1d]"); + return; + } + + String staffName = sender instanceof Player ? Profile.getProfiles().get(((Player) sender) + .getUniqueId()).getColoredUsername() : CC.DARK_RED + "Console"; + + Punishment punishment = new Punishment(UUID.randomUUID(), PunishmentType.MUTE, System.currentTimeMillis(), + reason, duration.getValue()); + + if (sender instanceof Player) { + punishment.setAddedBy(((Player) sender).getUniqueId()); + } + + profile.getPunishments().add(punishment); + profile.save(); + + Player player = profile.getPlayer(); + + if (player != null) { + String senderName = sender instanceof Player ? Profile.getProfiles().get(((Player) sender).getUniqueId()).getColoredUsername() : CC.DARK_RED + "Console"; + player.sendMessage(CC.RED + "You have been " + punishment.getContext() + " by " + + senderName + CC.RED + "."); + player.sendMessage(CC.RED + "The reason for this punishment: " + CC.WHITE + + punishment.getAddedReason()); + + if (!punishment.isPermanent()) { + player.sendMessage(CC.RED + "This mute will expire in " + CC.WHITE + + punishment.getTimeRemaining() + CC.RED + "."); + } + } + + Zoot.get().getPidgin().sendPacket(new PacketBroadcastPunishment(punishment, staffName, + profile.getColoredUsername(), profile.getUuid(), option != null)); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/command/UnbanCommand.java b/src/main/java/com/minexd/zoot/profile/punishment/command/UnbanCommand.java new file mode 100644 index 0000000..43f3d7b --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/command/UnbanCommand.java @@ -0,0 +1,48 @@ +package com.minexd.zoot.profile.punishment.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.packet.PacketBroadcastPunishment; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.profile.punishment.PunishmentType; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CPL; +import com.qrakn.honcho.command.CommandMeta; +import com.qrakn.honcho.command.CommandOption; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = "unban", permission = "zoot.staff.unban", async = true, options = "s") +public class UnbanCommand { + + public void execute(CommandSender sender, CommandOption option, @CPL("player") Profile profile, String reason) { + if (profile == null || !profile.isLoaded()) { + sender.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + if (profile.getActivePunishmentByType(PunishmentType.BAN) == null) { + sender.sendMessage(CC.RED + "That player is not banned."); + return; + } + + String staffName = sender instanceof Player ? Profile.getProfiles().get(((Player) sender) + .getUniqueId()).getColoredUsername() : CC.DARK_RED + "Console"; + + Punishment punishment = profile.getActivePunishmentByType(PunishmentType.BAN); + punishment.setRemovedAt(System.currentTimeMillis()); + punishment.setRemovedReason(reason); + punishment.setRemoved(true); + + if (sender instanceof Player) { + punishment.setRemovedBy(((Player) sender).getUniqueId()); + } + + profile.save(); + + Zoot.get().getPidgin().sendPacket(new PacketBroadcastPunishment(punishment, staffName, + profile.getColoredUsername(), profile.getUuid(), option != null)); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/command/UnmuteCommand.java b/src/main/java/com/minexd/zoot/profile/punishment/command/UnmuteCommand.java new file mode 100644 index 0000000..872b989 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/command/UnmuteCommand.java @@ -0,0 +1,48 @@ +package com.minexd.zoot.profile.punishment.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.packet.PacketBroadcastPunishment; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.profile.punishment.PunishmentType; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CPL; +import com.qrakn.honcho.command.CommandMeta; +import com.qrakn.honcho.command.CommandOption; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = "unmute", permission = "zoot.staff.unmute", async = true, options = "s") +public class UnmuteCommand { + + public void execute(CommandSender sender, CommandOption option, @CPL("player") Profile profile, String reason) { + if (profile == null || !profile.isLoaded()) { + sender.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + if (profile.getActivePunishmentByType(PunishmentType.MUTE) == null) { + sender.sendMessage(CC.RED + "That player is not muted."); + return; + } + + String staffName = sender instanceof Player ? Profile.getProfiles().get(((Player) sender) + .getUniqueId()).getColoredUsername() : CC.DARK_RED + "Console"; + + Punishment punishment = profile.getActivePunishmentByType(PunishmentType.MUTE); + punishment.setRemovedAt(System.currentTimeMillis()); + punishment.setRemovedReason(reason); + punishment.setRemoved(true); + + if (sender instanceof Player) { + punishment.setRemovedBy(((Player) sender).getUniqueId()); + } + + profile.save(); + + Zoot.get().getPidgin().sendPacket(new PacketBroadcastPunishment(punishment, staffName, + profile.getColoredUsername(), profile.getUuid(), option != null)); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/command/WarnCommand.java b/src/main/java/com/minexd/zoot/profile/punishment/command/WarnCommand.java new file mode 100644 index 0000000..86a941b --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/command/WarnCommand.java @@ -0,0 +1,51 @@ +package com.minexd.zoot.profile.punishment.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.packet.PacketBroadcastPunishment; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.profile.punishment.PunishmentType; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CPL; +import com.qrakn.honcho.command.CommandMeta; +import com.qrakn.honcho.command.CommandOption; +import java.util.UUID; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandMeta(label = "warn", permission = "zoot.staff.warn", async = true, options = "s") +public class WarnCommand { + + public void execute(CommandSender sender, CommandOption option, @CPL("player") Profile profile, String reason) { + if (profile == null || !profile.isLoaded()) { + sender.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + String staffName = sender instanceof Player ? Profile.getProfiles().get(((Player) sender) + .getUniqueId()).getColoredUsername() : CC.DARK_RED + "Console"; + + Punishment punishment = new Punishment(UUID.randomUUID(), PunishmentType.WARN, System.currentTimeMillis(), + reason, -1); + + if (sender instanceof Player) { + punishment.setAddedBy(((Player) sender).getUniqueId()); + } + + profile.getPunishments().add(punishment); + profile.save(); + + Player player = profile.getPlayer(); + + if (player != null) { + String senderName = sender instanceof Player ? Profile.getProfiles().get(((Player) sender).getUniqueId()).getColoredUsername() : CC.DARK_RED + "Console"; + player.sendMessage(CC.RED + "You have been warned by " + senderName + CC.RED + "."); + player.sendMessage(CC.RED + "The reason for this punishment: " + CC.WHITE + punishment.getAddedReason()); + } + + Zoot.get().getPidgin().sendPacket(new PacketBroadcastPunishment(punishment, staffName, + profile.getColoredUsername(), profile.getUuid(), option != null)); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/listener/PunishmentListener.java b/src/main/java/com/minexd/zoot/profile/punishment/listener/PunishmentListener.java new file mode 100644 index 0000000..214deba --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/listener/PunishmentListener.java @@ -0,0 +1,69 @@ +package com.minexd.zoot.profile.punishment.listener; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.BootstrappedListener; +import com.minexd.zoot.profile.punishment.procedure.PunishmentProcedure; +import com.minexd.zoot.profile.punishment.procedure.PunishmentProcedureStage; +import com.minexd.zoot.profile.punishment.procedure.PunishmentProcedureType; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.callback.TypeCallback; +import com.minexd.zoot.util.menu.menus.ConfirmMenu; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +public class PunishmentListener extends BootstrappedListener { + + public PunishmentListener(Zoot zoot) { + super(zoot); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onAsyncPlayerChatEvent(AsyncPlayerChatEvent event) { + if (!event.getPlayer().hasPermission("zoot.staff.grant")) { + return; + } + + PunishmentProcedure procedure = PunishmentProcedure.getByPlayer(event.getPlayer()); + + if (procedure != null && procedure.getStage() == PunishmentProcedureStage.REQUIRE_TEXT) { + event.setCancelled(true); + + if (event.getMessage().equalsIgnoreCase("cancel")) { + PunishmentProcedure.getProcedures().remove(procedure); + event.getPlayer().sendMessage(CC.RED + "You have cancelled the punishment procedure."); + return; + } + + if (procedure.getType() == PunishmentProcedureType.PARDON) { + new ConfirmMenu(CC.YELLOW + "Pardon this punishment?", new TypeCallback() { + @Override + public void callback(Boolean data) { + if (data) { + procedure.getPunishment().setRemovedBy(event.getPlayer().getUniqueId()); + procedure.getPunishment().setRemovedAt(System.currentTimeMillis()); + procedure.getPunishment().setRemovedReason(event.getMessage()); + procedure.getPunishment().setRemoved(true); + procedure.finish(); + + event.getPlayer().sendMessage(CC.GREEN + "The punishment has been removed."); + } else { + procedure.cancel(); + event.getPlayer().sendMessage(CC.RED + "You did not confirm to pardon the punishment."); + } + } + }, true) { + @Override + public void onClose(Player player) { + if (!isClosedByMenu()) { + procedure.cancel(); + event.getPlayer().sendMessage(CC.RED + "You did not confirm to pardon the punishment."); + } + } + }.openMenu(event.getPlayer()); + } + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/menu/PunishmentsListMenu.java b/src/main/java/com/minexd/zoot/profile/punishment/menu/PunishmentsListMenu.java new file mode 100644 index 0000000..e97d7aa --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/menu/PunishmentsListMenu.java @@ -0,0 +1,177 @@ +package com.minexd.zoot.profile.punishment.menu; + +import com.minexd.zoot.cache.RedisPlayerData; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.menu.ProfileMenuControlHeaderButton; +import com.minexd.zoot.profile.punishment.PunishmentType; +import com.minexd.zoot.profile.punishment.procedure.PunishmentProcedure; +import com.minexd.zoot.profile.punishment.procedure.PunishmentProcedureStage; +import com.minexd.zoot.profile.punishment.procedure.PunishmentProcedureType; +import com.minexd.zoot.util.menu.Button; +import com.minexd.zoot.profile.punishment.Punishment; +import com.minexd.zoot.util.ItemBuilder; +import com.minexd.zoot.util.TimeUtil; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.menu.pagination.PageFilter; +import com.minexd.zoot.util.menu.pagination.FilterablePaginatedMenu; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.AllArgsConstructor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +@AllArgsConstructor +public class PunishmentsListMenu extends FilterablePaginatedMenu { + + private Profile profile; + private RedisPlayerData redisPlayerData; + + @Override + public String getPrePaginatedTitle(Player player) { + return "&c" + profile.getUsername() + "'s Punishments (" + getCountOfFilteredPunishments() + ")"; + } + + @Override + public Map getFilteredButtons(Player player) { + Map buttons = new HashMap<>(); + + obj: + for (Punishment punishment : profile.getPunishments()) { + for (PageFilter filter : getFilters()) { + if (!filter.test(punishment)) { + continue obj; + } + } + + buttons.put(buttons.size(), new PunishmentInfoButton(punishment)); + } + + return buttons; + } + + @Override + public Map getGlobalButtons(Player player) { + Map buttons = super.getGlobalButtons(player); + + if (profile.getUsername() != null) { + buttons.put(4, new ProfileMenuControlHeaderButton(profile, redisPlayerData)); + } + + return buttons; + } + + @Override + public List> generateFilters() { + List> filters = new ArrayList<>(); + filters.add(new PageFilter<>("Type: Ban", (punishment -> punishment.getType() == PunishmentType.BAN))); + filters.add(new PageFilter<>("Type: Mute", (punishment -> punishment.getType() == PunishmentType.MUTE))); + filters.add(new PageFilter<>("Type: Warn", (punishment -> punishment.getType() == PunishmentType.WARN))); + filters.add(new PageFilter<>("Type: Kick", (punishment -> punishment.getType() == PunishmentType.KICK))); + filters.add(new PageFilter<>("Issued By Console", (punishment -> punishment.getAddedBy() == null))); + filters.add(new PageFilter<>("Removed", Punishment::isRemoved)); + return filters; + } + + private int getCountOfFilteredPunishments() { + int i = 0; + + obj: + for (Punishment punishment : profile.getPunishments()) { + for (PageFilter filter : getFilters()) { + if (!filter.test(punishment)) { + continue obj; + } + } + + i++; + } + + return i; + } + + @AllArgsConstructor + private class PunishmentInfoButton extends Button { + + private Punishment punishment; + + @Override + public ItemStack getButtonItem(Player player) { + int durability; + + if (punishment.isRemoved()) { + durability = 5; + } else if (punishment.hasExpired()) { + durability = 4; + } else { + durability = 14; + } + + String addedBy = "Console"; + + if (punishment.getAddedBy() != null) { + try { + Profile addedByProfile = Profile.getByUuid(punishment.getAddedBy()); + addedBy = addedByProfile.getUsername(); + } catch (Exception e) { + addedBy = "Could not fetch..."; + } + } + + String removedBy = "Console"; + + if (punishment.getRemovedBy() != null) { + try { + Profile removedByProfile = Profile.getByUuid(punishment.getRemovedBy()); + removedBy = removedByProfile.getUsername(); + } catch (Exception e) { + removedBy = "Could not fetch..."; + } + } + + List lore = new ArrayList<>(); + lore.add(CC.MENU_BAR); + lore.add("&3Type: &e" + punishment.getType().getReadable()); + lore.add("&3Duration: &e" + punishment.getDurationText()); + lore.add("&3Issued by: &e" + addedBy); + lore.add("&3Reason: &e&o\"" + punishment.getAddedReason() + "\""); + + if (punishment.isRemoved()) { + lore.add(CC.MENU_BAR); + lore.add("&a&lPunishment Removed"); + lore.add("&a" + TimeUtil.dateToString(new Date(punishment.getRemovedAt()), "&7")); + lore.add("&aRemoved by: &7" + removedBy); + lore.add("&aReason: &7&o\"" + punishment.getRemovedReason() + "\""); + } else { + if (!punishment.hasExpired() && punishment.getType().isRemovable()) { + lore.add(CC.MENU_BAR); + lore.add("&aRight click to remove this punishment"); + } + } + + lore.add(CC.MENU_BAR); + + return new ItemBuilder(Material.STAINED_GLASS_PANE) + .durability(durability) + .name("&3" + TimeUtil.dateToString(new Date(punishment.getAddedAt()), "&7")) + .lore(lore) + .build(); + } + + @Override + public void clicked(Player player, ClickType clickType) { + if (clickType == ClickType.RIGHT && !punishment.isRemoved() && !punishment.hasExpired() && punishment.getType().isRemovable()) { + PunishmentProcedure procedure = new PunishmentProcedure(player, profile, PunishmentProcedureType.PARDON, PunishmentProcedureStage.REQUIRE_TEXT); + procedure.setPunishment(punishment); + + player.sendMessage(CC.GREEN + "Enter a reason for removing this punishment."); + player.closeInventory(); + } + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedure.java b/src/main/java/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedure.java new file mode 100644 index 0000000..360fbc6 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedure.java @@ -0,0 +1,51 @@ +package com.minexd.zoot.profile.punishment.procedure; + +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.profile.punishment.Punishment; +import java.util.HashSet; +import java.util.Set; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; + +public class PunishmentProcedure { + + @Getter private static final Set procedures = new HashSet<>(); + + @Getter private final Player issuer; + @Getter private final Profile recipient; + @Getter private final PunishmentProcedureType type; + @Getter private PunishmentProcedureStage stage; + @Getter @Setter private Punishment punishment; + + public PunishmentProcedure(Player issuer, Profile recipient, PunishmentProcedureType type, PunishmentProcedureStage stage) { + this.issuer = issuer; + this.recipient = recipient; + this.type = type; + this.stage = stage; + + procedures.add(this); + } + + public void finish() { + this.recipient.save(); + procedures.remove(this); + } + + public void cancel() { + procedures.remove(this); + } + + public static PunishmentProcedure getByPlayer(Player player) { + for (PunishmentProcedure procedure : procedures) { + if (procedure.issuer.equals(player)) { + return procedure; + } + } + + return null; + } + + + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureStage.java b/src/main/java/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureStage.java new file mode 100644 index 0000000..856808b --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureStage.java @@ -0,0 +1,9 @@ +package com.minexd.zoot.profile.punishment.procedure; + +public enum PunishmentProcedureStage { + + REQUIRE_CLICK, + REQUIRE_TEXT, + REQUIRE_CONFIRMATION, + +} diff --git a/src/main/java/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureType.java b/src/main/java/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureType.java new file mode 100644 index 0000000..46c72da --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureType.java @@ -0,0 +1,8 @@ +package com.minexd.zoot.profile.punishment.procedure; + +public enum PunishmentProcedureType { + + ADD, + PARDON + +} diff --git a/src/main/java/com/minexd/zoot/profile/staff/ProfileStaffOptions.java b/src/main/java/com/minexd/zoot/profile/staff/ProfileStaffOptions.java new file mode 100644 index 0000000..b21cc4b --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/staff/ProfileStaffOptions.java @@ -0,0 +1,13 @@ +package com.minexd.zoot.profile.staff; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +@Accessors(fluent = true) +public class ProfileStaffOptions { + + @Getter @Setter private boolean staffModeEnabled = true; + @Getter @Setter private boolean staffChatModeEnabled = false; + +} diff --git a/src/main/java/com/minexd/zoot/profile/staff/command/AltsCommand.java b/src/main/java/com/minexd/zoot/profile/staff/command/AltsCommand.java new file mode 100644 index 0000000..a56750e --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/staff/command/AltsCommand.java @@ -0,0 +1,46 @@ +package com.minexd.zoot.profile.staff.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CPL; +import com.qrakn.honcho.command.CommandMeta; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "alts", async = true, permission = "zoot.staff.alts") +public class AltsCommand { + + public void execute(CommandSender sender, @CPL("player") Profile profile) { + if (profile == null || !profile.isLoaded()) { + sender.sendMessage(Locale.COULD_NOT_RESOLVE_PLAYER.format()); + return; + } + + List alts = new ArrayList<>(); + + for (UUID altUuid : profile.getKnownAlts()) { + Profile altProfile = Profile.getByUuid(altUuid); + + if (altProfile != null && altProfile.isLoaded()) { + alts.add(altProfile); + } + } + + if (alts.isEmpty()) { + sender.sendMessage(CC.RED + "This player has no known alt accounts."); + } else { + StringBuilder builder = new StringBuilder(); + + for (Profile altProfile : alts) { + builder.append(altProfile.getUsername()); + builder.append(", "); + } + + sender.sendMessage(CC.GOLD + "Alts: " + CC.RESET + builder.toString()); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/staff/command/StaffChatCommand.java b/src/main/java/com/minexd/zoot/profile/staff/command/StaffChatCommand.java new file mode 100644 index 0000000..e7ab531 --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/staff/command/StaffChatCommand.java @@ -0,0 +1,33 @@ +package com.minexd.zoot.profile.staff.command; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.packet.PacketStaffChat; +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "staffchat", "sc" }, permission = "zoot.staff") +public class StaffChatCommand { + + public void execute(Player player) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + profile.getStaffOptions().staffChatModeEnabled(!profile.getStaffOptions().staffChatModeEnabled()); + + player.sendMessage(profile.getStaffOptions().staffChatModeEnabled() ? + CC.GREEN + "You are now talking in staff chat." : CC.RED + "You are no longer talking in staff chat."); + } + + public void execute(Player player, String message) { + Profile profile = Profile.getProfiles().get(player.getUniqueId()); + + if (!profile.getStaffOptions().staffModeEnabled()) { + player.sendMessage(CC.RED + "You are not in staff mode."); + return; + } + + Zoot.get().getPidgin().sendPacket(new PacketStaffChat(player.getDisplayName(), + Zoot.get().getMainConfig().getString("SERVER_NAME"), message)); + } + +} diff --git a/src/main/java/com/minexd/zoot/profile/staff/command/StaffModeCommand.java b/src/main/java/com/minexd/zoot/profile/staff/command/StaffModeCommand.java new file mode 100644 index 0000000..c0a0dec --- /dev/null +++ b/src/main/java/com/minexd/zoot/profile/staff/command/StaffModeCommand.java @@ -0,0 +1,19 @@ +package com.minexd.zoot.profile.staff.command; + +import com.minexd.zoot.profile.Profile; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.entity.Player; + +@CommandMeta(label = { "staffmode", "sm" }, permission = "zoot.staff") +public class StaffModeCommand { + + public void execute(Player player) { + Profile profile = Profile.getByUuid(player.getUniqueId()); + profile.getStaffOptions().staffModeEnabled(!profile.getStaffOptions().staffModeEnabled()); + + player.sendMessage(profile.getStaffOptions().staffModeEnabled() ? + CC.GREEN + "You are now in staff mode." : CC.RED + "You are no longer in staff mode."); + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/Rank.java b/src/main/java/com/minexd/zoot/rank/Rank.java new file mode 100644 index 0000000..3a298cf --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/Rank.java @@ -0,0 +1,265 @@ +package com.minexd.zoot.rank; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.network.packet.PacketDeleteRank; +import com.minexd.zoot.network.packet.PacketRefreshRank; +import com.minexd.zoot.util.CC; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoCursor; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.ReplaceOptions; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.Getter; +import lombok.Setter; +import org.bson.Document; +import org.bukkit.ChatColor; + +public class Rank { + + @Getter private static Map ranks = new HashMap<>(); + private static MongoCollection collection; + + @Getter private final UUID uuid; + @Getter private final String displayName; + @Getter @Setter private String prefix = ""; + @Getter @Setter private String suffix = ""; + @Getter @Setter private String color = ""; + @Getter @Setter private int weight; + @Setter private boolean defaultRank; + @Getter private final List permissions = new ArrayList<>(); + @Getter private final List inherited = new ArrayList<>(); + + public Rank(String displayName) { + this.uuid = UUID.randomUUID(); + this.displayName = displayName; + + ranks.put(uuid, this); + } + + public Rank(UUID uuid, String displayName) { + this.uuid = uuid; + this.displayName = displayName; + + ranks.put(uuid, this); + } + + public Rank(UUID uuid, String displayName, String prefix, String suffix, String color, int weight, + boolean defaultRank) { + this.uuid = uuid; + this.displayName = displayName; + this.prefix = prefix; + this.suffix = suffix; + this.color = color; + this.weight = weight; + this.defaultRank = defaultRank; + + ranks.put(uuid, this); + } + + public boolean isDefaultRank() { + return defaultRank; + } + + public boolean addPermission(String permission) { + if (!permissions.contains(permission)) { + permissions.add(permission); + return true; + } + + return false; + } + + public boolean removePermission(String permission) { + return permissions.remove(permission); + } + + public boolean hasPermission(String permission) { + if (permissions.contains(permission)) { + return true; + } + + for (Rank rank : inherited) { + if (rank.hasPermission(permission)) { + return true; + } + } + + return false; + } + + public boolean canInherit(Rank rankToCheck) { + if (inherited.contains(rankToCheck) || rankToCheck.inherited.contains(this)) { + return false; + } + + for (Rank rank : inherited) { + if (!rank.canInherit(rankToCheck)) { + return false; + } + } + + return true; + } + + public List getAllPermissions() { + List permissions = new ArrayList<>(); + permissions.addAll(this.permissions); + + for (Rank rank : inherited) { + permissions.addAll(rank.getAllPermissions()); + } + + return permissions; + } + + public void load() { + load(collection.find(Filters.eq("uuid", uuid.toString())).first()); + } + + private void load(Document document) { + if (document == null) { + return; + } + + prefix = ChatColor.translateAlternateColorCodes('&', document.getString("prefix")); + suffix = ChatColor.translateAlternateColorCodes('&', document.getString("suffix")); + color = ChatColor.translateAlternateColorCodes('&', document.getString("color")); + weight = document.getInteger("weight"); + defaultRank = document.getBoolean("defaultRank"); + + inherited.clear(); + + Zoot.GSON.>fromJson(document.getString("inherits"), Zoot.LIST_STRING_TYPE) + .stream() + .map(s -> Rank.getRankByUuid(UUID.fromString(s))) + .filter(Objects::nonNull) + .forEach(inherited::add); + } + + public void save() { + Document document = new Document(); + document.put("uuid", uuid.toString()); + document.put("displayName", displayName); + document.put("prefix", prefix.replace(String.valueOf(ChatColor.COLOR_CHAR), "&")); + document.put("suffix", suffix.replace(String.valueOf(ChatColor.COLOR_CHAR), "&")); + document.put("color", color.replace(String.valueOf(ChatColor.COLOR_CHAR), "&")); + document.put("weight", weight); + document.put("defaultRank", defaultRank); + document.put("permissions", Zoot.GSON.toJson(permissions)); + document.put("inherits", Zoot.GSON.toJson(inherited + .stream() + .map(Rank::getUuid) + .map(UUID::toString) + .collect(Collectors.toList()))); + + collection.replaceOne(Filters.eq("uuid", uuid.toString()), document, + new ReplaceOptions().upsert(true)); + + Zoot.get().getPidgin().sendPacket(new PacketRefreshRank(uuid, displayName)); + } + + public void delete() { + ranks.remove(uuid); + collection.deleteOne(Filters.eq("uuid", uuid.toString())); + + Zoot.get().getPidgin().sendPacket(new PacketDeleteRank(uuid)); + } + + public static void init() { + collection = Zoot.get().getMongoDatabase().getCollection("ranks"); + + Map> inheritanceReferences = new HashMap<>(); + + try (MongoCursor cursor = collection.find().iterator()) { + while (cursor.hasNext()) { + Document document = cursor.next(); + + Rank rank = new Rank(UUID.fromString(document.getString("uuid")), + document.getString("displayName")); + rank.load(document); + + Zoot.GSON.>fromJson(document.getString("permissions"), Zoot.LIST_STRING_TYPE) + .forEach(perm -> rank.getPermissions().add(perm)); + + List ranksToInherit = new ArrayList<>(); + + Zoot.GSON.>fromJson(document.getString("inherits"), Zoot.LIST_STRING_TYPE) + .stream() + .map(UUID::fromString) + .forEach(ranksToInherit::add); + + inheritanceReferences.put(rank, ranksToInherit); + + ranks.put(rank.getUuid(), rank); + } + } + + inheritanceReferences.forEach((rank, list) -> { + list.forEach(uuid -> { + Rank inherited = ranks.get(uuid); + + if (inherited != null) { + rank.getInherited().add(inherited); + } + }); + }); + + getDefaultRank(); + } + + /** + * Retrieves a rank by UUID if one exists. + * + * @param uuid The UUID. + * + * @return A rank that matches the given UUID if found. + */ + public static Rank getRankByUuid(UUID uuid) { + return ranks.get(uuid); + } + + /** + * Retrieves a rank by name if one exists. + * + * @param name The name. + * + * @return A rank that matches the given name if found. + */ + public static Rank getRankByDisplayName(String name) { + for (Rank rank : ranks.values()) { + if (rank.getDisplayName().equalsIgnoreCase(name)) { + return rank; + } + } + + return null; + } + + /** + * Retrieves the default rank or creates a new default rank if one does not already exist. + * + * @return A default rank, or a new default rank if unavailable. + */ + public static Rank getDefaultRank() { + for (Rank rank : ranks.values()) { + if (rank.isDefaultRank()) { + return rank; + } + } + + Rank defaultRank = new Rank("Default"); + defaultRank.setDefaultRank(true); + defaultRank.save(); + + ranks.put(defaultRank.getUuid(), defaultRank); + + return defaultRank; + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/RankTypeAdapter.java b/src/main/java/com/minexd/zoot/rank/RankTypeAdapter.java new file mode 100644 index 0000000..f944934 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/RankTypeAdapter.java @@ -0,0 +1,27 @@ +package com.minexd.zoot.rank; + +import com.qrakn.honcho.command.adapter.CommandTypeAdapter; +import java.util.ArrayList; +import java.util.List; + +public class RankTypeAdapter implements CommandTypeAdapter { + + @Override + public T convert(String string, Class type) { + return type.cast(Rank.getRankByDisplayName(string)); + } + + @Override + public List tabComplete(String string, Class type) { + List completed = new ArrayList<>(); + + for (Rank rank : Rank.getRanks().values()) { + if (rank.getDisplayName().toLowerCase().startsWith(string)) { + completed.add(rank.getDisplayName()); + } + } + + return completed; + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankAddPermissionCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankAddPermissionCommand.java new file mode 100644 index 0000000..71fa9a7 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankAddPermissionCommand.java @@ -0,0 +1,20 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = { "rank addpermission", "rank addperm" }, permission = "zoot.admin.rank", async = true) +public class RankAddPermissionCommand { + + public void execute(CommandSender sender, Rank rank, String permission) { + if (!rank.addPermission(permission)) { + sender.sendMessage(CC.RED + "That rank already has that permission."); + } else { + rank.save(); + sender.sendMessage(CC.GREEN + "Successfully added permission to rank."); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankCreateCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankCreateCommand.java new file mode 100644 index 0000000..fdcdd35 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankCreateCommand.java @@ -0,0 +1,23 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "rank create", permission = "zoot.admin.rank", async = true) +public class RankCreateCommand { + + public void execute(CommandSender sender, String name) { + if (Rank.getRankByDisplayName(name) != null) { + sender.sendMessage(CC.RED + "A rank with that name already exists."); + return; + } + + Rank rank = new Rank(name); + rank.save(); + + sender.sendMessage(CC.GREEN + "You created a new rank."); + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankDeleteCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankDeleteCommand.java new file mode 100644 index 0000000..ebee733 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankDeleteCommand.java @@ -0,0 +1,23 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "rank delete", permission = "zoot.admin.rank", async = true) +public class RankDeleteCommand { + + public void execute(CommandSender sender, Rank rank) { + if (rank == null) { + sender.sendMessage(Locale.RANK_NOT_FOUND.format()); + return; + } + + rank.delete(); + + sender.sendMessage(CC.GREEN + "You deleted the rank."); + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankHelpCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankHelpCommand.java new file mode 100644 index 0000000..5938368 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankHelpCommand.java @@ -0,0 +1,39 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = { "rank", "rank help" }, permission = "zoot.admin.rank") +public class RankHelpCommand { + + private static final String[][] HELP; + + static { + HELP = new String[][]{ + new String[]{ "ranks", "List all existing ranks" }, + new String[]{ "rank create ", "Create a new rank" }, + new String[]{ "rank delete ", "Delete an existing rank" }, + new String[]{ "rank setcolor ", "Set a rank's color" }, + new String[]{ "rank setprefix ", "Set a rank's prefix" }, + new String[]{ "rank setsuffix ", "Set a rank's suffix" }, + new String[]{ "rank setweight ", "Set a rank's weight" }, + new String[]{ "rank addperm ", "Add a permission to a rank" }, + new String[]{ "rank delperm ", "Remove a permission from a rank" }, + new String[]{ "rank inherit ", "Make a parent rank inherit a child rank" }, + new String[]{ "rank uninherit ", "Make a parent rank uninherit a child rank" } + }; + } + + public void execute(CommandSender sender) { + sender.sendMessage(CC.CHAT_BAR); + sender.sendMessage(CC.GOLD + "Rank Help"); + + for (String[] help : HELP) { + sender.sendMessage(CC.BLUE + help[0] + CC.GRAY + " - " + CC.RESET + help[1]); + } + + sender.sendMessage(CC.CHAT_BAR); + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankInfoCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankInfoCommand.java new file mode 100644 index 0000000..6558ba9 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankInfoCommand.java @@ -0,0 +1,60 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.Locale; +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.TextSplitter; +import com.qrakn.honcho.command.CommandMeta; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +@CommandMeta(label = "rank info", permission = "zoot.admin.rank", async = true) +public class RankInfoCommand { + + public void execute(Player player, Rank rank) { + if (rank == null) { + player.sendMessage(Locale.RANK_NOT_FOUND.format()); + } else { + List toSend = new ArrayList<>(); + toSend.add(CC.CHAT_BAR); + toSend.add(ChatColor.GOLD + "Rank Information " + ChatColor.GRAY + "(" + ChatColor.RESET + + rank.getColor() + rank.getDisplayName() + ChatColor.GRAY + ")"); + + toSend.add(ChatColor.GRAY + "Weight: " + ChatColor.RESET + rank.getWeight()); + toSend.add(ChatColor.GRAY + "Prefix: " + ChatColor.RESET + rank.getPrefix() + "Example"); + toSend.add(ChatColor.GRAY + "Suffix: " + ChatColor.RESET + rank.getSuffix() + "Example"); + + List permissions = rank.getAllPermissions(); + + toSend.add(""); + toSend.add(ChatColor.GRAY + "Permissions: " + ChatColor.RESET + "(" + permissions.size() + ")"); + + if (!permissions.isEmpty()) { + toSend.addAll(TextSplitter.split(46, StringUtils.join(permissions, " "), "", ", ")); + } + + List inherited = rank.getInherited(); + + toSend.add(""); + toSend.add(ChatColor.GRAY + "Inherits: " + ChatColor.RESET + "(" + inherited.size() + ")"); + + if (!rank.getInherited().isEmpty()) { + toSend.addAll(rank.getInherited() + .stream() + .map(inheritedRank -> inheritedRank.getColor() + inheritedRank.getDisplayName()) + .collect(Collectors.toList())); + } + + toSend.add(CC.CHAT_BAR); + + for (String line : toSend) { + player.sendMessage(line); + } + } + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankInheritCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankInheritCommand.java new file mode 100644 index 0000000..d5094bd --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankInheritCommand.java @@ -0,0 +1,32 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "rank inherit", permission = "zoot.admin.rank", async = true) +public class RankInheritCommand { + + public void execute(CommandSender sender, Rank parent, Rank child) { + if (parent == null) { + sender.sendMessage(ChatColor.RED + "A rank with that name does not exist (parent)."); + return; + } + + if (child == null) { + sender.sendMessage(ChatColor.RED + "A rank with that name does not exist (child)."); + return; + } + + if (parent.canInherit(child)) { + parent.getInherited().add(child); + parent.save(); + sender.sendMessage(ChatColor.GREEN + "You made the parent rank " + parent.getDisplayName() + + " inherit the child rank " + child.getDisplayName() + "."); + } else { + sender.sendMessage(ChatColor.RED + "That parent rank cannot inherit that child rank."); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankRemovePermissionCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankRemovePermissionCommand.java new file mode 100644 index 0000000..f174ed1 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankRemovePermissionCommand.java @@ -0,0 +1,22 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = { "rank removepermission", "rank removeperm", "rank deleteperm", "rank delperm" }, + permission = "zoot.admin.rank", + async = true) +public class RankRemovePermissionCommand { + + public void execute(CommandSender sender, Rank rank, String permission) { + if (!rank.removePermission(permission)) { + sender.sendMessage(CC.RED + "That rank does not have that permission."); + } else { + rank.save(); + sender.sendMessage(CC.GREEN + "Successfully removed permission from rank."); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankSetColorCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankSetColorCommand.java new file mode 100644 index 0000000..b8e42a3 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankSetColorCommand.java @@ -0,0 +1,29 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "rank setcolor", permission = "zoot.admin.rank", async = true) +public class RankSetColorCommand { + + public void execute(CommandSender sender, Rank rank, String color) { + if (rank == null) { + sender.sendMessage(CC.RED + "A rank with that name does not exist."); + return; + } + + if (color == null) { + sender.sendMessage(CC.RED + "That color is not valid."); + return; + } + + rank.setColor(CC.translate(color)); + rank.save(); + + sender.sendMessage(CC.GREEN + "You updated the rank's color."); + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankSetPrefixCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankSetPrefixCommand.java new file mode 100644 index 0000000..d18e316 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankSetPrefixCommand.java @@ -0,0 +1,23 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "rank setprefix", permission = "zoot.admin.rank", async = true) +public class RankSetPrefixCommand { + + public void execute(CommandSender sender, Rank rank, String prefix) { + if (rank == null) { + sender.sendMessage(CC.RED + "A rank with that name does not exist."); + return; + } + + rank.setPrefix(CC.translate(prefix)); + rank.save(); + + sender.sendMessage(CC.GREEN + "You updated the rank's prefix."); + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankSetSuffixCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankSetSuffixCommand.java new file mode 100644 index 0000000..3fbcffb --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankSetSuffixCommand.java @@ -0,0 +1,23 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "rank setsuffix", permission = "zoot.admin.rank", async = true) +public class RankSetSuffixCommand { + + public void execute(CommandSender sender, Rank rank, String suffix) { + if (rank == null) { + sender.sendMessage(CC.RED + "A rank with that name does not exist."); + return; + } + + rank.setSuffix(CC.translate(suffix)); + rank.save(); + + sender.sendMessage(CC.GREEN + "You updated the rank's suffix."); + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankSetWeightCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankSetWeightCommand.java new file mode 100644 index 0000000..bfa5aef --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankSetWeightCommand.java @@ -0,0 +1,30 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "rank setweight", permission = "zoot.admin.rank", async = true) +public class RankSetWeightCommand { + + public void execute(CommandSender sender, Rank rank, String weight) { + if (rank == null) { + sender.sendMessage(CC.RED + "A rank with that name does not exist."); + return; + } + + try { + Integer.parseInt(weight); + } catch (Exception e) { + sender.sendMessage(CC.RED + "Invalid number."); + return; + } + + rank.setWeight(Integer.parseInt(weight)); + rank.save(); + + sender.sendMessage(CC.GREEN + "You updated the rank's weight."); + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RankUninheritCommand.java b/src/main/java/com/minexd/zoot/rank/command/RankUninheritCommand.java new file mode 100644 index 0000000..4d4fc43 --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RankUninheritCommand.java @@ -0,0 +1,31 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.qrakn.honcho.command.CommandMeta; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "rank uninherit", permission = "zoot.admin.rank", async = true) +public class RankUninheritCommand { + + public void execute(CommandSender sender, Rank parent, Rank child) { + if (parent == null) { + sender.sendMessage(ChatColor.RED + "A rank with that name does not exist (parent)."); + return; + } + + if (child == null) { + sender.sendMessage(ChatColor.RED + "A rank with that name does not exist (child)."); + return; + } + + if (parent.getInherited().remove(child)) { + parent.save(); + sender.sendMessage(ChatColor.GREEN + "You made the parent rank " + parent.getDisplayName() + + " uninherit the child rank " + child.getDisplayName() + "."); + } else { + sender.sendMessage(ChatColor.RED + "That parent rank does not inherit that child rank."); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/rank/command/RanksCommand.java b/src/main/java/com/minexd/zoot/rank/command/RanksCommand.java new file mode 100644 index 0000000..b94a09f --- /dev/null +++ b/src/main/java/com/minexd/zoot/rank/command/RanksCommand.java @@ -0,0 +1,31 @@ +package com.minexd.zoot.rank.command; + +import com.minexd.zoot.rank.Rank; +import com.qrakn.honcho.command.CommandMeta; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +@CommandMeta(label = "ranks", permission = "zoot.admin.rank") +public class RanksCommand { + + public void execute(CommandSender sender) { + List ranks = new ArrayList<>(Rank.getRanks().values()); + ranks.sort(new Comparator() { + @Override + public int compare(Rank o1, Rank o2) { + return o2.getWeight() - o1.getWeight(); + } + }); + + sender.sendMessage(ChatColor.GOLD + ChatColor.BOLD.toString() + "Ranks"); + + for (Rank rank : ranks) { + sender.sendMessage(ChatColor.GRAY + " - " + ChatColor.RESET + rank.getColor() + rank.getDisplayName() + + ChatColor.RESET + " (Weight: " + rank.getWeight() + ")"); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/util/BaseEvent.java b/src/main/java/com/minexd/zoot/util/BaseEvent.java new file mode 100644 index 0000000..2dbf7c0 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/BaseEvent.java @@ -0,0 +1,23 @@ +package com.minexd.zoot.util; + +import com.minexd.zoot.Zoot; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class BaseEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public void call() { + Zoot.get().getServer().getPluginManager().callEvent(this); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/BukkitReflection.java b/src/main/java/com/minexd/zoot/util/BukkitReflection.java new file mode 100644 index 0000000..9b50c82 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/BukkitReflection.java @@ -0,0 +1,112 @@ +package com.minexd.zoot.util; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class BukkitReflection { + + private static final String CRAFT_BUKKIT_PACKAGE; + private static final String NET_MINECRAFT_SERVER_PACKAGE; + + private static final Class CRAFT_SERVER_CLASS; + private static final Method CRAFT_SERVER_GET_HANDLE_METHOD; + + private static final Class PLAYER_LIST_CLASS; + private static final Field PLAYER_LIST_MAX_PLAYERS_FIELD; + + private static final Class CRAFT_PLAYER_CLASS; + private static final Method CRAFT_PLAYER_GET_HANDLE_METHOD; + + private static final Class ENTITY_PLAYER_CLASS; + private static final Field ENTITY_PLAYER_PING_FIELD; + + private static final Class CRAFT_ITEM_STACK_CLASS; + private static final Method CRAFT_ITEM_STACK_AS_NMS_COPY_METHOD; + private static final Class ENTITY_ITEM_STACK_CLASS; + private static final Method ENTITY_ITEM_STACK_GET_NAME; + + private static final Class SPIGOT_CONFIG_CLASS; + private static final Field SPIGOT_CONFIG_BUNGEE_FIELD; + + static { + try { + String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; + + CRAFT_BUKKIT_PACKAGE = "org.bukkit.craftbukkit." + version + "."; + NET_MINECRAFT_SERVER_PACKAGE = "net.minecraft.server." + version + "."; + + CRAFT_SERVER_CLASS = Class.forName(CRAFT_BUKKIT_PACKAGE + "CraftServer"); + CRAFT_SERVER_GET_HANDLE_METHOD = CRAFT_SERVER_CLASS.getDeclaredMethod("getHandle"); + CRAFT_SERVER_GET_HANDLE_METHOD.setAccessible(true); + + PLAYER_LIST_CLASS = Class.forName(NET_MINECRAFT_SERVER_PACKAGE + "PlayerList"); + PLAYER_LIST_MAX_PLAYERS_FIELD = PLAYER_LIST_CLASS.getDeclaredField("maxPlayers"); + PLAYER_LIST_MAX_PLAYERS_FIELD.setAccessible(true); + + CRAFT_PLAYER_CLASS = Class.forName(CRAFT_BUKKIT_PACKAGE + "entity.CraftPlayer"); + CRAFT_PLAYER_GET_HANDLE_METHOD = CRAFT_PLAYER_CLASS.getDeclaredMethod("getHandle"); + CRAFT_PLAYER_GET_HANDLE_METHOD.setAccessible(true); + + ENTITY_PLAYER_CLASS = Class.forName(NET_MINECRAFT_SERVER_PACKAGE + "EntityPlayer"); + ENTITY_PLAYER_PING_FIELD = ENTITY_PLAYER_CLASS.getDeclaredField("ping"); + ENTITY_PLAYER_PING_FIELD.setAccessible(true); + + CRAFT_ITEM_STACK_CLASS = Class.forName(CRAFT_BUKKIT_PACKAGE + "inventory.CraftItemStack"); + CRAFT_ITEM_STACK_AS_NMS_COPY_METHOD = + CRAFT_ITEM_STACK_CLASS.getDeclaredMethod("asNMSCopy", ItemStack.class); + CRAFT_ITEM_STACK_AS_NMS_COPY_METHOD.setAccessible(true); + + ENTITY_ITEM_STACK_CLASS = Class.forName(NET_MINECRAFT_SERVER_PACKAGE + "ItemStack"); + ENTITY_ITEM_STACK_GET_NAME = ENTITY_ITEM_STACK_CLASS.getDeclaredMethod("getName"); + + SPIGOT_CONFIG_CLASS = Class.forName("org.spigotmc.SpigotConfig"); + SPIGOT_CONFIG_BUNGEE_FIELD = SPIGOT_CONFIG_CLASS.getDeclaredField("bungee"); + SPIGOT_CONFIG_BUNGEE_FIELD.setAccessible(true); + } catch (Exception e) { + e.printStackTrace(); + + throw new RuntimeException("Failed to initialize Bukkit/NMS Reflection"); + } + } + + public static int getPing(Player player) { + try { + int ping = ENTITY_PLAYER_PING_FIELD.getInt(CRAFT_PLAYER_GET_HANDLE_METHOD.invoke(player)); + + return ping > 0 ? ping : 0; + } catch (Exception e) { + return 1; + } + } + + public static void setMaxPlayers(Server server, int slots) { + try { + PLAYER_LIST_MAX_PLAYERS_FIELD.set(CRAFT_SERVER_GET_HANDLE_METHOD.invoke(server), slots); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static String getItemStackName(ItemStack itemStack) { + try { + return (String) ENTITY_ITEM_STACK_GET_NAME.invoke(CRAFT_ITEM_STACK_AS_NMS_COPY_METHOD.invoke(itemStack, itemStack)); + } catch (Exception e) { + e.printStackTrace(); + return ""; + } + } + + public static boolean isBungeeServer() { + try { + return (boolean) SPIGOT_CONFIG_BUNGEE_FIELD.get(null); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + +} diff --git a/src/main/java/com/minexd/zoot/util/CC.java b/src/main/java/com/minexd/zoot/util/CC.java new file mode 100644 index 0000000..91132ca --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/CC.java @@ -0,0 +1,123 @@ +package com.minexd.zoot.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.bukkit.ChatColor; + +public class CC { + + private static final Map MAP; + + public static final String BLUE; + public static final String AQUA; + public static final String YELLOW; + public static final String RED; + public static final String GRAY; + public static final String GOLD; + public static final String GREEN; + public static final String WHITE; + public static final String BLACK; + public static final String BOLD; + public static final String ITALIC; + public static final String UNDER_LINE; + public static final String STRIKE_THROUGH; + public static final String RESET; + public static final String MAGIC; + public static final String DARK_BLUE; + public static final String DARK_AQUA; + public static final String DARK_GRAY; + public static final String DARK_GREEN; + public static final String DARK_PURPLE; + public static final String DARK_RED; + public static final String PINK; + public static final String MENU_BAR; + public static final String CHAT_BAR; + public static final String SB_BAR; + + static { + MAP = new HashMap<>(); + MAP.put("pink", ChatColor.LIGHT_PURPLE); + MAP.put("orange", ChatColor.GOLD); + MAP.put("purple", ChatColor.DARK_PURPLE); + + for (ChatColor chatColor : ChatColor.values()) { + MAP.put(chatColor.name().toLowerCase().replace("_", ""), chatColor); + } + + BLUE = ChatColor.BLUE.toString(); + AQUA = ChatColor.AQUA.toString(); + YELLOW = ChatColor.YELLOW.toString(); + RED = ChatColor.RED.toString(); + GRAY = ChatColor.GRAY.toString(); + GOLD = ChatColor.GOLD.toString(); + GREEN = ChatColor.GREEN.toString(); + WHITE = ChatColor.WHITE.toString(); + BLACK = ChatColor.BLACK.toString(); + BOLD = ChatColor.BOLD.toString(); + ITALIC = ChatColor.ITALIC.toString(); + UNDER_LINE = ChatColor.UNDERLINE.toString(); + STRIKE_THROUGH = ChatColor.STRIKETHROUGH.toString(); + RESET = ChatColor.RESET.toString(); + MAGIC = ChatColor.MAGIC.toString(); + DARK_BLUE = ChatColor.DARK_BLUE.toString(); + DARK_AQUA = ChatColor.DARK_AQUA.toString(); + DARK_GRAY = ChatColor.DARK_GRAY.toString(); + DARK_GREEN = ChatColor.DARK_GREEN.toString(); + DARK_PURPLE = ChatColor.DARK_PURPLE.toString(); + DARK_RED = ChatColor.DARK_RED.toString(); + PINK = ChatColor.LIGHT_PURPLE.toString(); + MENU_BAR = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH.toString() + "------------------------"; + CHAT_BAR = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH.toString() + "------------------------------------------------"; + SB_BAR = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH.toString() + "----------------------"; + } + + public static Set getColorNames() { + return MAP.keySet(); + } + + public static ChatColor getColorFromName(String name) { + if (MAP.containsKey(name.trim().toLowerCase())) { + return MAP.get(name.trim().toLowerCase()); + } + + ChatColor color; + + try { + color = ChatColor.valueOf(name.toUpperCase().replace(" ", "_")); + } catch (Exception e) { + return null; + } + + return color; + } + + public static String translate(String in) { + return ChatColor.translateAlternateColorCodes('&', in); + } + + public static List translate(List lines) { + List toReturn = new ArrayList<>(); + + for (String line : lines) { + toReturn.add(ChatColor.translateAlternateColorCodes('&', line)); + } + + return toReturn; + } + + public static List translate(String[] lines) { + List toReturn = new ArrayList<>(); + + for (String line : lines) { + if (line != null) { + toReturn.add(ChatColor.translateAlternateColorCodes('&', line)); + } + } + + return toReturn; + } + +} diff --git a/src/main/java/com/minexd/zoot/util/ChatHelper.java b/src/main/java/com/minexd/zoot/util/ChatHelper.java new file mode 100644 index 0000000..3be01b0 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/ChatHelper.java @@ -0,0 +1,21 @@ +package com.minexd.zoot.util; + +import com.minexd.zoot.chat.util.ChatComponentBuilder; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; + +public class ChatHelper { + + public static ClickEvent click(String command) { + return new ClickEvent(ClickEvent.Action.RUN_COMMAND, command); + } + + public static ClickEvent suggest(String command) { + return new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command); + } + + public static HoverEvent hover(String text) { + return new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentBuilder("").parse(text).create()); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/Cooldown.java b/src/main/java/com/minexd/zoot/util/Cooldown.java new file mode 100644 index 0000000..70a40bc --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/Cooldown.java @@ -0,0 +1,40 @@ +package com.minexd.zoot.util; + +import lombok.Data; + +@Data +public class Cooldown { + + private long start = System.currentTimeMillis(); + private long expire; + private boolean notified; + + public Cooldown(long duration) { + this.expire = this.start + duration; + + if (duration == 0) { + this.notified = true; + } + } + + public long getPassed() { + return System.currentTimeMillis() - this.start; + } + + public long getRemaining() { + return this.expire - System.currentTimeMillis(); + } + + public boolean hasExpired() { + return System.currentTimeMillis() - this.expire >= 0; + } + + public String getTimeLeft() { + if (this.getRemaining() >= 60_000) { + return TimeUtil.millisToRoundedTime(this.getRemaining()); + } else { + return TimeUtil.millisToSeconds(this.getRemaining()); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/util/ItemBuilder.java b/src/main/java/com/minexd/zoot/util/ItemBuilder.java new file mode 100644 index 0000000..d926f6c --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/ItemBuilder.java @@ -0,0 +1,121 @@ +package com.minexd.zoot.util; + +import java.util.ArrayList; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class ItemBuilder implements Listener { + + private ItemStack is; + + public ItemBuilder(Material mat) { + is = new ItemStack(mat); + } + + public ItemBuilder(ItemStack is) { + this.is = is; + } + + public ItemBuilder amount(int amount) { + is.setAmount(amount); + return this; + } + + public ItemBuilder name(String name) { + ItemMeta meta = is.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); + is.setItemMeta(meta); + return this; + } + + public ItemBuilder lore(String name) { + ItemMeta meta = is.getItemMeta(); + List lore = meta.getLore(); + + if (lore == null) { + lore = new ArrayList<>(); + } + + lore.add(ChatColor.translateAlternateColorCodes('&', name)); + meta.setLore(lore); + + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder lore(String... lore) { + List toSet = new ArrayList<>(); + ItemMeta meta = is.getItemMeta(); + + for (String string : lore) { + toSet.add(ChatColor.translateAlternateColorCodes('&', string)); + } + + meta.setLore(toSet); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder lore(List lore) { + List toSet = new ArrayList<>(); + ItemMeta meta = is.getItemMeta(); + + for (String string : lore) { + toSet.add(ChatColor.translateAlternateColorCodes('&', string)); + } + + meta.setLore(toSet); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder durability(int durability) { + is.setDurability((short) durability); + return this; + } + + public ItemBuilder enchantment(Enchantment enchantment, int level) { + is.addUnsafeEnchantment(enchantment, level); + return this; + } + + public ItemBuilder enchantment(Enchantment enchantment) { + is.addUnsafeEnchantment(enchantment, 1); + return this; + } + + public ItemBuilder type(Material material) { + is.setType(material); + return this; + } + + public ItemBuilder clearLore() { + ItemMeta meta = is.getItemMeta(); + + meta.setLore(new ArrayList<>()); + is.setItemMeta(meta); + + return this; + } + + public ItemBuilder clearEnchantments() { + for (Enchantment e : is.getEnchantments().keySet()) { + is.removeEnchantment(e); + } + + return this; + } + + public ItemStack build() { + return is; + } + +} \ No newline at end of file diff --git a/src/main/java/com/minexd/zoot/util/LocationUtil.java b/src/main/java/com/minexd/zoot/util/LocationUtil.java new file mode 100644 index 0000000..9b40fca --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/LocationUtil.java @@ -0,0 +1,42 @@ +package com.minexd.zoot.util; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; + +public class LocationUtil { + + public static Location[] getFaces(Location start) { + Location[] faces = new Location[4]; + faces[0] = new Location(start.getWorld(), start.getX() + 1, start.getY(), start.getZ()); + faces[1] = new Location(start.getWorld(), start.getX() - 1, start.getY(), start.getZ()); + faces[2] = new Location(start.getWorld(), start.getX(), start.getY() + 1, start.getZ()); + faces[3] = new Location(start.getWorld(), start.getX(), start.getY() - 1, start.getZ()); + return faces; + } + + public static String serialize(Location location) { + if (location == null) { + return "null"; + } + + return location.getWorld().getName() + ":" + location.getX() + ":" + location.getY() + ":" + location.getZ() + + ":" + location.getYaw() + ":" + location.getPitch(); + } + + public static Location deserialize(String source) { + if (source == null) { + return null; + } + + String[] split = source.split(":"); + World world = Bukkit.getServer().getWorld(split[0]); + + if (world == null) { + return null; + } + + return new Location(world, Double.parseDouble(split[1]), Double.parseDouble(split[2]), Double.parseDouble(split[3]), Float.parseFloat(split[4]), Float.parseFloat(split[5])); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/PotionUtil.java b/src/main/java/com/minexd/zoot/util/PotionUtil.java new file mode 100644 index 0000000..99e8346 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/PotionUtil.java @@ -0,0 +1,21 @@ +package com.minexd.zoot.util; + +import org.bukkit.potion.PotionEffectType; + +public class PotionUtil { + + public static String getName(PotionEffectType potionEffectType) { + if (potionEffectType.getName().equalsIgnoreCase("fire_resistance")) { + return "Fire Resistance"; + } else if (potionEffectType.getName().equalsIgnoreCase("speed")) { + return "Speed"; + } else if (potionEffectType.getName().equalsIgnoreCase("weakness")) { + return "Weakness"; + } else if (potionEffectType.getName().equalsIgnoreCase("slowness")) { + return "Slowness"; + } else { + return "Unknown"; + } + } + +} diff --git a/src/main/java/com/minexd/zoot/util/TextSplitter.java b/src/main/java/com/minexd/zoot/util/TextSplitter.java new file mode 100644 index 0000000..fc2be38 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/TextSplitter.java @@ -0,0 +1,50 @@ +package com.minexd.zoot.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class TextSplitter { + + public static List split(int length, List lines, String linePrefix, String wordSuffix) { + StringBuilder builder = new StringBuilder(); + + for (String line : lines) { + builder.append(line.trim()); + builder.append(" "); + } + + return split(length, builder.substring(0, builder.length() - 1), linePrefix, wordSuffix); + } + + public static List split(int length, String text, String linePrefix, String wordSuffix) { + if (text.length() <= length) { + return Collections.singletonList(linePrefix + text); + } + + List lines = new ArrayList<>(); + String[] split = text.split(" "); + StringBuilder builder = new StringBuilder(linePrefix); + + for (int i = 0; i < split.length; ++i) { + if (builder.length() + split[i].length() >= length) { + lines.add(builder.toString()); + builder = new StringBuilder(linePrefix); + } + + builder.append(split[i]); + builder.append(wordSuffix); + + if (i == split.length - 1) { + builder.replace(builder.length() - wordSuffix.length(), builder.length(), ""); + } + } + + if (builder.length() != 0) { + lines.add(builder.toString()); + } + + return lines; + } + +} diff --git a/src/main/java/com/minexd/zoot/util/TimeUtil.java b/src/main/java/com/minexd/zoot/util/TimeUtil.java new file mode 100644 index 0000000..e15f7a1 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/TimeUtil.java @@ -0,0 +1,146 @@ +package com.minexd.zoot.util; + +import java.sql.Timestamp; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class TimeUtil { + + private static final String HOUR_FORMAT = "%02d:%02d:%02d"; + private static final String MINUTE_FORMAT = "%02d:%02d"; + + private TimeUtil() { + throw new RuntimeException("Cannot instantiate a utility class."); + } + + public static String millisToTimer(long millis) { + long seconds = millis / 1000L; + + if (seconds > 3600L) { + return String.format(HOUR_FORMAT, seconds / 3600L, seconds % 3600L / 60L, seconds % 60L); + } else { + return String.format(MINUTE_FORMAT, seconds / 60L, seconds % 60L); + } + } + + /** + * Return the amount of seconds from milliseconds. + * Note: We explicitly use 1000.0F (float) instead of 1000L (long). + * + * @param millis the amount of time in milliseconds + * @return the seconds + */ + public static String millisToSeconds(long millis) { + return new DecimalFormat("#0.0").format(millis / 1000.0F); + } + + public static String dateToString(Date date, String secondaryColor) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + return new SimpleDateFormat("MMM dd yyyy " + (secondaryColor == null ? "" : secondaryColor) + + "(hh:mm aa zz)").format(date); + } + + public static Timestamp addDuration(long duration) { + return truncateTimestamp(new Timestamp(System.currentTimeMillis() + duration)); + } + + public static Timestamp truncateTimestamp(Timestamp timestamp) { + if (timestamp.toLocalDateTime().getYear() > 2037) { + timestamp.setYear(2037); + } + + return timestamp; + } + + public static Timestamp addDuration(Timestamp timestamp) { + return truncateTimestamp(new Timestamp(System.currentTimeMillis() + timestamp.getTime())); + } + + public static Timestamp fromMillis(long millis) { + return new Timestamp(millis); + } + + public static Timestamp getCurrentTimestamp() { + return new Timestamp(System.currentTimeMillis()); + } + + public static String millisToRoundedTime(long millis) { + millis += 1L; + + long seconds = millis / 1000L; + long minutes = seconds / 60L; + long hours = minutes / 60L; + long days = hours / 24L; + long weeks = days / 7L; + long months = weeks / 4L; + long years = months / 12L; + + if (years > 0) { + return years + " year" + (years == 1 ? "" : "s"); + } else if (months > 0) { + return months + " month" + (months == 1 ? "" : "s"); + } else if (weeks > 0) { + return weeks + " week" + (weeks == 1 ? "" : "s"); + } else if (days > 0) { + return days + " day" + (days == 1 ? "" : "s"); + } else if (hours > 0) { + return hours + " hour" + (hours == 1 ? "" : "s"); + } else if (minutes > 0) { + return minutes + " minute" + (minutes == 1 ? "" : "s"); + } else { + return seconds + " second" + (seconds == 1 ? "" : "s"); + } + } + + public static long parseTime(String time) { + long totalTime = 0L; + boolean found = false; + Matcher matcher = Pattern.compile("\\d+\\D+").matcher(time); + + while (matcher.find()) { + String s = matcher.group(); + Long value = Long.parseLong(s.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)")[0]); + String type = s.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)")[1]; + + switch (type) { + case "s": + totalTime += value; + found = true; + break; + case "m": + totalTime += value * 60; + found = true; + break; + case "h": + totalTime += value * 60 * 60; + found = true; + break; + case "d": + totalTime += value * 60 * 60 * 24; + found = true; + break; + case "w": + totalTime += value * 60 * 60 * 24 * 7; + found = true; + break; + case "M": + totalTime += value * 60 * 60 * 24 * 30; + found = true; + break; + case "y": + totalTime += value * 60 * 60 * 24 * 365; + found = true; + break; + } + } + + return !found ? -1 : totalTime * 1000; + } + +} diff --git a/src/main/java/com/minexd/zoot/util/adapter/ChatColorTypeAdapter.java b/src/main/java/com/minexd/zoot/util/adapter/ChatColorTypeAdapter.java new file mode 100644 index 0000000..45925b2 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/adapter/ChatColorTypeAdapter.java @@ -0,0 +1,30 @@ +package com.minexd.zoot.util.adapter; + +import com.minexd.zoot.util.CC; +import com.qrakn.honcho.command.adapter.CommandTypeAdapter; +import java.util.ArrayList; +import java.util.List; + +public class ChatColorTypeAdapter implements CommandTypeAdapter { + + @Override + public T convert(String string, Class type) { + return type.cast(CC.getColorFromName(string)); + } + + @Override + public List tabComplete(String string, Class type) { + final String compare = string.trim().toLowerCase(); + + List completed = new ArrayList<>(); + + for (String colorName : CC.getColorNames()) { + if (colorName.startsWith(compare)) { + completed.add(colorName); + } + } + + return completed; + } + +} diff --git a/src/main/java/com/minexd/zoot/util/callback/Callback.java b/src/main/java/com/minexd/zoot/util/callback/Callback.java new file mode 100644 index 0000000..c41f89c --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/callback/Callback.java @@ -0,0 +1,12 @@ +package com.minexd.zoot.util.callback; + +import java.io.Serializable; + +public interface Callback extends Serializable { + + /** + * A callback for running a task on a set of data. + */ + void callback(); + +} diff --git a/src/main/java/com/minexd/zoot/util/callback/ReturnableTypeCallback.java b/src/main/java/com/minexd/zoot/util/callback/ReturnableTypeCallback.java new file mode 100644 index 0000000..fc1b7aa --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/callback/ReturnableTypeCallback.java @@ -0,0 +1,7 @@ +package com.minexd.zoot.util.callback; + +public interface ReturnableTypeCallback { + + T call(); + +} diff --git a/src/main/java/com/minexd/zoot/util/callback/TypeCallback.java b/src/main/java/com/minexd/zoot/util/callback/TypeCallback.java new file mode 100644 index 0000000..a3aa661 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/callback/TypeCallback.java @@ -0,0 +1,14 @@ +package com.minexd.zoot.util.callback; + +import java.io.Serializable; + +public interface TypeCallback extends Serializable { + + /** + * A callback for running a task on a set of data. + * + * @param data the data needed to run the task. + */ + void callback(T data); + +} diff --git a/src/main/java/com/minexd/zoot/util/duration/Duration.java b/src/main/java/com/minexd/zoot/util/duration/Duration.java new file mode 100644 index 0000000..b809df5 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/duration/Duration.java @@ -0,0 +1,64 @@ +package com.minexd.zoot.util.duration; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import lombok.Getter; + +public class Duration { + + @Getter private long value; + + public Duration(long value) { + this.value = value; + } + + public static Duration fromString(String source) { + if (source.equalsIgnoreCase("perm") || source.equalsIgnoreCase("permanent")) { + return new Duration(Integer.MAX_VALUE); + } + + long totalTime = 0L; + boolean found = false; + Matcher matcher = Pattern.compile("\\d+\\D+").matcher(source); + + while (matcher.find()) { + String s = matcher.group(); + Long value = Long.parseLong(s.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)")[0]); + String type = s.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)")[1]; + + switch (type) { + case "s": + totalTime += value; + found = true; + break; + case "m": + totalTime += value * 60; + found = true; + break; + case "h": + totalTime += value * 60 * 60; + found = true; + break; + case "d": + totalTime += value * 60 * 60 * 24; + found = true; + break; + case "w": + totalTime += value * 60 * 60 * 24 * 7; + found = true; + break; + case "M": + totalTime += value * 60 * 60 * 24 * 30; + found = true; + break; + case "y": + totalTime += value * 60 * 60 * 24 * 365; + found = true; + break; + } + } + + return new Duration(!found ? -1 : totalTime * 1000); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/duration/DurationTypeAdapter.java b/src/main/java/com/minexd/zoot/util/duration/DurationTypeAdapter.java new file mode 100644 index 0000000..3e869d8 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/duration/DurationTypeAdapter.java @@ -0,0 +1,13 @@ +package com.minexd.zoot.util.duration; + +import com.qrakn.honcho.command.adapter.CommandTypeAdapter; + +public class DurationTypeAdapter implements CommandTypeAdapter { + + @Override + public T convert(String string, Class type) { + return type.cast(Duration.fromString(string)); + } + +} + diff --git a/src/main/java/com/minexd/zoot/util/json/JsonChain.java b/src/main/java/com/minexd/zoot/util/json/JsonChain.java new file mode 100644 index 0000000..98787d5 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/json/JsonChain.java @@ -0,0 +1,39 @@ +package com.minexd.zoot.util.json; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public class JsonChain { + + private JsonObject json = new JsonObject(); + + public JsonChain addProperty(String property, String value) { + this.json.addProperty(property, value); + return this; + } + + public JsonChain addProperty(String property, Number value) { + this.json.addProperty(property, value); + return this; + } + + public JsonChain addProperty(String property, Boolean value) { + this.json.addProperty(property, value); + return this; + } + + public JsonChain addProperty(String property, Character value) { + this.json.addProperty(property, value); + return this; + } + + public JsonChain add(String property, JsonElement element) { + this.json.add(property, element); + return this; + } + + public JsonObject get() { + return this.json; + } + +} diff --git a/src/main/java/com/minexd/zoot/util/json/JsonDeserializer.java b/src/main/java/com/minexd/zoot/util/json/JsonDeserializer.java new file mode 100644 index 0000000..b658af1 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/json/JsonDeserializer.java @@ -0,0 +1,9 @@ +package com.minexd.zoot.util.json; + +import com.google.gson.JsonObject; + +public interface JsonDeserializer { + + T deserialize(JsonObject object); + +} diff --git a/src/main/java/com/minexd/zoot/util/json/JsonSerializer.java b/src/main/java/com/minexd/zoot/util/json/JsonSerializer.java new file mode 100644 index 0000000..b7d0b2a --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/json/JsonSerializer.java @@ -0,0 +1,9 @@ +package com.minexd.zoot.util.json; + +import com.google.gson.JsonObject; + +public interface JsonSerializer { + + JsonObject serialize(T t); + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/Button.java b/src/main/java/com/minexd/zoot/util/menu/Button.java new file mode 100644 index 0000000..b509d20 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/Button.java @@ -0,0 +1,54 @@ +package com.minexd.zoot.util.menu; + +import org.apache.commons.lang.StringUtils; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public abstract class Button { + + public static Button placeholder(final Material material, final byte data, String... title) { + return (new Button() { + public ItemStack getButtonItem(Player player) { + ItemStack it = new ItemStack(material, 1, data); + ItemMeta meta = it.getItemMeta(); + + meta.setDisplayName(StringUtils.join(title)); + it.setItemMeta(meta); + + return it; + } + }); + } + + public static void playFail(Player player) { + player.playSound(player.getLocation(), Sound.DIG_GRASS, 20F, 0.1F); + + } + + public static void playSuccess(Player player) { + player.playSound(player.getLocation(), Sound.NOTE_PIANO, 20F, 15F); + } + + public static void playNeutral(Player player) { + player.playSound(player.getLocation(), Sound.CLICK, 20F, 1F); + } + + public abstract ItemStack getButtonItem(Player player); + + public void clicked(Player player, ClickType clickType) {} + + public void clicked(Player player, int slot, ClickType clickType, int hotbarSlot) {} + + public boolean shouldCancel(Player player, ClickType clickType) { + return true; + } + + public boolean shouldUpdate(Player player, ClickType clickType) { + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/com/minexd/zoot/util/menu/Menu.java b/src/main/java/com/minexd/zoot/util/menu/Menu.java new file mode 100644 index 0000000..e2c4876 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/Menu.java @@ -0,0 +1,136 @@ +package com.minexd.zoot.util.menu; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.util.CC; +import java.util.HashMap; +import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +@Getter +@Setter +public abstract class Menu { + + public static Map currentlyOpenedMenus = new HashMap<>(); + + @Getter protected Zoot zoot = Zoot.get(); + private Map buttons = new HashMap<>(); + private boolean autoUpdate = false; + private boolean updateAfterClick = true; + private boolean closedByMenu = false; + private boolean placeholder = false; + private Button placeholderButton = Button.placeholder(Material.STAINED_GLASS_PANE, (byte) 15, " "); + + private ItemStack createItemStack(Player player, Button button) { + ItemStack item = button.getButtonItem(player); + + if (item.getType() != Material.SKULL_ITEM) { + ItemMeta meta = item.getItemMeta(); + + if (meta != null && meta.hasDisplayName()) { + meta.setDisplayName(meta.getDisplayName() + "§b§c§d§e"); + } + + item.setItemMeta(meta); + } + + return item; + } + + public void openMenu(final Player player) { + this.buttons = this.getButtons(player); + + Menu previousMenu = Menu.currentlyOpenedMenus.get(player.getName()); + Inventory inventory = null; + int size = this.getSize() == -1 ? this.size(this.buttons) : this.getSize(); + boolean update = false; + String title = CC.translate(this.getTitle(player)); + + if (title.length() > 32) { + title = title.substring(0, 32); + } + + if (player.getOpenInventory() != null) { + if (previousMenu == null) { + player.closeInventory(); + } else { + int previousSize = player.getOpenInventory().getTopInventory().getSize(); + + if (previousSize == size && player.getOpenInventory().getTopInventory().getTitle().equals(title)) { + inventory = player.getOpenInventory().getTopInventory(); + update = true; + } else { + previousMenu.setClosedByMenu(true); + player.closeInventory(); + } + } + } + + if (inventory == null) { + inventory = Bukkit.createInventory(player, size, title); + } + + inventory.setContents(new ItemStack[inventory.getSize()]); + + currentlyOpenedMenus.put(player.getName(), this); + + for (Map.Entry buttonEntry : this.buttons.entrySet()) { + inventory.setItem(buttonEntry.getKey(), createItemStack(player, buttonEntry.getValue())); + } + + if (this.isPlaceholder()) { + for (int index = 0; index < size; index++) { + if (this.buttons.get(index) == null) { + this.buttons.put(index, this.placeholderButton); + inventory.setItem(index, this.placeholderButton.getButtonItem(player)); + } + } + } + + if (update) { + player.updateInventory(); + } else { + player.openInventory(inventory); + } + + this.onOpen(player); + this.setClosedByMenu(false); + } + + public int size(Map buttons) { + int highest = 0; + + for (int buttonValue : buttons.keySet()) { + if (buttonValue > highest) { + highest = buttonValue; + } + } + + return (int) (Math.ceil((highest + 1) / 9D) * 9D); + } + + public int getSize() { + return -1; + } + + public int getSlot(int x, int y) { + return ((9 * y) + x); + } + + public abstract String getTitle(Player player); + + public abstract Map getButtons(Player player); + + public void onOpen(Player player) { + } + + public void onClose(Player player) { + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/MenuListener.java b/src/main/java/com/minexd/zoot/util/menu/MenuListener.java new file mode 100644 index 0000000..b27a0fa --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/MenuListener.java @@ -0,0 +1,93 @@ +package com.minexd.zoot.util.menu; + +import com.minexd.zoot.Zoot; +import com.minexd.zoot.bootstrap.BootstrappedListener; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; + +public class MenuListener extends BootstrappedListener { + + public MenuListener(Zoot zoot) { + super(zoot); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onButtonPress(InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + Menu openMenu = Menu.currentlyOpenedMenus.get(player.getName()); + + if (openMenu != null) { + if (event.getSlot() != event.getRawSlot()) { + if ((event.getClick() == ClickType.SHIFT_LEFT || event.getClick() == ClickType.SHIFT_RIGHT)) { + event.setCancelled(true); + } + + return; + } + + if (openMenu.getButtons().containsKey(event.getSlot())) { + Button button = openMenu.getButtons().get(event.getSlot()); + boolean cancel = button.shouldCancel(player, event.getClick()); + + if (!cancel && (event.getClick() == ClickType.SHIFT_LEFT || event.getClick() == ClickType.SHIFT_RIGHT)) { + event.setCancelled(true); + + if (event.getCurrentItem() != null) { + player.getInventory().addItem(event.getCurrentItem()); + } + } else { + event.setCancelled(cancel); + } + + button.clicked(player, event.getClick()); + button.clicked(player, event.getSlot(), event.getClick(), event.getHotbarButton()); + + if (Menu.currentlyOpenedMenus.containsKey(player.getName())) { + Menu newMenu = Menu.currentlyOpenedMenus.get(player.getName()); + + if (newMenu == openMenu) { + boolean buttonUpdate = button.shouldUpdate(player, event.getClick()); + + if ((newMenu.isUpdateAfterClick() && buttonUpdate) || buttonUpdate) { + openMenu.setClosedByMenu(true); + newMenu.openMenu(player); + } + } + } else if (button.shouldUpdate(player, event.getClick())) { + openMenu.setClosedByMenu(true); + openMenu.openMenu(player); + } + + if (event.isCancelled()) { + Bukkit.getScheduler().runTaskLater(zoot, player::updateInventory, 1L); + } + } else { + if (event.getCurrentItem() != null) { + event.setCancelled(true); + } + + if ((event.getClick() == ClickType.SHIFT_LEFT || event.getClick() == ClickType.SHIFT_RIGHT)) { + event.setCancelled(true); + } + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onInventoryClose(InventoryCloseEvent event) { + Player player = (Player) event.getPlayer(); + Menu openMenu = Menu.currentlyOpenedMenus.get(player.getName()); + + if (openMenu != null) { + openMenu.onClose(player); + + Menu.currentlyOpenedMenus.remove(player.getName()); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/minexd/zoot/util/menu/button/BackButton.java b/src/main/java/com/minexd/zoot/util/menu/button/BackButton.java new file mode 100644 index 0000000..cb9a0e2 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/button/BackButton.java @@ -0,0 +1,36 @@ +package com.minexd.zoot.util.menu.button; + +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.ItemBuilder; +import com.minexd.zoot.util.menu.Button; +import com.minexd.zoot.util.menu.Menu; +import java.util.Arrays; +import lombok.AllArgsConstructor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +@AllArgsConstructor +public class BackButton extends Button { + + private Menu back; + + @Override + public ItemStack getButtonItem(Player player) { + return new ItemBuilder(Material.REDSTONE) + .name(CC.RED + CC.BOLD + "Back") + .lore(Arrays.asList( + CC.RED + "Click here to return to", + CC.RED + "the previous menu.") + ) + .build(); + } + + @Override + public void clicked(Player player, ClickType clickType) { + Button.playNeutral(player); + back.openMenu(player); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/button/ConfirmationButton.java b/src/main/java/com/minexd/zoot/util/menu/button/ConfirmationButton.java new file mode 100644 index 0000000..5803af9 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/button/ConfirmationButton.java @@ -0,0 +1,54 @@ +package com.minexd.zoot.util.menu.button; + +import com.minexd.zoot.util.callback.TypeCallback; +import com.minexd.zoot.util.menu.Button; +import com.minexd.zoot.util.menu.Menu; +import lombok.AllArgsConstructor; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +@AllArgsConstructor +public class ConfirmationButton extends Button { + + private boolean confirm; + private TypeCallback callback; + private boolean closeAfterResponse; + + @Override + public ItemStack getButtonItem(Player player) { + ItemStack itemStack = new ItemStack(Material.WOOL, 1, this.confirm ? ((byte) 5) : ((byte) 14)); + ItemMeta itemMeta = itemStack.getItemMeta(); + + itemMeta.setDisplayName(this.confirm ? ChatColor.GREEN + "Confirm" : ChatColor.RED + "Cancel"); + itemStack.setItemMeta(itemMeta); + + return itemStack; + } + + @Override + public void clicked(Player player, ClickType clickType) { + if (this.confirm) { + player.playSound(player.getLocation(), Sound.NOTE_PIANO, 20f, 0.1f); + } else { + player.playSound(player.getLocation(), Sound.DIG_GRAVEL, 20f, 0.1F); + } + + if (this.closeAfterResponse) { + Menu menu = Menu.currentlyOpenedMenus.get(player.getName()); + + if (menu != null) { + menu.setClosedByMenu(true); + } + + player.closeInventory(); + } + + this.callback.callback(this.confirm); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/button/DisplayButton.java b/src/main/java/com/minexd/zoot/util/menu/button/DisplayButton.java new file mode 100644 index 0000000..1e537df --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/button/DisplayButton.java @@ -0,0 +1,34 @@ +package com.minexd.zoot.util.menu.button; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import com.minexd.zoot.util.menu.Button; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +@AllArgsConstructor +@Getter +@Setter +public class DisplayButton extends Button { + + private ItemStack itemStack; + private boolean cancel; + + @Override + public ItemStack getButtonItem(Player player) { + if (this.itemStack == null) { + return new ItemStack(Material.AIR); + } else { + return this.itemStack; + } + } + + @Override + public boolean shouldCancel(Player player, ClickType clickType) { + return this.cancel; + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/button/JumpToMenuButton.java b/src/main/java/com/minexd/zoot/util/menu/button/JumpToMenuButton.java new file mode 100644 index 0000000..107c1ed --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/button/JumpToMenuButton.java @@ -0,0 +1,29 @@ +package com.minexd.zoot.util.menu.button; + +import com.minexd.zoot.util.menu.Button; +import com.minexd.zoot.util.menu.Menu; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +public class JumpToMenuButton extends Button { + + private Menu menu; + private ItemStack itemStack; + + public JumpToMenuButton(Menu menu, ItemStack itemStack) { + this.menu = menu; + this.itemStack = itemStack; + } + + @Override + public ItemStack getButtonItem(Player player) { + return itemStack; + } + + @Override + public void clicked(Player player, ClickType clickType) { + menu.openMenu(player); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/menus/ConfirmMenu.java b/src/main/java/com/minexd/zoot/util/menu/menus/ConfirmMenu.java new file mode 100644 index 0000000..76c31c5 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/menus/ConfirmMenu.java @@ -0,0 +1,52 @@ +package com.minexd.zoot.util.menu.menus; + +import com.minexd.zoot.util.menu.Button; +import com.minexd.zoot.util.menu.Menu; +import com.minexd.zoot.util.menu.button.ConfirmationButton; +import com.minexd.zoot.util.callback.TypeCallback; +import java.util.HashMap; +import java.util.Map; +import org.bukkit.entity.Player; + +public class ConfirmMenu extends Menu { + + private String title; + private TypeCallback response; + private boolean closeAfterResponse; + private Button[] centerButtons; + + public ConfirmMenu(String title, TypeCallback response, boolean closeAfter, Button... centerButtons) { + this.title = title; + this.response = response; + this.closeAfterResponse = closeAfter; + this.centerButtons = centerButtons; + } + + @Override + public Map getButtons(Player player) { + HashMap buttons = new HashMap<>(); + + for (int x = 0; x < 3; x++) { + for (int y = 0; y < 3; y++) { + buttons.put(getSlot(x, y), new ConfirmationButton(true, response, closeAfterResponse)); + buttons.put(getSlot(8 - x, y), new ConfirmationButton(false, response, closeAfterResponse)); + } + } + + if (centerButtons != null) { + for (int i = 0; i < centerButtons.length; i++) { + if (centerButtons[i] != null) { + buttons.put(getSlot(4, i), centerButtons[i]); + } + } + } + + return buttons; + } + + @Override + public String getTitle(Player player) { + return title; + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/pagination/FilterablePaginatedMenu.java b/src/main/java/com/minexd/zoot/util/menu/pagination/FilterablePaginatedMenu.java new file mode 100644 index 0000000..4e8e90b --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/pagination/FilterablePaginatedMenu.java @@ -0,0 +1,39 @@ +package com.minexd.zoot.util.menu.pagination; + +import com.minexd.zoot.util.menu.Button; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; + +public abstract class FilterablePaginatedMenu extends PaginatedMenu { + + @Getter private final List> filters; + @Getter @Setter private int scrollIndex = 0; + + { + filters = generateFilters(); + } + + @Override + public Map getGlobalButtons(Player player) { + Map buttons = new HashMap<>(); + buttons.put(7, new PageFilterButton<>(this)); + return buttons; + } + + @Override + public Map getAllPagesButtons(Player player) { + return getFilteredButtons(player); + } + + public abstract Map getFilteredButtons(Player player); + + public List> generateFilters() { + return new ArrayList<>(); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/pagination/JumpToPageButton.java b/src/main/java/com/minexd/zoot/util/menu/pagination/JumpToPageButton.java new file mode 100644 index 0000000..c443c0f --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/pagination/JumpToPageButton.java @@ -0,0 +1,45 @@ +package com.minexd.zoot.util.menu.pagination; + +import com.minexd.zoot.util.menu.Button; +import java.util.Arrays; +import lombok.AllArgsConstructor; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +@AllArgsConstructor +public class JumpToPageButton extends Button { + + private int page; + private PaginatedMenu menu; + private boolean current; + + @Override + public ItemStack getButtonItem(Player player) { + ItemStack itemStack = new ItemStack(this.current ? Material.ENCHANTED_BOOK : Material.BOOK, this.page); + ItemMeta itemMeta = itemStack.getItemMeta(); + + itemMeta.setDisplayName(ChatColor.YELLOW + "Page " + this.page); + + if (this.current) { + itemMeta.setLore(Arrays.asList( + "", + ChatColor.GREEN + "Current page" + )); + } + + itemStack.setItemMeta(itemMeta); + + return itemStack; + } + + @Override + public void clicked(Player player, ClickType clickType) { + this.menu.modPage(player, this.page - this.menu.getPage()); + Button.playNeutral(player); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/pagination/PageButton.java b/src/main/java/com/minexd/zoot/util/menu/pagination/PageButton.java new file mode 100644 index 0000000..72c6c52 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/pagination/PageButton.java @@ -0,0 +1,89 @@ +package com.minexd.zoot.util.menu.pagination; + +import com.minexd.zoot.util.ItemBuilder; +import java.util.Arrays; +import lombok.AllArgsConstructor; +import com.minexd.zoot.util.menu.Button; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +@AllArgsConstructor +public class PageButton extends Button { + + private int mod; + private PaginatedMenu menu; + + @Override + public ItemStack getButtonItem(Player player) { + if (this.mod > 0) { + if (hasNext(player)) { + return new ItemBuilder(Material.REDSTONE_TORCH_ON) + .name(ChatColor.GREEN + "Next Page") + .lore(Arrays.asList( + ChatColor.YELLOW + "Click here to jump", + ChatColor.YELLOW + "to the next page." + )) + .build(); + } else { + return new ItemBuilder(Material.LEVER) + .name(ChatColor.GRAY + "Next Page") + .lore(Arrays.asList( + ChatColor.YELLOW + "There is no available", + ChatColor.YELLOW + "next page." + )) + .build(); + } + } else { + if (hasPrevious(player)) { + return new ItemBuilder(Material.REDSTONE_TORCH_ON) + .name(ChatColor.GREEN + "Previous Page") + .lore(Arrays.asList( + ChatColor.YELLOW + "Click here to jump", + ChatColor.YELLOW + "to the previous page." + )) + .build(); + } else { + return new ItemBuilder(Material.LEVER) + .name(ChatColor.GRAY + "Previous Page") + .lore(Arrays.asList( + ChatColor.YELLOW + "There is no available", + ChatColor.YELLOW + "previous page." + )) + .build(); + } + } + } + + @Override + public void clicked(Player player, ClickType clickType) { + if (this.mod > 0) { + if (hasNext(player)) { + this.menu.modPage(player, this.mod); + Button.playNeutral(player); + } else { + Button.playFail(player); + } + } else { + if (hasPrevious(player)) { + this.menu.modPage(player, this.mod); + Button.playNeutral(player); + } else { + Button.playFail(player); + } + } + } + + private boolean hasNext(Player player) { + int pg = this.menu.getPage() + this.mod; + return this.menu.getPages(player) >= pg; + } + + private boolean hasPrevious(Player player) { + int pg = this.menu.getPage() + this.mod; + return pg > 0; + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/pagination/PageFilter.java b/src/main/java/com/minexd/zoot/util/menu/pagination/PageFilter.java new file mode 100644 index 0000000..8ad1967 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/pagination/PageFilter.java @@ -0,0 +1,24 @@ +package com.minexd.zoot.util.menu.pagination; + +import java.util.function.Predicate; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; + +@RequiredArgsConstructor +public class PageFilter { + + @Getter private final String name; + @Getter @Setter private boolean enabled; + private final Predicate predicate; + + public boolean test(T t) { + return !enabled || predicate.test(t); + } + + @Override + public boolean equals(Object object) { + return object instanceof PageFilter && ((PageFilter) object).getName().equals(name); + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/pagination/PageFilterButton.java b/src/main/java/com/minexd/zoot/util/menu/pagination/PageFilterButton.java new file mode 100644 index 0000000..4234058 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/pagination/PageFilterButton.java @@ -0,0 +1,84 @@ +package com.minexd.zoot.util.menu.pagination; + +import com.minexd.zoot.util.CC; +import com.minexd.zoot.util.ItemBuilder; +import com.minexd.zoot.util.menu.Button; +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringEscapeUtils; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +@AllArgsConstructor +public class PageFilterButton extends Button { + + private FilterablePaginatedMenu menu; + + @Override + public ItemStack getButtonItem(Player player) { + if (menu.getFilters() == null || menu.getFilters().isEmpty()) { + return new ItemStack(Material.AIR); + } + + List lore = new ArrayList<>(); + lore.add(CC.MENU_BAR); + + for (PageFilter filter : menu.getFilters()) { + String color; + String decoration = ""; + String icon; + + if (filter.isEnabled()) { + color = ChatColor.GREEN.toString(); + icon = StringEscapeUtils.unescapeJava("\u2713"); + } else { + color = ChatColor.RED.toString(); + icon = StringEscapeUtils.unescapeJava("\u2717"); + } + + if (menu.getFilters().get(menu.getScrollIndex()).equals(filter)) { + decoration = ChatColor.YELLOW + StringEscapeUtils.unescapeJava("» ") + " "; + } + + lore.add(decoration + color + icon + " " + filter.getName()); + } + + lore.add(CC.MENU_BAR); + lore.add("&eLeft click to scroll."); + lore.add("&eRight click to toggle a filter."); + lore.add(CC.MENU_BAR); + + return new ItemBuilder(Material.HOPPER) + .name("&7Filters") + .lore(lore) + .build(); + } + + @Override + public void clicked(Player player, ClickType clickType) { + if (menu.getFilters() == null || menu.getFilters().isEmpty()) { + player.sendMessage(ChatColor.RED + "There are no filters."); + } else { + if (clickType == ClickType.LEFT) { + if (menu.getScrollIndex() == menu.getFilters().size() - 1) { + menu.setScrollIndex(0); + } else { + menu.setScrollIndex(menu.getScrollIndex() + 1); + } + } else if (clickType == ClickType.RIGHT) { + PageFilter filter = menu.getFilters().get(menu.getScrollIndex()); + filter.setEnabled(!filter.isEnabled()); + } + } + } + + @Override + public boolean shouldUpdate(Player player, ClickType clickType) { + return true; + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/pagination/PageInfoButton.java b/src/main/java/com/minexd/zoot/util/menu/pagination/PageInfoButton.java new file mode 100644 index 0000000..fbe500e --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/pagination/PageInfoButton.java @@ -0,0 +1,41 @@ +package com.minexd.zoot.util.menu.pagination; + +import com.minexd.zoot.util.ItemBuilder; +import com.minexd.zoot.util.menu.Button; +import lombok.AllArgsConstructor; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +@AllArgsConstructor +public class PageInfoButton extends Button { + + private PaginatedMenu menu; + + @Override + public ItemStack getButtonItem(Player player) { + int pages = menu.getPages(player); + + return new ItemBuilder(Material.PAPER) + .name(ChatColor.GOLD + "Page Info") + .lore( + ChatColor.YELLOW + "You are viewing page #" + menu.getPage() + ".", + ChatColor.YELLOW + (pages == 1 ? "There is 1 page." : "There are " + pages + " pages."), + "", + ChatColor.YELLOW + "Middle click here to", + ChatColor.YELLOW + "view all pages." + ) + .build(); + } + + @Override + public void clicked(Player player, ClickType clickType) { + if (clickType == ClickType.RIGHT) { + new ViewAllPagesMenu(this.menu).openMenu(player); + playNeutral(player); + } + } + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/pagination/PaginatedMenu.java b/src/main/java/com/minexd/zoot/util/menu/pagination/PaginatedMenu.java new file mode 100644 index 0000000..61b7005 --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/pagination/PaginatedMenu.java @@ -0,0 +1,114 @@ +package com.minexd.zoot.util.menu.pagination; + +import com.minexd.zoot.util.menu.Button; +import com.minexd.zoot.util.menu.Menu; +import java.util.HashMap; +import java.util.Map; +import lombok.Getter; +import org.bukkit.entity.Player; + +public abstract class PaginatedMenu extends Menu { + + @Getter private int page = 1; + + { + setUpdateAfterClick(false); + } + + @Override + public String getTitle(Player player) { + return getPrePaginatedTitle(player); + } + + /** + * Changes the page number + * + * @param player player viewing the inventory + * @param mod delta to modify the page number by + */ + public final void modPage(Player player, int mod) { + page += mod; + getButtons().clear(); + openMenu(player); + } + + /** + * @param player player viewing the inventory + */ + public final int getPages(Player player) { + int buttonAmount = getAllPagesButtons(player).size(); + + if (buttonAmount == 0) { + return 1; + } + + return (int) Math.ceil(buttonAmount / (double) getMaxItemsPerPage(player)); + } + + @Override + public final Map getButtons(Player player) { + int minIndex = (int) ((double) (page - 1) * getMaxItemsPerPage(player)); + int maxIndex = (int) ((double) (page) * getMaxItemsPerPage(player)); + int topIndex = 0; + + HashMap buttons = new HashMap<>(); + + for (Map.Entry entry : getAllPagesButtons(player).entrySet()) { + int ind = entry.getKey(); + + if (ind >= minIndex && ind < maxIndex) { + ind -= (int) ((double) (getMaxItemsPerPage(player)) * (page - 1)) - 9; + buttons.put(ind, entry.getValue()); + + if (ind > topIndex) { + topIndex = ind; + } + } + } + + buttons.put(0, new PageButton(-1, this)); + buttons.put(8, new PageButton(1, this)); + + for (int i = 1; i < 8; i++) { + buttons.put(i, getPlaceholderButton()); + } + + Map global = getGlobalButtons(player); + + if (global != null) { + for (Map.Entry gent : global.entrySet()) { + buttons.put(gent.getKey(), gent.getValue()); + } + } + + return buttons; + } + + public int getMaxItemsPerPage(Player player) { + return 18; + } + + /** + * @param player player viewing the inventory + * + * @return a Map of button that returns items which will be present on all pages + */ + public Map getGlobalButtons(Player player) { + return null; + } + + /** + * @param player player viewing the inventory + * + * @return title of the inventory before the page number is added + */ + public abstract String getPrePaginatedTitle(Player player); + + /** + * @param player player viewing the inventory + * + * @return a map of button that will be paginated and spread across pages + */ + public abstract Map getAllPagesButtons(Player player); + +} diff --git a/src/main/java/com/minexd/zoot/util/menu/pagination/ViewAllPagesMenu.java b/src/main/java/com/minexd/zoot/util/menu/pagination/ViewAllPagesMenu.java new file mode 100644 index 0000000..c60d10b --- /dev/null +++ b/src/main/java/com/minexd/zoot/util/menu/pagination/ViewAllPagesMenu.java @@ -0,0 +1,49 @@ +package com.minexd.zoot.util.menu.pagination; + +import com.minexd.zoot.util.menu.Button; +import com.minexd.zoot.util.menu.Menu; +import com.minexd.zoot.util.menu.button.BackButton; +import java.util.HashMap; +import java.util.Map; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.bukkit.entity.Player; + +@RequiredArgsConstructor +public class ViewAllPagesMenu extends Menu { + + @NonNull + @Getter + PaginatedMenu menu; + + @Override + public String getTitle(Player player) { + return "Jump to page"; + } + + @Override + public Map getButtons(Player player) { + HashMap buttons = new HashMap<>(); + + buttons.put(0, new BackButton(menu)); + + int index = 10; + + for (int i = 1; i <= menu.getPages(player); i++) { + buttons.put(index++, new JumpToPageButton(i, menu, menu.getPage() == i)); + + if ((index - 8) % 9 == 0) { + index += 2; + } + } + + return buttons; + } + + @Override + public boolean isAutoUpdate() { + return true; + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..0a56f62 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,60 @@ +CONFIG_VERSION: 1 +SERVER_NAME: "Development" +MONGO: + HOST: "127.0.0.1" + PORT: 27017 + AUTHENTICATION: + ENABLED: false + USERNAME: "" + PASSWORD: "" +REDIS: + HOST: "127.0.0.1" + PORT: 6379 + AUTHENTICATION: + ENABLED: false + PASSWORD: "" +SETTINGS: + UPDATE_PLAYER_LIST_NAME: true +PUNISHMENTS: + BROADCAST: "&r{target} &ahas been {context} by &r{sender}" + BROADCAST_SILENT: "&7[Silent] &r{target} &ahas been {context} by &r{sender}" + BAN: + KICK: "&cYour account is {context} from Zonix.{temporary}\n\n&cIf you feel this punishment is unjust, you may appeal at:\n&ehttps://www.zonix.com" + TEMPORARY: "\n&cThis punishment expires in &e{time-remaining}&c." + KICK: + KICK: "&cYou were kicked by a staff member.\nReason: &e{reason}" +COMMON_ERRORS: + FAILED_TO_LOAD_PROFILE: "&cFailed to load your profile. Try again later." + COULD_NOT_RESOLVE_PLAYER: "&cCould not resolve player information..." + PLAYER_NOT_FOUND: "&cA player with that name could not be found." + RANK_NOT_FOUND: "&cA rank with that name could not be found." +STAFF: + CHAT: "{0}&r{1}&b ({2}): {3}" + BROADCAST_PREFIX: "&9&l[Staff] &r" + JOIN_NETWORK: "{0}{1} &ajoined the network &2({2})" + LEAVE_NETWORK: "{0}{1} &aleft the network" + SWITCH_SERVER: "{0}({1} &ajoined {2} &2(from {3})" +NETWORK: + BROADCAST_PREFIX: "&8[&eNetwork&8] &f" + RANK_REFRESH: "{0}Refreshed rank \"{1}\"" + RANK_DELETE: "{0}Deleted rank \"{1}\"" +CHAT: + FORMAT: "%1$s&r: %2$s" + CLEAR_CHAT_BROADCAST: "&eThe chat has been cleared by &r{0}" + CLEAR_CHAT_FOR_STAFF: false + MUTE_CHAT_BROADCAST: "&eThe chat has been {0} by &r{1}" + DELAY_CHAT_ENABLED_BROADCAST: "&eThe chat has been delayed by &r{0} &7({1} second{2})" + DELAY_CHAT_DISABLED_BROADCAST: "&eThe chat delay has been lifted by &r{0}" + CHAT_DELAYED: "&cSlow down! You may chat again in {0} seconds." +# using both text formatter and text replacing because I need to escape colors in the input message +# format: player name, player display name, player color, target name, target display name, target color +CONVERSATION: + SEND_MESSAGE: "&7(To &r{5}{3}&7) %MSG%" + RECEIVE_MESSAGE: "&7(From &r{5}{3}&7) %MSG%" +OPTIONS: + GLOBAL_CHAT_ENABLED: "&eYou can now see global chat." + GLOBAL_CHAT_DISABLED: "&cYou will no longer see global chat." + PRIVATE_MESSAGES_ENABLED: "&aYou can now receive new conversations." + PRIVATE_MESSAGES_DISABLED: "&cYou can no longer receive new conversations. If you start a conversation with a player, they will be able to message you back." + PRIVATE_MESSAGE_SOUNDS_ENABLED: "&eYou enabled private message sounds." + PRIVATE_MESSAGE_SOUNDS_DISABLED: "&cYou disabled private message sounds." \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..1f4e2dd --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,5 @@ +main: com.minexd.zoot.Zoot +name: Zoot +author: joeleoli +version: 1.0 +depend: [ProtocolLib] \ No newline at end of file diff --git a/target/classes/com/minexd/zoot/Locale.class b/target/classes/com/minexd/zoot/Locale.class new file mode 100644 index 0000000..bc0df3e Binary files /dev/null and b/target/classes/com/minexd/zoot/Locale.class differ diff --git a/target/classes/com/minexd/zoot/Zoot$1.class b/target/classes/com/minexd/zoot/Zoot$1.class new file mode 100644 index 0000000..0ca8aae Binary files /dev/null and b/target/classes/com/minexd/zoot/Zoot$1.class differ diff --git a/target/classes/com/minexd/zoot/Zoot$2.class b/target/classes/com/minexd/zoot/Zoot$2.class new file mode 100644 index 0000000..a30cc62 Binary files /dev/null and b/target/classes/com/minexd/zoot/Zoot$2.class differ diff --git a/target/classes/com/minexd/zoot/Zoot.class b/target/classes/com/minexd/zoot/Zoot.class new file mode 100644 index 0000000..1f5663f Binary files /dev/null and b/target/classes/com/minexd/zoot/Zoot.class differ diff --git a/target/classes/com/minexd/zoot/ZootAPI.class b/target/classes/com/minexd/zoot/ZootAPI.class new file mode 100644 index 0000000..08adcc7 Binary files /dev/null and b/target/classes/com/minexd/zoot/ZootAPI.class differ diff --git a/target/classes/com/minexd/zoot/bootstrap/Bootstrapped.class b/target/classes/com/minexd/zoot/bootstrap/Bootstrapped.class new file mode 100644 index 0000000..71ebc6a Binary files /dev/null and b/target/classes/com/minexd/zoot/bootstrap/Bootstrapped.class differ diff --git a/target/classes/com/minexd/zoot/bootstrap/BootstrappedListener.class b/target/classes/com/minexd/zoot/bootstrap/BootstrappedListener.class new file mode 100644 index 0000000..2e9c2c0 Binary files /dev/null and b/target/classes/com/minexd/zoot/bootstrap/BootstrappedListener.class differ diff --git a/target/classes/com/minexd/zoot/cache/RedisCache.class b/target/classes/com/minexd/zoot/cache/RedisCache.class new file mode 100644 index 0000000..e005dc3 Binary files /dev/null and b/target/classes/com/minexd/zoot/cache/RedisCache.class differ diff --git a/target/classes/com/minexd/zoot/cache/RedisPlayerData$LastAction.class b/target/classes/com/minexd/zoot/cache/RedisPlayerData$LastAction.class new file mode 100644 index 0000000..665c46c Binary files /dev/null and b/target/classes/com/minexd/zoot/cache/RedisPlayerData$LastAction.class differ diff --git a/target/classes/com/minexd/zoot/cache/RedisPlayerData.class b/target/classes/com/minexd/zoot/cache/RedisPlayerData.class new file mode 100644 index 0000000..b27fd0e Binary files /dev/null and b/target/classes/com/minexd/zoot/cache/RedisPlayerData.class differ diff --git a/target/classes/com/minexd/zoot/chat/Chat.class b/target/classes/com/minexd/zoot/chat/Chat.class new file mode 100644 index 0000000..b586157 Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/Chat.class differ diff --git a/target/classes/com/minexd/zoot/chat/ChatAttempt$Response.class b/target/classes/com/minexd/zoot/chat/ChatAttempt$Response.class new file mode 100644 index 0000000..4640855 Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/ChatAttempt$Response.class differ diff --git a/target/classes/com/minexd/zoot/chat/ChatAttempt.class b/target/classes/com/minexd/zoot/chat/ChatAttempt.class new file mode 100644 index 0000000..7c627a4 Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/ChatAttempt.class differ diff --git a/target/classes/com/minexd/zoot/chat/ChatListener$1.class b/target/classes/com/minexd/zoot/chat/ChatListener$1.class new file mode 100644 index 0000000..fc5e5fb Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/ChatListener$1.class differ diff --git a/target/classes/com/minexd/zoot/chat/ChatListener.class b/target/classes/com/minexd/zoot/chat/ChatListener.class new file mode 100644 index 0000000..7310ce1 Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/ChatListener.class differ diff --git a/target/classes/com/minexd/zoot/chat/command/ClearChatCommand.class b/target/classes/com/minexd/zoot/chat/command/ClearChatCommand.class new file mode 100644 index 0000000..f93d631 Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/command/ClearChatCommand.class differ diff --git a/target/classes/com/minexd/zoot/chat/command/MuteChatCommand.class b/target/classes/com/minexd/zoot/chat/command/MuteChatCommand.class new file mode 100644 index 0000000..d86a4ff Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/command/MuteChatCommand.class differ diff --git a/target/classes/com/minexd/zoot/chat/command/SlowChatCommand.class b/target/classes/com/minexd/zoot/chat/command/SlowChatCommand.class new file mode 100644 index 0000000..4dac83d Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/command/SlowChatCommand.class differ diff --git a/target/classes/com/minexd/zoot/chat/event/ChatAttemptEvent.class b/target/classes/com/minexd/zoot/chat/event/ChatAttemptEvent.class new file mode 100644 index 0000000..080675e Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/event/ChatAttemptEvent.class differ diff --git a/target/classes/com/minexd/zoot/chat/filter/ChatFilter.class b/target/classes/com/minexd/zoot/chat/filter/ChatFilter.class new file mode 100644 index 0000000..0d604ca Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/filter/ChatFilter.class differ diff --git a/target/classes/com/minexd/zoot/chat/filter/impl/ContainsFilter.class b/target/classes/com/minexd/zoot/chat/filter/impl/ContainsFilter.class new file mode 100644 index 0000000..ef69b9d Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/filter/impl/ContainsFilter.class differ diff --git a/target/classes/com/minexd/zoot/chat/filter/impl/LinkFilter.class b/target/classes/com/minexd/zoot/chat/filter/impl/LinkFilter.class new file mode 100644 index 0000000..699ea64 Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/filter/impl/LinkFilter.class differ diff --git a/target/classes/com/minexd/zoot/chat/util/ChatComponentBuilder.class b/target/classes/com/minexd/zoot/chat/util/ChatComponentBuilder.class new file mode 100644 index 0000000..d0bf5db Binary files /dev/null and b/target/classes/com/minexd/zoot/chat/util/ChatComponentBuilder.class differ diff --git a/target/classes/com/minexd/zoot/config/ConfigConversion.class b/target/classes/com/minexd/zoot/config/ConfigConversion.class new file mode 100644 index 0000000..55b1590 Binary files /dev/null and b/target/classes/com/minexd/zoot/config/ConfigConversion.class differ diff --git a/target/classes/com/minexd/zoot/config/ConfigValidation.class b/target/classes/com/minexd/zoot/config/ConfigValidation.class new file mode 100644 index 0000000..0c76de7 Binary files /dev/null and b/target/classes/com/minexd/zoot/config/ConfigValidation.class differ diff --git a/target/classes/com/minexd/zoot/config/ConfigVersion.class b/target/classes/com/minexd/zoot/config/ConfigVersion.class new file mode 100644 index 0000000..ff5ac70 Binary files /dev/null and b/target/classes/com/minexd/zoot/config/ConfigVersion.class differ diff --git a/target/classes/com/minexd/zoot/config/impl/ConfigConversion1.class b/target/classes/com/minexd/zoot/config/impl/ConfigConversion1.class new file mode 100644 index 0000000..397a62b Binary files /dev/null and b/target/classes/com/minexd/zoot/config/impl/ConfigConversion1.class differ diff --git a/target/classes/com/minexd/zoot/config/impl/ConfigConversion2.class b/target/classes/com/minexd/zoot/config/impl/ConfigConversion2.class new file mode 100644 index 0000000..ac2b75f Binary files /dev/null and b/target/classes/com/minexd/zoot/config/impl/ConfigConversion2.class differ diff --git a/target/classes/com/minexd/zoot/config/impl/ConfigConversion3.class b/target/classes/com/minexd/zoot/config/impl/ConfigConversion3.class new file mode 100644 index 0000000..ad7200c Binary files /dev/null and b/target/classes/com/minexd/zoot/config/impl/ConfigConversion3.class differ diff --git a/target/classes/com/minexd/zoot/essentials/Essentials.class b/target/classes/com/minexd/zoot/essentials/Essentials.class new file mode 100644 index 0000000..e2b735e Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/Essentials.class differ diff --git a/target/classes/com/minexd/zoot/essentials/EssentialsListener.class b/target/classes/com/minexd/zoot/essentials/EssentialsListener.class new file mode 100644 index 0000000..df97638 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/EssentialsListener.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/BroadcastCommand.class b/target/classes/com/minexd/zoot/essentials/command/BroadcastCommand.class new file mode 100644 index 0000000..e1942b4 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/BroadcastCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/ClearCommand.class b/target/classes/com/minexd/zoot/essentials/command/ClearCommand.class new file mode 100644 index 0000000..ab7860c Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/ClearCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/DayCommand.class b/target/classes/com/minexd/zoot/essentials/command/DayCommand.class new file mode 100644 index 0000000..501e74e Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/DayCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/GameModeCommand.class b/target/classes/com/minexd/zoot/essentials/command/GameModeCommand.class new file mode 100644 index 0000000..32b6dfb Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/GameModeCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/HealCommand.class b/target/classes/com/minexd/zoot/essentials/command/HealCommand.class new file mode 100644 index 0000000..8d99897 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/HealCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/HidePlayerCommand.class b/target/classes/com/minexd/zoot/essentials/command/HidePlayerCommand.class new file mode 100644 index 0000000..6714dd6 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/HidePlayerCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/ListCommand$1.class b/target/classes/com/minexd/zoot/essentials/command/ListCommand$1.class new file mode 100644 index 0000000..e248450 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/ListCommand$1.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/ListCommand$2.class b/target/classes/com/minexd/zoot/essentials/command/ListCommand$2.class new file mode 100644 index 0000000..7826348 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/ListCommand$2.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/ListCommand.class b/target/classes/com/minexd/zoot/essentials/command/ListCommand.class new file mode 100644 index 0000000..6cdfb25 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/ListCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/LocationCommand.class b/target/classes/com/minexd/zoot/essentials/command/LocationCommand.class new file mode 100644 index 0000000..2e6e354 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/LocationCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/MoreCommand.class b/target/classes/com/minexd/zoot/essentials/command/MoreCommand.class new file mode 100644 index 0000000..3e819a1 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/MoreCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/NightCommand.class b/target/classes/com/minexd/zoot/essentials/command/NightCommand.class new file mode 100644 index 0000000..812e724 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/NightCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/PingCommand.class b/target/classes/com/minexd/zoot/essentials/command/PingCommand.class new file mode 100644 index 0000000..3fa195f Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/PingCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/RenameCommand.class b/target/classes/com/minexd/zoot/essentials/command/RenameCommand.class new file mode 100644 index 0000000..fbd31bb Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/RenameCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/SetSlotsCommand.class b/target/classes/com/minexd/zoot/essentials/command/SetSlotsCommand.class new file mode 100644 index 0000000..ae6ce5d Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/SetSlotsCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/SetSpawnCommand.class b/target/classes/com/minexd/zoot/essentials/command/SetSpawnCommand.class new file mode 100644 index 0000000..851d79e Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/SetSpawnCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/ShowPlayerCommand.class b/target/classes/com/minexd/zoot/essentials/command/ShowPlayerCommand.class new file mode 100644 index 0000000..26dca60 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/ShowPlayerCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/SpawnCommand.class b/target/classes/com/minexd/zoot/essentials/command/SpawnCommand.class new file mode 100644 index 0000000..fd698f4 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/SpawnCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/SunsetCommand.class b/target/classes/com/minexd/zoot/essentials/command/SunsetCommand.class new file mode 100644 index 0000000..081d359 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/SunsetCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/TeleportWorldCommand.class b/target/classes/com/minexd/zoot/essentials/command/TeleportWorldCommand.class new file mode 100644 index 0000000..6e24691 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/TeleportWorldCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/command/ZootDebugCommand.class b/target/classes/com/minexd/zoot/essentials/command/ZootDebugCommand.class new file mode 100644 index 0000000..2ab20dd Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/command/ZootDebugCommand.class differ diff --git a/target/classes/com/minexd/zoot/essentials/event/SpawnTeleportEvent.class b/target/classes/com/minexd/zoot/essentials/event/SpawnTeleportEvent.class new file mode 100644 index 0000000..e7a9b41 Binary files /dev/null and b/target/classes/com/minexd/zoot/essentials/event/SpawnTeleportEvent.class differ diff --git a/target/classes/com/minexd/zoot/network/NetworkPacketListener$1.class b/target/classes/com/minexd/zoot/network/NetworkPacketListener$1.class new file mode 100644 index 0000000..13951a5 Binary files /dev/null and b/target/classes/com/minexd/zoot/network/NetworkPacketListener$1.class differ diff --git a/target/classes/com/minexd/zoot/network/NetworkPacketListener.class b/target/classes/com/minexd/zoot/network/NetworkPacketListener.class new file mode 100644 index 0000000..bd03437 Binary files /dev/null and b/target/classes/com/minexd/zoot/network/NetworkPacketListener.class differ diff --git a/target/classes/com/minexd/zoot/network/event/ReceiveStaffChatEvent.class b/target/classes/com/minexd/zoot/network/event/ReceiveStaffChatEvent.class new file mode 100644 index 0000000..219dd70 Binary files /dev/null and b/target/classes/com/minexd/zoot/network/event/ReceiveStaffChatEvent.class differ diff --git a/target/classes/com/minexd/zoot/network/packet/PacketAddGrant.class b/target/classes/com/minexd/zoot/network/packet/PacketAddGrant.class new file mode 100644 index 0000000..708dda7 Binary files /dev/null and b/target/classes/com/minexd/zoot/network/packet/PacketAddGrant.class differ diff --git a/target/classes/com/minexd/zoot/network/packet/PacketBroadcastPunishment.class b/target/classes/com/minexd/zoot/network/packet/PacketBroadcastPunishment.class new file mode 100644 index 0000000..09e8408 Binary files /dev/null and b/target/classes/com/minexd/zoot/network/packet/PacketBroadcastPunishment.class differ diff --git a/target/classes/com/minexd/zoot/network/packet/PacketDeleteGrant.class b/target/classes/com/minexd/zoot/network/packet/PacketDeleteGrant.class new file mode 100644 index 0000000..e13d14a Binary files /dev/null and b/target/classes/com/minexd/zoot/network/packet/PacketDeleteGrant.class differ diff --git a/target/classes/com/minexd/zoot/network/packet/PacketDeleteRank.class b/target/classes/com/minexd/zoot/network/packet/PacketDeleteRank.class new file mode 100644 index 0000000..de922ee Binary files /dev/null and b/target/classes/com/minexd/zoot/network/packet/PacketDeleteRank.class differ diff --git a/target/classes/com/minexd/zoot/network/packet/PacketRefreshRank.class b/target/classes/com/minexd/zoot/network/packet/PacketRefreshRank.class new file mode 100644 index 0000000..f3f4643 Binary files /dev/null and b/target/classes/com/minexd/zoot/network/packet/PacketRefreshRank.class differ diff --git a/target/classes/com/minexd/zoot/network/packet/PacketStaffChat.class b/target/classes/com/minexd/zoot/network/packet/PacketStaffChat.class new file mode 100644 index 0000000..686f149 Binary files /dev/null and b/target/classes/com/minexd/zoot/network/packet/PacketStaffChat.class differ diff --git a/target/classes/com/minexd/zoot/network/packet/PacketStaffJoinNetwork.class b/target/classes/com/minexd/zoot/network/packet/PacketStaffJoinNetwork.class new file mode 100644 index 0000000..cdd9c2f Binary files /dev/null and b/target/classes/com/minexd/zoot/network/packet/PacketStaffJoinNetwork.class differ diff --git a/target/classes/com/minexd/zoot/network/packet/PacketStaffLeaveNetwork.class b/target/classes/com/minexd/zoot/network/packet/PacketStaffLeaveNetwork.class new file mode 100644 index 0000000..7c3c531 Binary files /dev/null and b/target/classes/com/minexd/zoot/network/packet/PacketStaffLeaveNetwork.class differ diff --git a/target/classes/com/minexd/zoot/network/packet/PacketStaffSwitchServer.class b/target/classes/com/minexd/zoot/network/packet/PacketStaffSwitchServer.class new file mode 100644 index 0000000..c14ae8d Binary files /dev/null and b/target/classes/com/minexd/zoot/network/packet/PacketStaffSwitchServer.class differ diff --git a/target/classes/com/minexd/zoot/pidgin/Pidgin$1.class b/target/classes/com/minexd/zoot/pidgin/Pidgin$1.class new file mode 100644 index 0000000..44d3f03 Binary files /dev/null and b/target/classes/com/minexd/zoot/pidgin/Pidgin$1.class differ diff --git a/target/classes/com/minexd/zoot/pidgin/Pidgin.class b/target/classes/com/minexd/zoot/pidgin/Pidgin.class new file mode 100644 index 0000000..c773ed7 Binary files /dev/null and b/target/classes/com/minexd/zoot/pidgin/Pidgin.class differ diff --git a/target/classes/com/minexd/zoot/pidgin/packet/Packet.class b/target/classes/com/minexd/zoot/pidgin/packet/Packet.class new file mode 100644 index 0000000..a9dfe50 Binary files /dev/null and b/target/classes/com/minexd/zoot/pidgin/packet/Packet.class differ diff --git a/target/classes/com/minexd/zoot/pidgin/packet/handler/IncomingPacketHandler.class b/target/classes/com/minexd/zoot/pidgin/packet/handler/IncomingPacketHandler.class new file mode 100644 index 0000000..62bf95a Binary files /dev/null and b/target/classes/com/minexd/zoot/pidgin/packet/handler/IncomingPacketHandler.class differ diff --git a/target/classes/com/minexd/zoot/pidgin/packet/handler/PacketExceptionHandler.class b/target/classes/com/minexd/zoot/pidgin/packet/handler/PacketExceptionHandler.class new file mode 100644 index 0000000..94990e4 Binary files /dev/null and b/target/classes/com/minexd/zoot/pidgin/packet/handler/PacketExceptionHandler.class differ diff --git a/target/classes/com/minexd/zoot/pidgin/packet/listener/PacketListener.class b/target/classes/com/minexd/zoot/pidgin/packet/listener/PacketListener.class new file mode 100644 index 0000000..aba80b7 Binary files /dev/null and b/target/classes/com/minexd/zoot/pidgin/packet/listener/PacketListener.class differ diff --git a/target/classes/com/minexd/zoot/pidgin/packet/listener/PacketListenerData.class b/target/classes/com/minexd/zoot/pidgin/packet/listener/PacketListenerData.class new file mode 100644 index 0000000..69c372f Binary files /dev/null and b/target/classes/com/minexd/zoot/pidgin/packet/listener/PacketListenerData.class differ diff --git a/target/classes/com/minexd/zoot/profile/Profile.class b/target/classes/com/minexd/zoot/profile/Profile.class new file mode 100644 index 0000000..076bc41 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/Profile.class differ diff --git a/target/classes/com/minexd/zoot/profile/ProfileListener$1.class b/target/classes/com/minexd/zoot/profile/ProfileListener$1.class new file mode 100644 index 0000000..39e8425 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/ProfileListener$1.class differ diff --git a/target/classes/com/minexd/zoot/profile/ProfileListener.class b/target/classes/com/minexd/zoot/profile/ProfileListener.class new file mode 100644 index 0000000..a1f8a79 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/ProfileListener.class differ diff --git a/target/classes/com/minexd/zoot/profile/ProfileTypeAdapter.class b/target/classes/com/minexd/zoot/profile/ProfileTypeAdapter.class new file mode 100644 index 0000000..efef43c Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/ProfileTypeAdapter.class differ diff --git a/target/classes/com/minexd/zoot/profile/conversation/Conversation.class b/target/classes/com/minexd/zoot/profile/conversation/Conversation.class new file mode 100644 index 0000000..15cba7d Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/conversation/Conversation.class differ diff --git a/target/classes/com/minexd/zoot/profile/conversation/ProfileConversations.class b/target/classes/com/minexd/zoot/profile/conversation/ProfileConversations.class new file mode 100644 index 0000000..91c0c87 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/conversation/ProfileConversations.class differ diff --git a/target/classes/com/minexd/zoot/profile/conversation/command/MessageCommand.class b/target/classes/com/minexd/zoot/profile/conversation/command/MessageCommand.class new file mode 100644 index 0000000..ac9fc98 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/conversation/command/MessageCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/conversation/command/ReplyCommand.class b/target/classes/com/minexd/zoot/profile/conversation/command/ReplyCommand.class new file mode 100644 index 0000000..2fa3f88 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/conversation/command/ReplyCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/Grant.class b/target/classes/com/minexd/zoot/profile/grant/Grant.class new file mode 100644 index 0000000..c30bbf8 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/Grant.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/GrantJsonDeserializer.class b/target/classes/com/minexd/zoot/profile/grant/GrantJsonDeserializer.class new file mode 100644 index 0000000..a39d509 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/GrantJsonDeserializer.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/GrantJsonSerializer.class b/target/classes/com/minexd/zoot/profile/grant/GrantJsonSerializer.class new file mode 100644 index 0000000..67419f0 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/GrantJsonSerializer.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/GrantListener$1.class b/target/classes/com/minexd/zoot/profile/grant/GrantListener$1.class new file mode 100644 index 0000000..477e97a Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/GrantListener$1.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/GrantListener$2.class b/target/classes/com/minexd/zoot/profile/grant/GrantListener$2.class new file mode 100644 index 0000000..65cf7d6 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/GrantListener$2.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/GrantListener.class b/target/classes/com/minexd/zoot/profile/grant/GrantListener.class new file mode 100644 index 0000000..7922c41 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/GrantListener.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/command/GrantCommand.class b/target/classes/com/minexd/zoot/profile/grant/command/GrantCommand.class new file mode 100644 index 0000000..a74a2a2 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/command/GrantCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/command/GrantsCommand.class b/target/classes/com/minexd/zoot/profile/grant/command/GrantsCommand.class new file mode 100644 index 0000000..41590c1 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/command/GrantsCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/event/GrantAppliedEvent.class b/target/classes/com/minexd/zoot/profile/grant/event/GrantAppliedEvent.class new file mode 100644 index 0000000..9d23d7d Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/event/GrantAppliedEvent.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/event/GrantExpireEvent.class b/target/classes/com/minexd/zoot/profile/grant/event/GrantExpireEvent.class new file mode 100644 index 0000000..63d6b98 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/event/GrantExpireEvent.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/menu/GrantsListMenu$GrantInfoButton.class b/target/classes/com/minexd/zoot/profile/grant/menu/GrantsListMenu$GrantInfoButton.class new file mode 100644 index 0000000..2c71007 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/menu/GrantsListMenu$GrantInfoButton.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/menu/GrantsListMenu.class b/target/classes/com/minexd/zoot/profile/grant/menu/GrantsListMenu.class new file mode 100644 index 0000000..6b49eba Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/menu/GrantsListMenu.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/procedure/GrantProcedure.class b/target/classes/com/minexd/zoot/profile/grant/procedure/GrantProcedure.class new file mode 100644 index 0000000..fcc0be7 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/procedure/GrantProcedure.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/procedure/GrantProcedureStage.class b/target/classes/com/minexd/zoot/profile/grant/procedure/GrantProcedureStage.class new file mode 100644 index 0000000..7a1b821 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/procedure/GrantProcedureStage.class differ diff --git a/target/classes/com/minexd/zoot/profile/grant/procedure/GrantProcedureType.class b/target/classes/com/minexd/zoot/profile/grant/procedure/GrantProcedureType.class new file mode 100644 index 0000000..dd4bbf0 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/grant/procedure/GrantProcedureType.class differ diff --git a/target/classes/com/minexd/zoot/profile/menu/ProfileMenuControlHeaderButton.class b/target/classes/com/minexd/zoot/profile/menu/ProfileMenuControlHeaderButton.class new file mode 100644 index 0000000..974e200 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/menu/ProfileMenuControlHeaderButton.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/ProfileOptions.class b/target/classes/com/minexd/zoot/profile/option/ProfileOptions.class new file mode 100644 index 0000000..44d6c4a Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/ProfileOptions.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/command/OptionsCommand.class b/target/classes/com/minexd/zoot/profile/option/command/OptionsCommand.class new file mode 100644 index 0000000..26b0d36 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/command/OptionsCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/command/ToggleGlobalChatCommand.class b/target/classes/com/minexd/zoot/profile/option/command/ToggleGlobalChatCommand.class new file mode 100644 index 0000000..fb9f12f Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/command/ToggleGlobalChatCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/command/TogglePrivateMessagesCommand.class b/target/classes/com/minexd/zoot/profile/option/command/TogglePrivateMessagesCommand.class new file mode 100644 index 0000000..129f39e Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/command/TogglePrivateMessagesCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/command/ToggleSoundsCommand.class b/target/classes/com/minexd/zoot/profile/option/command/ToggleSoundsCommand.class new file mode 100644 index 0000000..adb3a23 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/command/ToggleSoundsCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/event/OptionsOpenedEvent.class b/target/classes/com/minexd/zoot/profile/option/event/OptionsOpenedEvent.class new file mode 100644 index 0000000..eed89e1 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/event/OptionsOpenedEvent.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/menu/ProfileOptionButton.class b/target/classes/com/minexd/zoot/profile/option/menu/ProfileOptionButton.class new file mode 100644 index 0000000..5d9f6c8 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/menu/ProfileOptionButton.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/menu/ProfileOptionsMenu.class b/target/classes/com/minexd/zoot/profile/option/menu/ProfileOptionsMenu.class new file mode 100644 index 0000000..a0f973c Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/menu/ProfileOptionsMenu.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/menu/button/PrivateChatOptionButton.class b/target/classes/com/minexd/zoot/profile/option/menu/button/PrivateChatOptionButton.class new file mode 100644 index 0000000..c0a9201 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/menu/button/PrivateChatOptionButton.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/menu/button/PrivateChatSoundsOptionButton.class b/target/classes/com/minexd/zoot/profile/option/menu/button/PrivateChatSoundsOptionButton.class new file mode 100644 index 0000000..815a673 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/menu/button/PrivateChatSoundsOptionButton.class differ diff --git a/target/classes/com/minexd/zoot/profile/option/menu/button/PublicChatOptionButton.class b/target/classes/com/minexd/zoot/profile/option/menu/button/PublicChatOptionButton.class new file mode 100644 index 0000000..f2c367b Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/option/menu/button/PublicChatOptionButton.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/Punishment.class b/target/classes/com/minexd/zoot/profile/punishment/Punishment.class new file mode 100644 index 0000000..6c7684b Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/Punishment.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/PunishmentJsonDeserializer.class b/target/classes/com/minexd/zoot/profile/punishment/PunishmentJsonDeserializer.class new file mode 100644 index 0000000..e580f80 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/PunishmentJsonDeserializer.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/PunishmentJsonSerializer.class b/target/classes/com/minexd/zoot/profile/punishment/PunishmentJsonSerializer.class new file mode 100644 index 0000000..aec023a Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/PunishmentJsonSerializer.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/PunishmentType$PunishmentTypeData.class b/target/classes/com/minexd/zoot/profile/punishment/PunishmentType$PunishmentTypeData.class new file mode 100644 index 0000000..47e571e Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/PunishmentType$PunishmentTypeData.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/PunishmentType.class b/target/classes/com/minexd/zoot/profile/punishment/PunishmentType.class new file mode 100644 index 0000000..d47d02f Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/PunishmentType.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/command/BanCommand$1.class b/target/classes/com/minexd/zoot/profile/punishment/command/BanCommand$1.class new file mode 100644 index 0000000..178384b Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/command/BanCommand$1.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/command/BanCommand.class b/target/classes/com/minexd/zoot/profile/punishment/command/BanCommand.class new file mode 100644 index 0000000..d61f0d6 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/command/BanCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/command/CheckCommand.class b/target/classes/com/minexd/zoot/profile/punishment/command/CheckCommand.class new file mode 100644 index 0000000..e0808cb Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/command/CheckCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/command/KickCommand$1.class b/target/classes/com/minexd/zoot/profile/punishment/command/KickCommand$1.class new file mode 100644 index 0000000..fa31477 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/command/KickCommand$1.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/command/KickCommand.class b/target/classes/com/minexd/zoot/profile/punishment/command/KickCommand.class new file mode 100644 index 0000000..a7ad583 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/command/KickCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/command/MuteCommand.class b/target/classes/com/minexd/zoot/profile/punishment/command/MuteCommand.class new file mode 100644 index 0000000..1d3ff10 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/command/MuteCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/command/UnbanCommand.class b/target/classes/com/minexd/zoot/profile/punishment/command/UnbanCommand.class new file mode 100644 index 0000000..25dc4c0 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/command/UnbanCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/command/UnmuteCommand.class b/target/classes/com/minexd/zoot/profile/punishment/command/UnmuteCommand.class new file mode 100644 index 0000000..a262dfa Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/command/UnmuteCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/command/WarnCommand.class b/target/classes/com/minexd/zoot/profile/punishment/command/WarnCommand.class new file mode 100644 index 0000000..0429e57 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/command/WarnCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/listener/PunishmentListener$1.class b/target/classes/com/minexd/zoot/profile/punishment/listener/PunishmentListener$1.class new file mode 100644 index 0000000..93d9d19 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/listener/PunishmentListener$1.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/listener/PunishmentListener$2.class b/target/classes/com/minexd/zoot/profile/punishment/listener/PunishmentListener$2.class new file mode 100644 index 0000000..4e05179 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/listener/PunishmentListener$2.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/listener/PunishmentListener.class b/target/classes/com/minexd/zoot/profile/punishment/listener/PunishmentListener.class new file mode 100644 index 0000000..e234af9 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/listener/PunishmentListener.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/menu/PunishmentsListMenu$PunishmentInfoButton.class b/target/classes/com/minexd/zoot/profile/punishment/menu/PunishmentsListMenu$PunishmentInfoButton.class new file mode 100644 index 0000000..a517af3 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/menu/PunishmentsListMenu$PunishmentInfoButton.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/menu/PunishmentsListMenu.class b/target/classes/com/minexd/zoot/profile/punishment/menu/PunishmentsListMenu.class new file mode 100644 index 0000000..c78f137 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/menu/PunishmentsListMenu.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedure.class b/target/classes/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedure.class new file mode 100644 index 0000000..3ea48b2 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedure.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureStage.class b/target/classes/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureStage.class new file mode 100644 index 0000000..ed2c73c Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureStage.class differ diff --git a/target/classes/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureType.class b/target/classes/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureType.class new file mode 100644 index 0000000..3ef300e Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/punishment/procedure/PunishmentProcedureType.class differ diff --git a/target/classes/com/minexd/zoot/profile/staff/ProfileStaffOptions.class b/target/classes/com/minexd/zoot/profile/staff/ProfileStaffOptions.class new file mode 100644 index 0000000..2ee500e Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/staff/ProfileStaffOptions.class differ diff --git a/target/classes/com/minexd/zoot/profile/staff/command/AltsCommand.class b/target/classes/com/minexd/zoot/profile/staff/command/AltsCommand.class new file mode 100644 index 0000000..465ec61 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/staff/command/AltsCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/staff/command/StaffChatCommand.class b/target/classes/com/minexd/zoot/profile/staff/command/StaffChatCommand.class new file mode 100644 index 0000000..8447317 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/staff/command/StaffChatCommand.class differ diff --git a/target/classes/com/minexd/zoot/profile/staff/command/StaffModeCommand.class b/target/classes/com/minexd/zoot/profile/staff/command/StaffModeCommand.class new file mode 100644 index 0000000..f633a92 Binary files /dev/null and b/target/classes/com/minexd/zoot/profile/staff/command/StaffModeCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/Rank.class b/target/classes/com/minexd/zoot/rank/Rank.class new file mode 100644 index 0000000..5b2c801 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/Rank.class differ diff --git a/target/classes/com/minexd/zoot/rank/RankTypeAdapter.class b/target/classes/com/minexd/zoot/rank/RankTypeAdapter.class new file mode 100644 index 0000000..d6dd2c4 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/RankTypeAdapter.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankAddPermissionCommand.class b/target/classes/com/minexd/zoot/rank/command/RankAddPermissionCommand.class new file mode 100644 index 0000000..7787c5c Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankAddPermissionCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankCreateCommand.class b/target/classes/com/minexd/zoot/rank/command/RankCreateCommand.class new file mode 100644 index 0000000..4b6f7d8 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankCreateCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankDeleteCommand.class b/target/classes/com/minexd/zoot/rank/command/RankDeleteCommand.class new file mode 100644 index 0000000..7d5a4d9 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankDeleteCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankHelpCommand.class b/target/classes/com/minexd/zoot/rank/command/RankHelpCommand.class new file mode 100644 index 0000000..bfd40b7 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankHelpCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankInfoCommand.class b/target/classes/com/minexd/zoot/rank/command/RankInfoCommand.class new file mode 100644 index 0000000..5bf1400 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankInfoCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankInheritCommand.class b/target/classes/com/minexd/zoot/rank/command/RankInheritCommand.class new file mode 100644 index 0000000..9dc8049 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankInheritCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankRemovePermissionCommand.class b/target/classes/com/minexd/zoot/rank/command/RankRemovePermissionCommand.class new file mode 100644 index 0000000..ba15d72 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankRemovePermissionCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankSetColorCommand.class b/target/classes/com/minexd/zoot/rank/command/RankSetColorCommand.class new file mode 100644 index 0000000..1a58dc0 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankSetColorCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankSetPrefixCommand.class b/target/classes/com/minexd/zoot/rank/command/RankSetPrefixCommand.class new file mode 100644 index 0000000..5a2cef2 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankSetPrefixCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankSetSuffixCommand.class b/target/classes/com/minexd/zoot/rank/command/RankSetSuffixCommand.class new file mode 100644 index 0000000..af2f167 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankSetSuffixCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankSetWeightCommand.class b/target/classes/com/minexd/zoot/rank/command/RankSetWeightCommand.class new file mode 100644 index 0000000..27790e9 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankSetWeightCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RankUninheritCommand.class b/target/classes/com/minexd/zoot/rank/command/RankUninheritCommand.class new file mode 100644 index 0000000..d2bda37 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RankUninheritCommand.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RanksCommand$1.class b/target/classes/com/minexd/zoot/rank/command/RanksCommand$1.class new file mode 100644 index 0000000..d6eaec6 Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RanksCommand$1.class differ diff --git a/target/classes/com/minexd/zoot/rank/command/RanksCommand.class b/target/classes/com/minexd/zoot/rank/command/RanksCommand.class new file mode 100644 index 0000000..2f614bf Binary files /dev/null and b/target/classes/com/minexd/zoot/rank/command/RanksCommand.class differ diff --git a/target/classes/com/minexd/zoot/util/BaseEvent.class b/target/classes/com/minexd/zoot/util/BaseEvent.class new file mode 100644 index 0000000..fe34a60 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/BaseEvent.class differ diff --git a/target/classes/com/minexd/zoot/util/BukkitReflection.class b/target/classes/com/minexd/zoot/util/BukkitReflection.class new file mode 100644 index 0000000..d5b4a6c Binary files /dev/null and b/target/classes/com/minexd/zoot/util/BukkitReflection.class differ diff --git a/target/classes/com/minexd/zoot/util/CC.class b/target/classes/com/minexd/zoot/util/CC.class new file mode 100644 index 0000000..2171ccb Binary files /dev/null and b/target/classes/com/minexd/zoot/util/CC.class differ diff --git a/target/classes/com/minexd/zoot/util/ChatHelper.class b/target/classes/com/minexd/zoot/util/ChatHelper.class new file mode 100644 index 0000000..7081478 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/ChatHelper.class differ diff --git a/target/classes/com/minexd/zoot/util/Cooldown.class b/target/classes/com/minexd/zoot/util/Cooldown.class new file mode 100644 index 0000000..458d524 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/Cooldown.class differ diff --git a/target/classes/com/minexd/zoot/util/ItemBuilder.class b/target/classes/com/minexd/zoot/util/ItemBuilder.class new file mode 100644 index 0000000..6a07477 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/ItemBuilder.class differ diff --git a/target/classes/com/minexd/zoot/util/LocationUtil.class b/target/classes/com/minexd/zoot/util/LocationUtil.class new file mode 100644 index 0000000..0c8889f Binary files /dev/null and b/target/classes/com/minexd/zoot/util/LocationUtil.class differ diff --git a/target/classes/com/minexd/zoot/util/PotionUtil.class b/target/classes/com/minexd/zoot/util/PotionUtil.class new file mode 100644 index 0000000..ae2ce7e Binary files /dev/null and b/target/classes/com/minexd/zoot/util/PotionUtil.class differ diff --git a/target/classes/com/minexd/zoot/util/TextSplitter.class b/target/classes/com/minexd/zoot/util/TextSplitter.class new file mode 100644 index 0000000..8267721 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/TextSplitter.class differ diff --git a/target/classes/com/minexd/zoot/util/TimeUtil.class b/target/classes/com/minexd/zoot/util/TimeUtil.class new file mode 100644 index 0000000..3121d87 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/TimeUtil.class differ diff --git a/target/classes/com/minexd/zoot/util/adapter/ChatColorTypeAdapter.class b/target/classes/com/minexd/zoot/util/adapter/ChatColorTypeAdapter.class new file mode 100644 index 0000000..8029af9 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/adapter/ChatColorTypeAdapter.class differ diff --git a/target/classes/com/minexd/zoot/util/callback/Callback.class b/target/classes/com/minexd/zoot/util/callback/Callback.class new file mode 100644 index 0000000..f517081 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/callback/Callback.class differ diff --git a/target/classes/com/minexd/zoot/util/callback/ReturnableTypeCallback.class b/target/classes/com/minexd/zoot/util/callback/ReturnableTypeCallback.class new file mode 100644 index 0000000..a922cb1 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/callback/ReturnableTypeCallback.class differ diff --git a/target/classes/com/minexd/zoot/util/callback/TypeCallback.class b/target/classes/com/minexd/zoot/util/callback/TypeCallback.class new file mode 100644 index 0000000..a3c6a53 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/callback/TypeCallback.class differ diff --git a/target/classes/com/minexd/zoot/util/duration/Duration.class b/target/classes/com/minexd/zoot/util/duration/Duration.class new file mode 100644 index 0000000..96da0da Binary files /dev/null and b/target/classes/com/minexd/zoot/util/duration/Duration.class differ diff --git a/target/classes/com/minexd/zoot/util/duration/DurationTypeAdapter.class b/target/classes/com/minexd/zoot/util/duration/DurationTypeAdapter.class new file mode 100644 index 0000000..af654e7 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/duration/DurationTypeAdapter.class differ diff --git a/target/classes/com/minexd/zoot/util/json/JsonChain.class b/target/classes/com/minexd/zoot/util/json/JsonChain.class new file mode 100644 index 0000000..d691b62 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/json/JsonChain.class differ diff --git a/target/classes/com/minexd/zoot/util/json/JsonDeserializer.class b/target/classes/com/minexd/zoot/util/json/JsonDeserializer.class new file mode 100644 index 0000000..c8f38a5 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/json/JsonDeserializer.class differ diff --git a/target/classes/com/minexd/zoot/util/json/JsonSerializer.class b/target/classes/com/minexd/zoot/util/json/JsonSerializer.class new file mode 100644 index 0000000..cd97abe Binary files /dev/null and b/target/classes/com/minexd/zoot/util/json/JsonSerializer.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/Button$1.class b/target/classes/com/minexd/zoot/util/menu/Button$1.class new file mode 100644 index 0000000..60e9924 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/Button$1.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/Button.class b/target/classes/com/minexd/zoot/util/menu/Button.class new file mode 100644 index 0000000..ee3e3dd Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/Button.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/Menu.class b/target/classes/com/minexd/zoot/util/menu/Menu.class new file mode 100644 index 0000000..948b45c Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/Menu.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/MenuListener.class b/target/classes/com/minexd/zoot/util/menu/MenuListener.class new file mode 100644 index 0000000..79c3e7f Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/MenuListener.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/button/BackButton.class b/target/classes/com/minexd/zoot/util/menu/button/BackButton.class new file mode 100644 index 0000000..6cc64bd Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/button/BackButton.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/button/ConfirmationButton.class b/target/classes/com/minexd/zoot/util/menu/button/ConfirmationButton.class new file mode 100644 index 0000000..b194e6a Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/button/ConfirmationButton.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/button/DisplayButton.class b/target/classes/com/minexd/zoot/util/menu/button/DisplayButton.class new file mode 100644 index 0000000..91f0b41 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/button/DisplayButton.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/button/JumpToMenuButton.class b/target/classes/com/minexd/zoot/util/menu/button/JumpToMenuButton.class new file mode 100644 index 0000000..4e9468e Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/button/JumpToMenuButton.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/menus/ConfirmMenu.class b/target/classes/com/minexd/zoot/util/menu/menus/ConfirmMenu.class new file mode 100644 index 0000000..b0500d9 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/menus/ConfirmMenu.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/pagination/FilterablePaginatedMenu.class b/target/classes/com/minexd/zoot/util/menu/pagination/FilterablePaginatedMenu.class new file mode 100644 index 0000000..b341e0b Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/pagination/FilterablePaginatedMenu.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/pagination/JumpToPageButton.class b/target/classes/com/minexd/zoot/util/menu/pagination/JumpToPageButton.class new file mode 100644 index 0000000..30f23a0 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/pagination/JumpToPageButton.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/pagination/PageButton.class b/target/classes/com/minexd/zoot/util/menu/pagination/PageButton.class new file mode 100644 index 0000000..30715de Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/pagination/PageButton.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/pagination/PageFilter.class b/target/classes/com/minexd/zoot/util/menu/pagination/PageFilter.class new file mode 100644 index 0000000..eb053d2 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/pagination/PageFilter.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/pagination/PageFilterButton.class b/target/classes/com/minexd/zoot/util/menu/pagination/PageFilterButton.class new file mode 100644 index 0000000..99360d8 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/pagination/PageFilterButton.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/pagination/PageInfoButton.class b/target/classes/com/minexd/zoot/util/menu/pagination/PageInfoButton.class new file mode 100644 index 0000000..e29f699 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/pagination/PageInfoButton.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/pagination/PaginatedMenu.class b/target/classes/com/minexd/zoot/util/menu/pagination/PaginatedMenu.class new file mode 100644 index 0000000..a43c9d8 Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/pagination/PaginatedMenu.class differ diff --git a/target/classes/com/minexd/zoot/util/menu/pagination/ViewAllPagesMenu.class b/target/classes/com/minexd/zoot/util/menu/pagination/ViewAllPagesMenu.class new file mode 100644 index 0000000..5377dff Binary files /dev/null and b/target/classes/com/minexd/zoot/util/menu/pagination/ViewAllPagesMenu.class differ diff --git a/target/classes/config.yml b/target/classes/config.yml new file mode 100644 index 0000000..0a56f62 --- /dev/null +++ b/target/classes/config.yml @@ -0,0 +1,60 @@ +CONFIG_VERSION: 1 +SERVER_NAME: "Development" +MONGO: + HOST: "127.0.0.1" + PORT: 27017 + AUTHENTICATION: + ENABLED: false + USERNAME: "" + PASSWORD: "" +REDIS: + HOST: "127.0.0.1" + PORT: 6379 + AUTHENTICATION: + ENABLED: false + PASSWORD: "" +SETTINGS: + UPDATE_PLAYER_LIST_NAME: true +PUNISHMENTS: + BROADCAST: "&r{target} &ahas been {context} by &r{sender}" + BROADCAST_SILENT: "&7[Silent] &r{target} &ahas been {context} by &r{sender}" + BAN: + KICK: "&cYour account is {context} from Zonix.{temporary}\n\n&cIf you feel this punishment is unjust, you may appeal at:\n&ehttps://www.zonix.com" + TEMPORARY: "\n&cThis punishment expires in &e{time-remaining}&c." + KICK: + KICK: "&cYou were kicked by a staff member.\nReason: &e{reason}" +COMMON_ERRORS: + FAILED_TO_LOAD_PROFILE: "&cFailed to load your profile. Try again later." + COULD_NOT_RESOLVE_PLAYER: "&cCould not resolve player information..." + PLAYER_NOT_FOUND: "&cA player with that name could not be found." + RANK_NOT_FOUND: "&cA rank with that name could not be found." +STAFF: + CHAT: "{0}&r{1}&b ({2}): {3}" + BROADCAST_PREFIX: "&9&l[Staff] &r" + JOIN_NETWORK: "{0}{1} &ajoined the network &2({2})" + LEAVE_NETWORK: "{0}{1} &aleft the network" + SWITCH_SERVER: "{0}({1} &ajoined {2} &2(from {3})" +NETWORK: + BROADCAST_PREFIX: "&8[&eNetwork&8] &f" + RANK_REFRESH: "{0}Refreshed rank \"{1}\"" + RANK_DELETE: "{0}Deleted rank \"{1}\"" +CHAT: + FORMAT: "%1$s&r: %2$s" + CLEAR_CHAT_BROADCAST: "&eThe chat has been cleared by &r{0}" + CLEAR_CHAT_FOR_STAFF: false + MUTE_CHAT_BROADCAST: "&eThe chat has been {0} by &r{1}" + DELAY_CHAT_ENABLED_BROADCAST: "&eThe chat has been delayed by &r{0} &7({1} second{2})" + DELAY_CHAT_DISABLED_BROADCAST: "&eThe chat delay has been lifted by &r{0}" + CHAT_DELAYED: "&cSlow down! You may chat again in {0} seconds." +# using both text formatter and text replacing because I need to escape colors in the input message +# format: player name, player display name, player color, target name, target display name, target color +CONVERSATION: + SEND_MESSAGE: "&7(To &r{5}{3}&7) %MSG%" + RECEIVE_MESSAGE: "&7(From &r{5}{3}&7) %MSG%" +OPTIONS: + GLOBAL_CHAT_ENABLED: "&eYou can now see global chat." + GLOBAL_CHAT_DISABLED: "&cYou will no longer see global chat." + PRIVATE_MESSAGES_ENABLED: "&aYou can now receive new conversations." + PRIVATE_MESSAGES_DISABLED: "&cYou can no longer receive new conversations. If you start a conversation with a player, they will be able to message you back." + PRIVATE_MESSAGE_SOUNDS_ENABLED: "&eYou enabled private message sounds." + PRIVATE_MESSAGE_SOUNDS_DISABLED: "&cYou disabled private message sounds." \ No newline at end of file diff --git a/target/classes/plugin.yml b/target/classes/plugin.yml new file mode 100644 index 0000000..1f4e2dd --- /dev/null +++ b/target/classes/plugin.yml @@ -0,0 +1,5 @@ +main: com.minexd.zoot.Zoot +name: Zoot +author: joeleoli +version: 1.0 +depend: [ProtocolLib] \ No newline at end of file diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties new file mode 100644 index 0000000..4f1fe29 --- /dev/null +++ b/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Sun Feb 17 16:58:10 EST 2019 +version=1.0-SNAPSHOT +groupId=com.minexd +artifactId=zoot diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..0dfb432 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,185 @@ +com\minexd\zoot\util\menu\pagination\FilterablePaginatedMenu.class +com\minexd\zoot\Zoot$2.class +com\minexd\zoot\network\packet\PacketRefreshRank.class +com\minexd\zoot\profile\grant\GrantJsonDeserializer.class +com\minexd\zoot\rank\command\RankSetSuffixCommand.class +com\minexd\zoot\pidgin\packet\handler\IncomingPacketHandler.class +com\minexd\zoot\essentials\command\SpawnCommand.class +com\minexd\zoot\config\ConfigValidation.class +com\minexd\zoot\util\menu\MenuListener.class +com\minexd\zoot\Locale.class +com\minexd\zoot\util\LocationUtil.class +com\minexd\zoot\util\menu\Button$1.class +com\minexd\zoot\util\menu\Menu.class +com\minexd\zoot\profile\punishment\menu\PunishmentsListMenu$PunishmentInfoButton.class +com\minexd\zoot\chat\ChatListener$1.class +com\minexd\zoot\profile\option\ProfileOptions.class +com\minexd\zoot\profile\grant\procedure\GrantProcedure.class +com\minexd\zoot\util\callback\TypeCallback.class +com\minexd\zoot\util\ChatHelper.class +com\minexd\zoot\ZootAPI.class +com\minexd\zoot\profile\staff\command\StaffModeCommand.class +com\minexd\zoot\profile\conversation\command\ReplyCommand.class +com\minexd\zoot\chat\filter\impl\LinkFilter.class +com\minexd\zoot\profile\ProfileListener.class +com\minexd\zoot\profile\grant\menu\GrantsListMenu.class +com\minexd\zoot\util\BaseEvent.class +com\minexd\zoot\rank\command\RankAddPermissionCommand.class +com\minexd\zoot\rank\command\RanksCommand.class +com\minexd\zoot\profile\conversation\ProfileConversations.class +com\minexd\zoot\util\Cooldown.class +com\minexd\zoot\profile\option\menu\button\PrivateChatOptionButton.class +com\minexd\zoot\network\packet\PacketStaffLeaveNetwork.class +com\minexd\zoot\util\TimeUtil.class +com\minexd\zoot\profile\staff\ProfileStaffOptions.class +com\minexd\zoot\chat\command\MuteChatCommand.class +com\minexd\zoot\rank\command\RankDeleteCommand.class +com\minexd\zoot\essentials\event\SpawnTeleportEvent.class +com\minexd\zoot\profile\grant\event\GrantAppliedEvent.class +com\minexd\zoot\rank\command\RankRemovePermissionCommand.class +com\minexd\zoot\rank\command\RankSetPrefixCommand.class +com\minexd\zoot\chat\ChatListener.class +com\minexd\zoot\essentials\command\NightCommand.class +com\minexd\zoot\network\packet\PacketAddGrant.class +com\minexd\zoot\rank\command\RankUninheritCommand.class +com\minexd\zoot\bootstrap\Bootstrapped.class +com\minexd\zoot\pidgin\packet\listener\PacketListenerData.class +com\minexd\zoot\profile\staff\command\AltsCommand.class +com\minexd\zoot\profile\punishment\menu\PunishmentsListMenu.class +com\minexd\zoot\profile\punishment\command\MuteCommand.class +com\minexd\zoot\util\CC.class +com\minexd\zoot\essentials\command\PingCommand.class +com\minexd\zoot\essentials\command\ClearCommand.class +com\minexd\zoot\config\impl\ConfigConversion3.class +com\minexd\zoot\profile\punishment\procedure\PunishmentProcedureStage.class +com\minexd\zoot\util\PotionUtil.class +com\minexd\zoot\rank\RankTypeAdapter.class +com\minexd\zoot\chat\util\ChatComponentBuilder.class +com\minexd\zoot\pidgin\packet\Packet.class +com\minexd\zoot\rank\Rank.class +com\minexd\zoot\profile\grant\procedure\GrantProcedureType.class +com\minexd\zoot\profile\punishment\command\WarnCommand.class +com\minexd\zoot\essentials\command\GameModeCommand.class +com\minexd\zoot\profile\ProfileTypeAdapter.class +com\minexd\zoot\essentials\command\SetSlotsCommand.class +com\minexd\zoot\util\ItemBuilder.class +com\minexd\zoot\essentials\command\ShowPlayerCommand.class +com\minexd\zoot\profile\grant\menu\GrantsListMenu$GrantInfoButton.class +com\minexd\zoot\chat\filter\impl\ContainsFilter.class +com\minexd\zoot\util\menu\button\JumpToMenuButton.class +com\minexd\zoot\chat\filter\ChatFilter.class +com\minexd\zoot\pidgin\packet\handler\PacketExceptionHandler.class +com\minexd\zoot\util\menu\button\ConfirmationButton.class +com\minexd\zoot\essentials\command\DayCommand.class +com\minexd\zoot\network\packet\PacketStaffJoinNetwork.class +com\minexd\zoot\config\impl\ConfigConversion2.class +com\minexd\zoot\profile\grant\command\GrantsCommand.class +com\minexd\zoot\profile\punishment\listener\PunishmentListener.class +com\minexd\zoot\util\duration\Duration.class +com\minexd\zoot\profile\punishment\Punishment.class +com\minexd\zoot\util\menu\button\DisplayButton.class +com\minexd\zoot\network\packet\PacketStaffChat.class +com\minexd\zoot\util\menu\button\BackButton.class +com\minexd\zoot\essentials\command\HidePlayerCommand.class +com\minexd\zoot\util\json\JsonDeserializer.class +com\minexd\zoot\network\packet\PacketDeleteRank.class +com\minexd\zoot\profile\option\event\OptionsOpenedEvent.class +com\minexd\zoot\profile\option\command\ToggleSoundsCommand.class +com\minexd\zoot\profile\punishment\command\UnbanCommand.class +com\minexd\zoot\rank\command\RankInheritCommand.class +com\minexd\zoot\network\NetworkPacketListener$1.class +com\minexd\zoot\profile\Profile.class +com\minexd\zoot\essentials\Essentials.class +com\minexd\zoot\essentials\command\HealCommand.class +com\minexd\zoot\profile\conversation\command\MessageCommand.class +com\minexd\zoot\network\event\ReceiveStaffChatEvent.class +com\minexd\zoot\profile\option\command\ToggleGlobalChatCommand.class +com\minexd\zoot\config\impl\ConfigConversion1.class +com\minexd\zoot\util\adapter\ChatColorTypeAdapter.class +com\minexd\zoot\util\BukkitReflection.class +com\minexd\zoot\util\menu\pagination\PageFilter.class +com\minexd\zoot\essentials\command\LocationCommand.class +com\minexd\zoot\profile\punishment\PunishmentType.class +com\minexd\zoot\profile\option\menu\button\PrivateChatSoundsOptionButton.class +com\minexd\zoot\rank\command\RankCreateCommand.class +com\minexd\zoot\essentials\command\ZootDebugCommand.class +com\minexd\zoot\network\packet\PacketBroadcastPunishment.class +com\minexd\zoot\profile\punishment\command\BanCommand.class +com\minexd\zoot\rank\command\RankSetWeightCommand.class +com\minexd\zoot\network\packet\PacketStaffSwitchServer.class +com\minexd\zoot\profile\punishment\procedure\PunishmentProcedureType.class +com\minexd\zoot\network\NetworkPacketListener.class +com\minexd\zoot\profile\ProfileListener$1.class +com\minexd\zoot\profile\conversation\Conversation.class +com\minexd\zoot\config\ConfigVersion.class +com\minexd\zoot\essentials\command\ListCommand$1.class +com\minexd\zoot\pidgin\packet\listener\PacketListener.class +com\minexd\zoot\util\menu\pagination\JumpToPageButton.class +com\minexd\zoot\chat\command\SlowChatCommand.class +com\minexd\zoot\util\TextSplitter.class +com\minexd\zoot\rank\command\RankHelpCommand.class +com\minexd\zoot\chat\command\ClearChatCommand.class +com\minexd\zoot\util\duration\DurationTypeAdapter.class +com\minexd\zoot\util\menu\pagination\PaginatedMenu.class +com\minexd\zoot\profile\option\command\OptionsCommand.class +com\minexd\zoot\util\callback\ReturnableTypeCallback.class +com\minexd\zoot\util\callback\Callback.class +com\minexd\zoot\profile\grant\Grant.class +com\minexd\zoot\essentials\command\MoreCommand.class +com\minexd\zoot\profile\punishment\PunishmentJsonDeserializer.class +com\minexd\zoot\profile\punishment\command\KickCommand.class +com\minexd\zoot\profile\punishment\PunishmentType$PunishmentTypeData.class +com\minexd\zoot\cache\RedisCache.class +com\minexd\zoot\profile\grant\GrantListener$2.class +com\minexd\zoot\profile\punishment\command\KickCommand$1.class +com\minexd\zoot\util\menu\pagination\PageButton.class +com\minexd\zoot\chat\event\ChatAttemptEvent.class +com\minexd\zoot\profile\punishment\command\BanCommand$1.class +com\minexd\zoot\Zoot$1.class +com\minexd\zoot\chat\ChatAttempt.class +com\minexd\zoot\util\menu\Button.class +com\minexd\zoot\essentials\command\BroadcastCommand.class +com\minexd\zoot\essentials\command\ListCommand.class +com\minexd\zoot\profile\punishment\listener\PunishmentListener$2.class +com\minexd\zoot\profile\grant\event\GrantExpireEvent.class +com\minexd\zoot\Zoot.class +com\minexd\zoot\profile\option\menu\button\PublicChatOptionButton.class +com\minexd\zoot\cache\RedisPlayerData$LastAction.class +com\minexd\zoot\cache\RedisPlayerData.class +com\minexd\zoot\profile\punishment\command\UnmuteCommand.class +com\minexd\zoot\rank\command\RanksCommand$1.class +com\minexd\zoot\profile\punishment\procedure\PunishmentProcedure.class +com\minexd\zoot\essentials\command\TeleportWorldCommand.class +com\minexd\zoot\profile\option\menu\ProfileOptionsMenu.class +com\minexd\zoot\network\packet\PacketDeleteGrant.class +com\minexd\zoot\rank\command\RankInfoCommand.class +com\minexd\zoot\chat\Chat.class +com\minexd\zoot\chat\ChatAttempt$Response.class +com\minexd\zoot\essentials\command\SunsetCommand.class +com\minexd\zoot\profile\punishment\command\CheckCommand.class +com\minexd\zoot\bootstrap\BootstrappedListener.class +com\minexd\zoot\profile\menu\ProfileMenuControlHeaderButton.class +com\minexd\zoot\util\menu\menus\ConfirmMenu.class +com\minexd\zoot\profile\grant\procedure\GrantProcedureStage.class +com\minexd\zoot\rank\command\RankSetColorCommand.class +com\minexd\zoot\profile\punishment\PunishmentJsonSerializer.class +com\minexd\zoot\util\menu\pagination\PageInfoButton.class +com\minexd\zoot\profile\grant\command\GrantCommand.class +com\minexd\zoot\profile\grant\GrantListener.class +com\minexd\zoot\profile\staff\command\StaffChatCommand.class +com\minexd\zoot\profile\grant\GrantJsonSerializer.class +com\minexd\zoot\profile\grant\GrantListener$1.class +com\minexd\zoot\essentials\command\RenameCommand.class +com\minexd\zoot\essentials\EssentialsListener.class +com\minexd\zoot\util\menu\pagination\ViewAllPagesMenu.class +com\minexd\zoot\essentials\command\SetSpawnCommand.class +com\minexd\zoot\pidgin\Pidgin$1.class +com\minexd\zoot\profile\option\menu\ProfileOptionButton.class +com\minexd\zoot\util\menu\pagination\PageFilterButton.class +com\minexd\zoot\profile\option\command\TogglePrivateMessagesCommand.class +com\minexd\zoot\pidgin\Pidgin.class +com\minexd\zoot\util\json\JsonSerializer.class +com\minexd\zoot\util\json\JsonChain.class +com\minexd\zoot\config\ConfigConversion.class +com\minexd\zoot\essentials\command\ListCommand$2.class +com\minexd\zoot\profile\punishment\listener\PunishmentListener$1.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..1441f0f --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,164 @@ +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\packet\PacketStaffSwitchServer.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\config\impl\ConfigConversion1.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\menu\GrantsListMenu.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\packet\PacketStaffLeaveNetwork.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\listener\PunishmentListener.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\menus\ConfirmMenu.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\event\ChatAttemptEvent.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\PingCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\HidePlayerCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\MenuListener.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\command\TogglePrivateMessagesCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\SpawnCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\PunishmentJsonDeserializer.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\Essentials.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\Menu.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\filter\impl\LinkFilter.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\TimeUtil.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\packet\PacketRefreshRank.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\LocationUtil.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\pagination\JumpToPageButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\conversation\command\ReplyCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\event\GrantExpireEvent.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\command\GrantsCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\PunishmentJsonSerializer.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\SetSpawnCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\pidgin\packet\Packet.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\command\BanCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\Zoot.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\BukkitReflection.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\command\WarnCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\event\OptionsOpenedEvent.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\pagination\PageFilterButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\config\impl\ConfigConversion2.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\staff\command\StaffChatCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankAddPermissionCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankUninheritCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\menu\button\PublicChatOptionButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\pagination\ViewAllPagesMenu.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\event\SpawnTeleportEvent.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\pagination\PaginatedMenu.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\ShowPlayerCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\callback\TypeCallback.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\RenameCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\adapter\ChatColorTypeAdapter.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\procedure\GrantProcedure.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\config\ConfigValidation.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\NightCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankInheritCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankSetSuffixCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\bootstrap\Bootstrapped.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\pagination\FilterablePaginatedMenu.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\HealCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\staff\command\StaffModeCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\EssentialsListener.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\duration\DurationTypeAdapter.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\button\JumpToMenuButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\pagination\PageButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\TeleportWorldCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\event\ReceiveStaffChatEvent.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\conversation\command\MessageCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\PotionUtil.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankSetWeightCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\Cooldown.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\Button.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankHelpCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\command\KickCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\conversation\Conversation.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\pidgin\packet\handler\PacketExceptionHandler.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\menu\ProfileOptionsMenu.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\button\BackButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\button\ConfirmationButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\callback\Callback.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\pagination\PageInfoButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\filter\impl\ContainsFilter.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\GrantJsonSerializer.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\button\DisplayButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\Locale.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\CC.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\Profile.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\RankTypeAdapter.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\command\ToggleSoundsCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\menu\ProfileMenuControlHeaderButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\command\CheckCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\callback\ReturnableTypeCallback.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\util\ChatComponentBuilder.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\ListCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\BroadcastCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\command\MuteChatCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\pidgin\packet\listener\PacketListenerData.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\procedure\PunishmentProcedure.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\ChatHelper.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\MoreCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\menu\button\PrivateChatSoundsOptionButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\GameModeCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\PunishmentType.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankCreateCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankRemovePermissionCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\procedure\PunishmentProcedureType.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\command\ClearChatCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\bootstrap\BootstrappedListener.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\pidgin\Pidgin.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\ProfileOptions.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\staff\ProfileStaffOptions.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\cache\RedisPlayerData.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\json\JsonSerializer.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\pidgin\packet\handler\IncomingPacketHandler.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\ProfileListener.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\BaseEvent.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\packet\PacketAddGrant.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\event\GrantAppliedEvent.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\ChatAttempt.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\filter\ChatFilter.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\ItemBuilder.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\Rank.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\LocationCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\packet\PacketDeleteRank.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\menu\PunishmentsListMenu.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\conversation\ProfileConversations.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\packet\PacketBroadcastPunishment.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankSetColorCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\config\ConfigConversion.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankInfoCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\duration\Duration.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\menu\button\PrivateChatOptionButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\Chat.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\config\ConfigVersion.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\Punishment.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\menu\ProfileOptionButton.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\TextSplitter.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\DayCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\menu\pagination\PageFilter.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\staff\command\AltsCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RanksCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\command\UnbanCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\ClearCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\NetworkPacketListener.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\command\UnmuteCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\packet\PacketDeleteGrant.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\packet\PacketStaffChat.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\ProfileTypeAdapter.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\network\packet\PacketStaffJoinNetwork.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\pidgin\packet\listener\PacketListener.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\cache\RedisCache.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\GrantJsonDeserializer.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\json\JsonChain.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\procedure\GrantProcedureStage.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\ChatListener.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\Grant.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\ZootAPI.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\SunsetCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankDeleteCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\command\GrantCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\command\OptionsCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\util\json\JsonDeserializer.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\SetSlotsCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\GrantListener.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\rank\command\RankSetPrefixCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\grant\procedure\GrantProcedureType.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\essentials\command\ZootDebugCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\option\command\ToggleGlobalChatCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\command\MuteCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\config\impl\ConfigConversion3.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\chat\command\SlowChatCommand.java +C:\Zoot\zoot\src\main\java\com\minexd\zoot\profile\punishment\procedure\PunishmentProcedureStage.java diff --git a/target/original-zoot-1.0-SNAPSHOT.jar b/target/original-zoot-1.0-SNAPSHOT.jar new file mode 100644 index 0000000..27e3f08 Binary files /dev/null and b/target/original-zoot-1.0-SNAPSHOT.jar differ diff --git a/target/zoot-1.0-SNAPSHOT.jar b/target/zoot-1.0-SNAPSHOT.jar new file mode 100644 index 0000000..de1f741 Binary files /dev/null and b/target/zoot-1.0-SNAPSHOT.jar differ diff --git a/zoot.iml b/zoot.iml new file mode 100644 index 0000000..e936585 --- /dev/null +++ b/zoot.iml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file