diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/arcade/src/main/java/zone/themcgamer/arcade/map/MapManager.java b/arcade/src/main/java/zone/themcgamer/arcade/map/MapManager.java index bc251d0..84d8509 100644 --- a/arcade/src/main/java/zone/themcgamer/arcade/map/MapManager.java +++ b/arcade/src/main/java/zone/themcgamer/arcade/map/MapManager.java @@ -6,6 +6,7 @@ import zone.themcgamer.common.ZipUtils; import zone.themcgamer.core.game.MGZGame; import zone.themcgamer.core.module.Module; import zone.themcgamer.core.module.ModuleInfo; +import zone.themcgamer.core.server.ServerManager; import zone.themcgamer.core.world.MGZWorld; import java.io.File; @@ -32,8 +33,7 @@ public class MapManager extends Module { if (!mapsDirectory.exists()) mapsDirectory.mkdirs(); for (MGZGame game : MGZGame.values()) { - File parsedMapsDirectory = new File(File.separator + "home" + File.separator + "minecraft" + File.separator + - "upload" + File.separator + "maps" + File.separator + game.name()); + File parsedMapsDirectory = new File(File.separator + "home" + File.separator + "minecraft" + File.separator + "ftp" + File.separator + "upload" + File.separator + "upload" + File.separator + "maps" + File.separator + game.name()); if (!parsedMapsDirectory.exists()) continue; File[] files = parsedMapsDirectory.listFiles(); @@ -56,6 +56,8 @@ public class MapManager extends Module { maps.add(new MGZWorld(targetDirectory)); } catch (IOException ex) { ex.printStackTrace(); + + MGZWorld mgzWorld; } } } diff --git a/buildserver/src/main/java/zone/themcgamer/buildServer/listener/PlayerListener.java b/buildserver/src/main/java/zone/themcgamer/buildServer/listener/PlayerListener.java index 119fba6..cee948e 100644 --- a/buildserver/src/main/java/zone/themcgamer/buildServer/listener/PlayerListener.java +++ b/buildserver/src/main/java/zone/themcgamer/buildServer/listener/PlayerListener.java @@ -10,10 +10,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; -import org.bukkit.event.player.AsyncPlayerChatEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.*; import org.bukkit.plugin.java.JavaPlugin; import zone.themcgamer.buildServer.Build; import zone.themcgamer.buildServer.world.WorldManager; @@ -106,4 +103,9 @@ public class PlayerListener implements Listener { private void onQuit(PlayerQuitEvent event) { event.setQuitMessage(Style.color("&8[&c-&8] &7" + event.getPlayer().getName())); } + + @EventHandler + private void onWorldChange(PlayerChangedWorldEvent event) { + event.getFrom().save(); + } } \ No newline at end of file diff --git a/buildserver/src/main/java/zone/themcgamer/buildServer/parse/ParseTask.java b/buildserver/src/main/java/zone/themcgamer/buildServer/parse/ParseTask.java index bee211e..70b3281 100644 --- a/buildserver/src/main/java/zone/themcgamer/buildServer/parse/ParseTask.java +++ b/buildserver/src/main/java/zone/themcgamer/buildServer/parse/ParseTask.java @@ -131,7 +131,7 @@ public class ParseTask { mgzWorld.save(new File(world.getWorldFolder(), MGZWorld.FILE_NAME)); // Zipping the parsed world - File targetDirectory = new File(File.separator + "home" + File.separator + "minecraft" + File.separator + "upload" + File.separator + + File targetDirectory = new File(File.separator + "home" + File.separator + "minecraft" + File.separator + "ftp" + File.separator + "upload" + File.separator + "upload" + File.separator + "maps" + File.separator + mgzWorld.getCategory().name()); if (!targetDirectory.exists()) targetDirectory.mkdirs(); diff --git a/buildserver/src/main/java/zone/themcgamer/buildServer/world/WorldManager.java b/buildserver/src/main/java/zone/themcgamer/buildServer/world/WorldManager.java index 4538986..829db38 100644 --- a/buildserver/src/main/java/zone/themcgamer/buildServer/world/WorldManager.java +++ b/buildserver/src/main/java/zone/themcgamer/buildServer/world/WorldManager.java @@ -128,6 +128,7 @@ public class WorldManager extends Module { if (mgzWorld != null) { if (world.getPlayers().isEmpty()) { setupWorld(world); + world.save(); Bukkit.unloadWorld(world, true); unloadWorld(mgzWorld); mgzWorld.setWorld(null); diff --git a/buildserver/src/main/java/zone/themcgamer/buildServer/world/command/CreateCommand.java b/buildserver/src/main/java/zone/themcgamer/buildServer/world/command/CreateCommand.java index e2e6ea8..01822c5 100644 --- a/buildserver/src/main/java/zone/themcgamer/buildServer/world/command/CreateCommand.java +++ b/buildserver/src/main/java/zone/themcgamer/buildServer/world/command/CreateCommand.java @@ -1,6 +1,7 @@ package zone.themcgamer.buildServer.world.command; import lombok.AllArgsConstructor; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; import zone.themcgamer.buildServer.world.WorldManager; @@ -52,5 +53,6 @@ public class CreateCommand { World world = worldManager.create(name, player.getName(), WorldCategory.OTHER, generator, preset); player.teleport(world.getSpawnLocation()); player.sendMessage(Style.main("Map", "Created a new map named §b" + name + "§7!")); + player.sendMessage(Style.color("Please pre-generate the world! Use /pregen")); } } \ No newline at end of file diff --git a/commons/src/main/java/zone/themcgamer/common/DoubleUtils.java b/commons/src/main/java/zone/themcgamer/common/DoubleUtils.java index 34b09da..af2497a 100644 --- a/commons/src/main/java/zone/themcgamer/common/DoubleUtils.java +++ b/commons/src/main/java/zone/themcgamer/common/DoubleUtils.java @@ -11,7 +11,7 @@ public class DoubleUtils { * Format the given value into a readable format * * @param amount the value to format - * @param shortSuffixes whether or not to have shorrt suffixes + * @param shortSuffixes whether or not to have short suffixes * @return the formatted value * @author Ell (modified by Braydon) */ diff --git a/commons/src/main/java/zone/themcgamer/common/HashUtils.java b/commons/src/main/java/zone/themcgamer/common/HashUtils.java index 4a4a482..9806262 100644 --- a/commons/src/main/java/zone/themcgamer/common/HashUtils.java +++ b/commons/src/main/java/zone/themcgamer/common/HashUtils.java @@ -17,8 +17,8 @@ public class HashUtils { try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(s.getBytes()); - byte digest[] = messageDigest.digest(); - StringBuffer buffer = new StringBuffer(); + byte[] digest = messageDigest.digest(); + StringBuilder buffer = new StringBuilder(); for (byte b : digest) buffer.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); return buffer.toString(); diff --git a/commons/src/main/java/zone/themcgamer/common/StringUtils.java b/commons/src/main/java/zone/themcgamer/common/StringUtils.java new file mode 100644 index 0000000..271dd34 --- /dev/null +++ b/commons/src/main/java/zone/themcgamer/common/StringUtils.java @@ -0,0 +1,4 @@ +package zone.themcgamer.common; + +public class StringUtils { +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 7f40490..58b071f 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,3 +1,11 @@ +repositories { + mavenCentral() + maven { + url = uri("http://repo.citizensnpcs.co/") + url = uri("https://repo.codemc.io/repository/maven-public/") + } +} + dependencies { api(project(":serverdata")) implementation("com.zaxxer:HikariCP:3.4.5") @@ -5,4 +13,6 @@ dependencies { implementation("com.github.cryptomorin:XSeries:7.8.0") implementation("com.warrenstrange:googleauth:1.4.0") implementation("com.google.zxing:javase:3.4.1") + compileOnly("com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.3") + compileOnly("net.citizensnpcs:citizensapi:2.0.28-SNAPSHOT") } \ No newline at end of file diff --git a/core/src/main/java/zone/themcgamer/core/account/AccountRepository.java b/core/src/main/java/zone/themcgamer/core/account/AccountRepository.java index ee48b43..9e4f072 100644 --- a/core/src/main/java/zone/themcgamer/core/account/AccountRepository.java +++ b/core/src/main/java/zone/themcgamer/core/account/AccountRepository.java @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.Objects; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -35,6 +36,7 @@ public class AccountRepository extends MySQLRepository { "(`id`, `uuid`, `name`, `primaryRank`, `secondaryRanks`, `gold`, `gems`, `ipAddress`, `firstLogin`, `lastLogin`) VALUES " + "(NULL, ?, ?, '" + Rank.DEFAULT.name() + "', '', '0', '0', ?, ?, ?);"; private static final String UPDATE_RANK = "UPDATE `accounts` SET `primaryRank` = ? WHERE `id` = ?;"; + private static final String UPDATE_SECONDARY = "UPDATE `accounts` SET `secondaryRanks` = ? WHERE `id` = ?;"; public AccountRepository(HikariDataSource dataSource) { super(dataSource); @@ -173,6 +175,14 @@ public class AccountRepository extends MySQLRepository { }); } + public void setUpdateSecondary(int accountId, Rank[] ranks) { + /*CompletableFuture.runAsync(() -> { + executeInsert(UPDATE_SECONDARY, new Column[] { + new StringColumn("secondaryRanks", ranks.length), + new IntegerColumn("id", accountId) + }); + });*/ + } public void clearRanks(int accountId) { String query = UPDATE_RANK .replaceFirst("\\?", "'" + Rank.DEFAULT.name() + "'") diff --git a/core/src/main/java/zone/themcgamer/core/account/command/GoldCommand.java b/core/src/main/java/zone/themcgamer/core/account/command/GoldCommand.java index 20a0fd8..575f0f1 100644 --- a/core/src/main/java/zone/themcgamer/core/account/command/GoldCommand.java +++ b/core/src/main/java/zone/themcgamer/core/account/command/GoldCommand.java @@ -17,9 +17,12 @@ public class GoldCommand { Player player = command.getPlayer(); String[] args = command.getArgs(); String target = player.getName(); + if (args.length > 0) target = args[0]; + String finalTarget = target; + accountManager.lookup(target, account -> { if (account == null) { player.sendMessage(Style.invalidAccount("Account", finalTarget)); diff --git a/core/src/main/java/zone/themcgamer/core/announce/Announcement.java b/core/src/main/java/zone/themcgamer/core/announce/Announcement.java new file mode 100644 index 0000000..da78d70 --- /dev/null +++ b/core/src/main/java/zone/themcgamer/core/announce/Announcement.java @@ -0,0 +1,15 @@ +package zone.themcgamer.core.announce; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import zone.themcgamer.data.jedis.command.impl.announce.AnnounceType; + +@AllArgsConstructor @Getter @Setter +public class Announcement { + + private String message; + private long period, delay; + private AnnounceType type; + +} diff --git a/core/src/main/java/zone/themcgamer/core/chat/component/impl/BasicRankComponent.java b/core/src/main/java/zone/themcgamer/core/chat/component/impl/BasicRankComponent.java index 98a9f35..0a7e84d 100644 --- a/core/src/main/java/zone/themcgamer/core/chat/component/impl/BasicRankComponent.java +++ b/core/src/main/java/zone/themcgamer/core/chat/component/impl/BasicRankComponent.java @@ -1,12 +1,14 @@ package zone.themcgamer.core.chat.component.impl; -import net.md_5.bungee.api.chat.*; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.entity.Player; import zone.themcgamer.common.MiscUtils; import zone.themcgamer.core.account.Account; import zone.themcgamer.core.account.AccountManager; import zone.themcgamer.core.chat.component.IChatComponent; -import zone.themcgamer.core.common.Style; import zone.themcgamer.data.Rank; import java.util.Optional; @@ -23,10 +25,8 @@ public class BasicRankComponent implements IChatComponent { return null; ComponentBuilder componentBuilder = new ComponentBuilder(account.getPrimaryRank().getPrefix()); componentBuilder.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(MiscUtils.arrayToString( - Style.color("&7This is &b" + account.getPrimaryRank().getDisplayName() + " &7rank"), - Style.color("&7Do you also want to stand out in the &achat&7?"), - Style.color("&e&lClick Me &7to donate and support the server!"))).create())); - componentBuilder.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/store")).create(); + account.getPrimaryRank().getPrefix(), + "§f" + account.getPrimaryRank().getDescription())).create())); return new TextComponent(componentBuilder.create()); } } diff --git a/core/src/main/java/zone/themcgamer/core/command/impl/debug/LocateCommand.java b/core/src/main/java/zone/themcgamer/core/command/impl/debug/LocateCommand.java new file mode 100644 index 0000000..04e603e --- /dev/null +++ b/core/src/main/java/zone/themcgamer/core/command/impl/debug/LocateCommand.java @@ -0,0 +1,16 @@ +package zone.themcgamer.core.command.impl.debug; + +import org.bukkit.entity.Player; +import zone.themcgamer.core.command.Command; +import zone.themcgamer.core.command.CommandProvider; +import zone.themcgamer.core.common.Style; +import zone.themcgamer.data.Rank; + +public class LocateCommand { + @Command(name = "location", aliases = "loc", ranks = Rank.BUILDER, description = "Get location you're at", playersOnly = true) + public void onCommand(CommandProvider command) { + Player player = command.getPlayer(); + if (player == null) return; + player.sendMessage(Style.main("Debug", "You're location & facing is: &b" + player.getLocation() + " &7facing: &6" + player.getEyeLocation())); + } +} diff --git a/core/src/main/java/zone/themcgamer/core/command/impl/staff/StaffClearChatCommand.java b/core/src/main/java/zone/themcgamer/core/command/impl/staff/StaffClearChatCommand.java new file mode 100644 index 0000000..2e6d957 --- /dev/null +++ b/core/src/main/java/zone/themcgamer/core/command/impl/staff/StaffClearChatCommand.java @@ -0,0 +1,63 @@ +package zone.themcgamer.core.command.impl.staff; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import zone.themcgamer.core.command.Command; +import zone.themcgamer.core.command.CommandProvider; +import zone.themcgamer.core.common.Style; +import zone.themcgamer.data.Rank; + +import java.util.function.Predicate; + +public class StaffClearChatCommand { + + @Command(name = "clearchat", aliases = {"cc"}, description = "Clears the chat.", ranks = {Rank.HELPER}) + public void onCommand(CommandProvider commandProvider) { + // Assuming that the Sender has sufficient permissions due to the provided condition that the rank + // must be HELPER + + // If there are no arguments, 100 new lines will sent instantly to make the current chat disappear + + // If there is one argument, if the argument is an integer, n new lines will be sent instantly to make + // the current chat disappear. + + // If there is more than one argument, an error message should be sent to the sender saying command + // mis-used + + switch (commandProvider.getArgs().length) { + case 0: + if (commandProvider.isPlayer()) { + send(100, player -> player.getUniqueId() != commandProvider.getPlayer().getUniqueId()); + } else { + send(100, $ -> true); + } + break; + case 1: + try { + int lines = Integer.parseInt(commandProvider.getArgs()[0]); + + if (commandProvider.isPlayer()) { + send(lines, player -> player.getUniqueId() != commandProvider.getPlayer().getUniqueId()); + } else { + send(lines, $ -> true); + } + }catch (Exception ignored) { + commandProvider.getSender().sendMessage(Style.error("ClearChat", + "Arguemnt is not an integer!")); + } + break; + default: + commandProvider.getSender().sendMessage(Style.error("ClearChat", + "Command mis-used!")); + break; + } + } + + private void send(int lines, Predicate condition) { + Bukkit.getOnlinePlayers().forEach(player -> { + if (condition.test(player)) + for (int index = 0; index < lines; index++) + player.sendMessage(""); + }); + } +} diff --git a/core/src/main/java/zone/themcgamer/core/command/impl/staff/StaffModeCommand.java b/core/src/main/java/zone/themcgamer/core/command/impl/staff/StaffModeCommand.java new file mode 100644 index 0000000..01f21e4 --- /dev/null +++ b/core/src/main/java/zone/themcgamer/core/command/impl/staff/StaffModeCommand.java @@ -0,0 +1,56 @@ +package zone.themcgamer.core.command.impl.staff; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import zone.themcgamer.core.account.AccountManager; +import zone.themcgamer.core.command.Command; +import zone.themcgamer.core.command.CommandProvider; +import zone.themcgamer.core.common.Style; +import zone.themcgamer.data.Rank; + +import java.util.Optional; + +public class StaffModeCommand { + + @Command(name = "staffmode", aliases = {"sm"}, description = "Open the staff gui", ranks = {Rank.HELPER}) + public void onCommand(CommandProvider command) { + CommandSender sender = command.getSender(); + String[] args = command.getArgs(); + +// Assuming that the sender is already a staff, due to the provided requirement that this command +// can be ran by HELPER and above +// If there are no args, the staff gui should be open to the sender +// only if the sender is a player +// if there is one argument, if it's a player, open it for that player (maybe force open) +// more than one argument should result in an error saying command mis-use + + switch (args.length) { + case 0: + if (sender instanceof ConsoleCommandSender) { + command.getSender().sendMessage(Style.error("StaffMode", + "Provide a player for the command to be used on!")); + return; + } else if (sender instanceof Player) { + //TODO open the staff gui for the sender + //command.getPlayer().openInventory(null); EXAMPLE + } + break; + case 1: + Optional.ofNullable(Bukkit.getPlayerExact(args[0])).ifPresentOrElse(player -> + AccountManager.fromCache(player.getUniqueId()).ifPresent(account -> { + if (account.hasRank(Rank.HELPER)) { + //TODO open the staff gui for the given player if found + player.sendMessage(Style.main("StaffMode", "Opened Staff gui by Console!")); + } + }), () -> command.getSender().sendMessage(Style.error("StaffMode", + "Provide a valid player for the command to be used on!"))); + break; + default: + command.getPlayer().sendMessage(Style.error("StaffMode", "Command mis-used!")); + break; + } + + } +} diff --git a/core/src/main/java/zone/themcgamer/core/deliveryMan/DeliveryManManager.java b/core/src/main/java/zone/themcgamer/core/deliveryMan/DeliveryManManager.java index d1fbade..b8e0c84 100644 --- a/core/src/main/java/zone/themcgamer/core/deliveryMan/DeliveryManManager.java +++ b/core/src/main/java/zone/themcgamer/core/deliveryMan/DeliveryManManager.java @@ -1,6 +1,7 @@ package zone.themcgamer.core.deliveryMan; import com.cryptomorin.xseries.XSound; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -11,6 +12,7 @@ import zone.themcgamer.core.account.AccountManager; import zone.themcgamer.core.account.MiniAccount; import zone.themcgamer.core.common.Style; import zone.themcgamer.core.deliveryMan.command.DeliveryManCommand; +import zone.themcgamer.core.deliveryMan.event.ClaimEvent; import zone.themcgamer.core.module.ModuleInfo; import zone.themcgamer.data.mysql.MySQLController; @@ -93,6 +95,7 @@ public class DeliveryManManager extends MiniAccount { return; repository.claim(optionalAccount.get().getId(), reward); deliveryManClient.claim(reward); + Bukkit.getPluginManager().callEvent(new ClaimEvent(player, reward)); player.playSound(player.getEyeLocation(), XSound.ENTITY_HORSE_ARMOR.parseSound(), 0.9f, 1f); player.sendMessage(Style.main(DELIVERY_MAN_NAME, "You claimed §b" + reward.getDisplayName() + "§7.")); } diff --git a/core/src/main/java/zone/themcgamer/core/deliveryMan/event/ClaimEvent.java b/core/src/main/java/zone/themcgamer/core/deliveryMan/event/ClaimEvent.java new file mode 100644 index 0000000..cceccf1 --- /dev/null +++ b/core/src/main/java/zone/themcgamer/core/deliveryMan/event/ClaimEvent.java @@ -0,0 +1,17 @@ +package zone.themcgamer.core.deliveryMan.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.entity.Player; +import zone.themcgamer.core.common.WrappedBukkitEvent; +import zone.themcgamer.core.deliveryMan.DeliveryManReward; + +/* + this event get called when player claims a reward. + */ +@AllArgsConstructor +@Getter +public class ClaimEvent extends WrappedBukkitEvent { + private final Player player; + private final DeliveryManReward deliveryManReward; +} diff --git a/core/src/main/java/zone/themcgamer/core/discord/DiscordLinkManager.java b/core/src/main/java/zone/themcgamer/core/discord/DiscordLinkManager.java new file mode 100644 index 0000000..c87f3da --- /dev/null +++ b/core/src/main/java/zone/themcgamer/core/discord/DiscordLinkManager.java @@ -0,0 +1,12 @@ +package zone.themcgamer.core.discord; + +import org.bukkit.plugin.java.JavaPlugin; +import zone.themcgamer.core.module.Module; +import zone.themcgamer.core.module.ModuleInfo; + +@ModuleInfo(name = "Discord Link Manager") +public class DiscordLinkManager extends Module { + public DiscordLinkManager(JavaPlugin plugin) { + super(plugin); + } +} \ No newline at end of file diff --git a/core/src/main/java/zone/themcgamer/core/discord/commands/LinkCommand.java b/core/src/main/java/zone/themcgamer/core/discord/commands/LinkCommand.java new file mode 100644 index 0000000..c9adbff --- /dev/null +++ b/core/src/main/java/zone/themcgamer/core/discord/commands/LinkCommand.java @@ -0,0 +1,21 @@ +package zone.themcgamer.core.discord.commands; + +import zone.themcgamer.core.command.Command; +import zone.themcgamer.core.command.CommandProvider; +import zone.themcgamer.data.jedis.cache.CacheRepository; +import zone.themcgamer.data.jedis.repository.RedisRepository; + +public class LinkCommand { + + @Command(name = "link", description = "Link your discord account", playersOnly = true) + public void onCommand(CommandProvider command) { + + //Check if user is linked + //Here + + String token = "321dsa12"; + + CacheRepository cacheRepository = RedisRepository.getRepository(CacheRepository.class).orElse(null); + } + +} diff --git a/core/src/main/java/zone/themcgamer/core/hologram/HologramManager.java b/core/src/main/java/zone/themcgamer/core/hologram/HologramManager.java new file mode 100644 index 0000000..0686633 --- /dev/null +++ b/core/src/main/java/zone/themcgamer/core/hologram/HologramManager.java @@ -0,0 +1,356 @@ +package zone.themcgamer.core.hologram; + +import com.cryptomorin.xseries.XMaterial; +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.gmail.filoghost.holographicdisplays.api.line.ItemLine; +import com.gmail.filoghost.holographicdisplays.api.line.TextLine; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.plugin.java.JavaPlugin; +import zone.themcgamer.core.common.Style; +import zone.themcgamer.core.module.Module; +import zone.themcgamer.core.module.ModuleInfo; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +@ModuleInfo(name="HologramManager") +public class HologramManager extends Module { + + /* + TODO Animation system for animated holograms + TODO Once player settings is being created, a system to toggle all holograms on or off for FPS + TODO Document everything + */ + + public HologramManager(JavaPlugin plugin) { + super(plugin); + } + + private final Map global = new HashMap<>(); // global holograms + private final Map> cache = new HashMap<>(); // personal + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + // Show public and private holograms to the player + } + + @EventHandler + private void onQuit(PlayerQuitEvent event) { + removePlayerHolograms(destroyPlayerHolograms(event.getPlayer().getUniqueId())); + } + + @EventHandler + private void onDisable(PluginDisableEvent event) { + destroyGlobalHolograms(); + removeGlobalHolograms(); + + destroyPlayerHolograms(); + removePLayerHolograms(); + } + + /** + * This method should add a single hologram with the given name, to the specified player. + * + * @param uuid the specified player uuid. + * @param name the given name. + * @param hologram the hologram. + */ + public Hologram addPlayerHologram(UUID uuid, String name, Hologram hologram) { + fetchPlayerHolograms(uuid).ifPresentOrElse(map -> map.put(name, hologram), () -> { + cache.put(uuid, new HashMap<>()); + cache.get(uuid).put(name,hologram); + }); + return hologram; + } + + /** + * This method should add a multiple holograms with the given name, to the specified player. + * + * @param player the specified player. + * @param hologramMap the hologram objects. + */ + public Map addPlayerHolograms(Player player, Map hologramMap) { + return cache.put(player.getUniqueId(), hologramMap); + } + + /** + * This method should add a global single hologram with the given name. + * + * @param name the given name. + * @param hologram the hologram. + */ + public Hologram addGlobalHologram(String name, Hologram hologram) { + global.put(name, hologram); + return hologram; + } + + /** + * This method should add a global single hologram with the given name. + * + * @param hologramMap the holograms objects. + */ + public Map addGlobalHolograms(Map hologramMap) { + global.putAll(hologramMap); + return hologramMap; + } + + /** + * This method should remove a single hologram with the given name. + * + * @param uuid the specified player uuid. + * @param index the given hologram name. + */ + public void removePlayerHologram(UUID uuid, String index) { + fetchPlayerHolograms(uuid).ifPresent(map -> map.remove(index)); + } + + /** + * This method should remove a global hologram with the given name. + * + * @param name the specified hologram name. + */ + public void removeGlobalHologram(String name) { + fetchGlobalHolograms().ifPresent(map -> map.remove(name)); + } + + /** + * This method should remove a multiple player holograms with the given uuid. + * + * @param uuid the specified player uuid. + */ + public void removePlayerHolograms(UUID uuid) { + fetchPlayerHolograms(uuid).ifPresent(map -> { + map.values().forEach(Hologram::delete); + map.clear(); + }); + } + + /** + * This method should remove all players from the cache. + */ + public void removePLayerHolograms() { + cache.clear(); + } + + /** + * This method should delete all global holograms from the cache & delete the holograms. + */ + public void removeGlobalHolograms() { + fetchGlobalHolograms().ifPresent(map -> { + map.values().forEach(Hologram::delete); + map.clear(); + }); + } + + /** + * This method should create a player hologram on the given location. + * + * @param location location of the hologram. + * @param player the specified player. + * @return returns the hologram object. + */ + public Hologram createPlayerHologram(Location location, Player player) { + final Hologram hologram = HologramsAPI.createHologram(getPlugin(), location); + hologram.getVisibilityManager().setVisibleByDefault(false); + hologram.getVisibilityManager().showTo(player); + return hologram; + } + + /** + * This method should create a global hologram on the given location. + * + * @param location location of the hologram. + * @return returns the hologram object. + */ + public Hologram createGlobalHologram(String name, Location location) { + final Hologram hologram = HologramsAPI.createHologram(getPlugin(), location); + hologram.getVisibilityManager().setVisibleByDefault(true); + return hologram; + } + + /** + * This method destroys the hologram and deletes the hologram. + * + * @param uuid the specified player uuid. + * @param name the name of the hologram. + * @return returns the name of the hologram. + */ + public String destroyPlayerHologram(UUID uuid, String name) { + fetchPlayerHolograms(uuid).filter(map -> map.containsKey(name)) + .ifPresent(map -> map.get(name).delete()); + return name; + } + + /** + * This method destroys the player hologram you specified. + * + * @param uuid the specified player uuid. + * @return returns the player uuid. + */ + public UUID destroyPlayerHolograms(UUID uuid) { + fetchPlayerHolograms(uuid).ifPresent(map -> map.values().forEach(Hologram::delete)); + return uuid; + } + + /** + * This method destroys all player holograms in the server. + */ + public void destroyPlayerHolograms() { + cache.values().forEach(map -> map.values().forEach(Hologram::delete)); + } + + /** + * This method destroys the specified global hologram in the server. + * + * @param name the specified hologram name. + * @return returns the name of the hologram. + */ + public String destroyGlobalHologram(String name) { + fetchGlobalHolograms().filter(map -> map.containsKey(name)) + .ifPresent(map -> map.get(name).delete()); + return name; + } + + /** + * This method destroys all global holograms in the server. + */ + public void destroyGlobalHolograms() { + global.values().forEach(Hologram::delete); + } + + /** + * This method allows you to set textLines in a hologram, this is a method that recude client lag. + * + * @param uuid the specified player uuid. + * @param index the name of the hologram. + * @param line the line number. + * @param text the text you want to set to. + */ + public void setTextPlayerHologram(UUID uuid, String index, int line, String text) { + fetchPlayerHologram(uuid, index).ifPresent(hologram -> { + while (hologram.size() <= line + 1) + hologram.insertTextLine(line, ""); + ((TextLine) hologram.getLine(line)).setText(Style.color(text)); + }); + } + + /** + * This method allows you to remove a line from a player hologram + * + * @param uuid the specified player uuid. + * @param index the name of the hologram. + * @param line the line number. + */ + public void removeTextPlayerHologram(UUID uuid, String index, int line) { + fetchPlayerHologram(uuid, index).ifPresent(hologram -> { + if (hologram.size() >= line + 1) + hologram.removeLine(line); + }); + } + + /** + * This method allows you to set textLines in a global hologram, this is a method that recude client lag. + * + * @param index the name of the hologram. + * @param line the line number. + * @param text the text you want to set to. + */ + public void setTextGlobalHologram(String index, int line, String text) { + fetchGlobalHologram(index).ifPresent(hologram -> { + while (hologram.size() <= line) + hologram.insertTextLine(line, ""); + ((TextLine) hologram.getLine(line)).setText(Style.color(text)); + }); + } + + /** + * This method allows you to set textLines in a global hologram, this is a method that recude client lag. + * + * @param index the name of the hologram. + * @param line the line number. + * @param item the item you want to set to. + */ + public void setItemGlobalHologram(String index, int line, XMaterial item) { + fetchGlobalHologram(index).ifPresent(hologram -> { + while (hologram.size() <= line) { + hologram.insertItemLine(line, item.parseItem()); + return; + } + ((ItemLine) hologram.getLine(line)).setItemStack(item.parseItem()); + }); + } + + /** + * This method allows you to remove a line from a global hologram + * + * @param index the name of the hologram. + * @param line the line number. + */ + public void removeTextGlobalHologram(String index, int line) { + fetchGlobalHologram(index).ifPresent(hologram -> { + if (hologram.size() >= line + 1) + hologram.removeLine(line); + }); + } + + /** + * This method allows you to hide a player hologram in the server. + * + * @param player the specified player. + * @param index the specified hologram name. + * @param visible if you want it to be visible or not. + */ + public void setPlayerHologramVisible(Player player, String index, boolean visible) { + fetchPlayerHologram(player.getUniqueId(), index).ifPresent(hologram -> { + if (visible) + hologram.getVisibilityManager().showTo(player); + else + hologram.getVisibilityManager().hideTo(player); + }); + } + + /** + * This method allows you to hide a global hologram in the server. + * + * @param index the specified hologram name. + * @param visible if you want it to be visible or not. + */ + public void setGlobalHologramVisible(Player player, String index, boolean visible) { + fetchGlobalHologram( index).ifPresent(hologram -> { + if (visible) + hologram.getVisibilityManager().showTo(player); + else + hologram.getVisibilityManager().hideTo(player); + }); + } + + public Optional> fetchPlayerHolograms(UUID uuid) { + return Optional.ofNullable(cache.get(uuid)); + } + + public Optional fetchPlayerHologram(UUID uuid, String index) { + final Map map = cache.get(uuid); + if (map != null){ + return Optional.ofNullable(map.get(index)); + } + else + return Optional.empty(); + } + + public Optional> fetchGlobalHolograms() { + return Optional.of(global); + } + + public Optional fetchGlobalHologram(String name) { + return Optional.ofNullable(global.get(name)); + } +} diff --git a/core/src/main/java/zone/themcgamer/core/nametag/NametagHandler.java b/core/src/main/java/zone/themcgamer/core/nametag/NametagHandler.java index 304398b..0043a86 100644 --- a/core/src/main/java/zone/themcgamer/core/nametag/NametagHandler.java +++ b/core/src/main/java/zone/themcgamer/core/nametag/NametagHandler.java @@ -8,6 +8,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; import zone.themcgamer.core.common.ServerUtils; import zone.themcgamer.core.common.ServerVersion; import zone.themcgamer.core.common.Style; diff --git a/core/src/main/java/zone/themcgamer/core/npc/NpcManager.java b/core/src/main/java/zone/themcgamer/core/npc/NpcManager.java new file mode 100644 index 0000000..35cb85b --- /dev/null +++ b/core/src/main/java/zone/themcgamer/core/npc/NpcManager.java @@ -0,0 +1,65 @@ +package zone.themcgamer.core.npc; + +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.npc.NPC; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.plugin.java.JavaPlugin; +import zone.themcgamer.core.module.Module; +import zone.themcgamer.core.module.ModuleInfo; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@ModuleInfo(name="Npc manager") +public class NpcManager extends Module { + + private static final Map cache = new HashMap<>(); + + public void onDisable() { + cache.forEach((name, npc) -> { + despawnNpc(npc); + destroyNpc(npc); + }); + cache.clear(); + } + + public NpcManager(JavaPlugin plugin) { + super(plugin); + } + + public void addNpc(String name, NPC npc) { + cache.put(name, npc); + } + + public NPC removeNpc(String name) { + return cache.remove(name); + } + + public static Optional getNpc(String name) { + return Optional.ofNullable(cache.get(name)); + } + + public boolean hasNpc(NPC npc) { + return cache.containsValue(npc); + } + + public NPC createNpc(String displayName, EntityType type, Location location) { + final NPC npc = CitizensAPI.getNPCRegistry().createNPC(type, displayName); + Bukkit.getScheduler().runTask(getPlugin(), () -> npc.spawn(location)); + return npc; + } + + public NPC despawnNpc(NPC npc) { + npc.despawn(); // So that the npc can be spawned once again in the future + return npc; + } + + public NPC destroyNpc(NPC npc) { + npc.destroy(); + return npc; + } + +} diff --git a/core/src/main/java/zone/themcgamer/core/plugin/MGZPlugin.java b/core/src/main/java/zone/themcgamer/core/plugin/MGZPlugin.java index 9a79cf0..c8ed2bc 100644 --- a/core/src/main/java/zone/themcgamer/core/plugin/MGZPlugin.java +++ b/core/src/main/java/zone/themcgamer/core/plugin/MGZPlugin.java @@ -14,8 +14,10 @@ import zone.themcgamer.core.common.ServerUtils; import zone.themcgamer.core.common.menu.MenuManager; import zone.themcgamer.core.common.scheduler.Scheduler; import zone.themcgamer.core.cooldown.CooldownHandler; +import zone.themcgamer.core.hologram.HologramManager; import zone.themcgamer.core.module.Module; import zone.themcgamer.core.nametag.NametagManager; +import zone.themcgamer.core.npc.NpcManager; import zone.themcgamer.core.plugin.command.BuildDataCommand; import zone.themcgamer.core.plugin.command.PluginsCommand; import zone.themcgamer.core.server.ServerManager; @@ -55,6 +57,8 @@ public abstract class MGZPlugin extends JavaPlugin { protected AccountManager accountManager; protected BadSportSystem badSportSystem; protected NametagManager nametagManager; + protected HologramManager hologramManager; + protected NpcManager npcManager; @SneakyThrows @Override @@ -105,7 +109,7 @@ public abstract class MGZPlugin extends JavaPlugin { name, null, serverGroupRepository.lookup(groupName).orElse(null), - "168.119.4.237", + "88.198.23.221", getServer().getPort(), 0, 0, @@ -183,6 +187,11 @@ public abstract class MGZPlugin extends JavaPlugin { new AnnounceManager(this); + if (getServer().getPluginManager().isPluginEnabled("HolographicDisplays")) + hologramManager = new HologramManager(this); + if (getServer().getPluginManager().isPluginEnabled("Citizens")) + npcManager = new NpcManager(this); + // Running the @Startup methods for the plugin getLogger().info("Running @Startup methods..."); List methods = Arrays.stream(getClass().getMethods()) diff --git a/core/src/main/java/zone/themcgamer/core/update/ServerUpdater.java b/core/src/main/java/zone/themcgamer/core/update/ServerUpdater.java index c3b2628..08b3316 100644 --- a/core/src/main/java/zone/themcgamer/core/update/ServerUpdater.java +++ b/core/src/main/java/zone/themcgamer/core/update/ServerUpdater.java @@ -38,7 +38,7 @@ public class ServerUpdater extends Module { this.traveler = traveler; // Creating the jars directory - File jarsDirectory = new File(File.separator + "home" + File.separator + "minecraft" + File.separator + "upload" + File.separator + "jars"); + File jarsDirectory = new File(File.separator + "home" + File.separator + "minecraft" + File.separator + "ftp" + File.separator + "upload" + File.separator + "upload" + File.separator + "jars"); if (!jarsDirectory.exists()) jarsDirectory.mkdirs(); diff --git a/discordbot/src/main/java/zone/themcgamer/discordbot/MGZBot.java b/discordbot/src/main/java/zone/themcgamer/discordbot/MGZBot.java index c227d06..7da0a6c 100644 --- a/discordbot/src/main/java/zone/themcgamer/discordbot/MGZBot.java +++ b/discordbot/src/main/java/zone/themcgamer/discordbot/MGZBot.java @@ -7,9 +7,12 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.OnlineStatus; import net.dv8tion.jda.api.entities.Activity; -import net.dv8tion.jda.api.entities.GuildChannel; -import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.requests.GatewayIntent; +import zone.themcgamer.data.jedis.JedisController; +import zone.themcgamer.data.jedis.cache.CacheRepository; +import zone.themcgamer.data.jedis.cache.impl.PlayerStatusCache; +import zone.themcgamer.data.jedis.repository.RedisRepository; +import zone.themcgamer.data.jedis.repository.impl.APIKeyRepository; import zone.themcgamer.discordbot.command.impl.*; import zone.themcgamer.discordbot.events.GuildsListener; import zone.themcgamer.discordbot.events.MainGuildListener; @@ -29,6 +32,9 @@ public class MGZBot { instance = this; long time = System.currentTimeMillis(); + // Initializing Redis + new JedisController().start(); + CommandClientBuilder commandClientBuilder = new CommandClientBuilder(); commandClientBuilder.setPrefix(BotConstants.PREFIX); commandClientBuilder.setActivity(Activity.playing("McGamerZone")); @@ -46,6 +52,8 @@ public class MGZBot { commandClientBuilder.addCommand(new AddReactionToMessageCommand()); commandClientBuilder.addCommand(new MemberCountCommand()); commandClientBuilder.addCommand(new PingCommand()); + commandClientBuilder.addCommand(new StopCommand()); + commandClientBuilder.addCommand(new OnlineCommand()); try { jda = JDABuilder.createDefault(BotConstants.TOKEN) diff --git a/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/CommandsCommand.java b/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/CommandsCommand.java index 446e6ad..5b260c8 100644 --- a/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/CommandsCommand.java +++ b/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/CommandsCommand.java @@ -1,21 +1,11 @@ package zone.themcgamer.discordbot.command.impl; -import com.jagrosh.jdautilities.command.Command; -import com.jagrosh.jdautilities.command.CommandClientBuilder; import com.jagrosh.jdautilities.command.CommandEvent; import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.TextChannel; -import zone.themcgamer.core.command.CommandManager; -import zone.themcgamer.discordbot.BotConstants; -import zone.themcgamer.discordbot.MGZBot; import zone.themcgamer.discordbot.command.BaseCommand; -import zone.themcgamer.discordbot.guild.Guild; import zone.themcgamer.discordbot.utilities.EmbedUtils; -import zone.themcgamer.discordbot.utilities.MessageUtils; -import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; /** * @author Nicholas diff --git a/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/OnlineCommand.java b/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/OnlineCommand.java new file mode 100644 index 0000000..5dcdc91 --- /dev/null +++ b/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/OnlineCommand.java @@ -0,0 +1,38 @@ +package zone.themcgamer.discordbot.command.impl; + +import com.jagrosh.jdautilities.command.CommandEvent; +import zone.themcgamer.data.jedis.cache.CacheRepository; +import zone.themcgamer.data.jedis.cache.impl.PlayerStatusCache; +import zone.themcgamer.data.jedis.repository.RedisRepository; +import zone.themcgamer.discordbot.MGZBot; +import zone.themcgamer.discordbot.command.BaseCommand; +import zone.themcgamer.discordbot.guild.Guild; +import zone.themcgamer.discordbot.utilities.EmbedUtils; + +import java.util.Arrays; +import java.util.List; + +public class OnlineCommand extends BaseCommand { + + public OnlineCommand() { + name = "online"; + aliases = new String[]{"players"}; + help = "Get the amount of online players in the network"; + cooldown = 30; + guildOnly = true; + guilds = Arrays.asList(Guild.MAIN, Guild.TEAM, Guild.TEST); + } + + @Override + protected void execute(CommandEvent event, List args) { + CacheRepository cacheRepository = RedisRepository.getRepository(CacheRepository.class).orElse(null); + + if (cacheRepository == null) { + event.reply(EmbedUtils.errorEmbed().setDescription("This command is unavailble right now!").build()); + return; + } + + int online = Math.toIntExact(cacheRepository.getCached().stream().filter(cacheItem -> cacheItem instanceof PlayerStatusCache).count()); + event.reply(EmbedUtils.defaultEmbed().setDescription("There are currently " + online + " players online!").build()); + } +} diff --git a/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/PingCommand.java b/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/PingCommand.java index 7a108e6..75db50e 100644 --- a/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/PingCommand.java +++ b/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/PingCommand.java @@ -1,27 +1,17 @@ package zone.themcgamer.discordbot.command.impl; import com.jagrosh.jdautilities.command.CommandEvent; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import zone.themcgamer.discordbot.command.BaseCommand; import zone.themcgamer.discordbot.guild.Guild; import zone.themcgamer.discordbot.utilities.EmbedUtils; -import zone.themcgamer.discordbot.utilities.MessageUtils; import java.awt.*; +import java.time.temporal.ChronoUnit; import java.util.Arrays; -import java.util.Date; import java.util.List; public class PingCommand extends BaseCommand { - private static long inputTime; - - public static void setInputTime(long inputTimeLong) { - inputTime = inputTimeLong; - } - private Color getColorByPing(long ping) { if (ping < 100) return Color.cyan; @@ -44,11 +34,11 @@ public class PingCommand extends BaseCommand { @Override protected void execute(CommandEvent event, List args) { - long processing = new Date().getTime() - inputTime; - long ping = event.getJDA().getGatewayPing(); - event.getTextChannel().sendMessage(EmbedUtils.defaultEmbed().setColor(getColorByPing(ping)).setDescription( - String.format(":ping_pong: **Pong!**\n\nThe bot took `%s` milliseconds to response.\nIt took `%s` milliseconds to parse the command and the ping is `%s` milliseconds.", - processing + ping, processing, ping) - ).build()).queue(); + event.reply(":ping_pong: Pong! ...", m -> { + long ping = event.getMessage().getTimeCreated().until(m.getTimeCreated(), ChronoUnit.MILLIS); + m.editMessage(EmbedUtils.defaultEmbed().setColor(getColorByPing(ping)) + .setDescription("Ping: " + ping + "ms | Websocket: " + event.getJDA().getGatewayPing() + "ms").build()) + .queue(); + }); } } diff --git a/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/StopCommand.java b/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/StopCommand.java new file mode 100644 index 0000000..34f05f7 --- /dev/null +++ b/discordbot/src/main/java/zone/themcgamer/discordbot/command/impl/StopCommand.java @@ -0,0 +1,28 @@ +package zone.themcgamer.discordbot.command.impl; + +import com.jagrosh.jdautilities.command.CommandEvent; +import net.dv8tion.jda.api.Permission; +import zone.themcgamer.discordbot.MGZBot; +import zone.themcgamer.discordbot.command.BaseCommand; +import zone.themcgamer.discordbot.guild.Guild; + +import java.util.Arrays; +import java.util.List; + +public class StopCommand extends BaseCommand { + + public StopCommand() { + name = "stop"; + aliases = new String[]{"shutdown"}; + help = "Stop the bot"; + userPermissions = new Permission[] { Permission.ADMINISTRATOR }; + guildOnly = true; + guilds = Arrays.asList(Guild.MAIN, Guild.TEAM, Guild.TEST); + } + + @Override + protected void execute(CommandEvent event, List args) { + event.reply("Shutting down..."); + MGZBot.getInstance().getJda().shutdown(); + } +} diff --git a/hub/build.gradle.kts b/hub/build.gradle.kts index 9ccdef2..9dbdada 100644 --- a/hub/build.gradle.kts +++ b/hub/build.gradle.kts @@ -1,7 +1,17 @@ +repositories { + mavenCentral() + maven { + url = uri("http://repo.citizensnpcs.co/") + url = uri("https://repo.codemc.io/repository/maven-public/") + } +} + dependencies { implementation(project(":core")) compileOnly("com.destroystokyo:paperspigot:1.12.2") implementation("com.github.cryptomorin:XSeries:7.8.0") + compileOnly("net.citizensnpcs:citizensapi:2.0.28-SNAPSHOT") + compileOnly("com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.0") } tasks { diff --git a/hub/src/main/java/zone/themcgamer/hub/Hub.java b/hub/src/main/java/zone/themcgamer/hub/Hub.java index 2f42593..4b9a6d4 100644 --- a/hub/src/main/java/zone/themcgamer/hub/Hub.java +++ b/hub/src/main/java/zone/themcgamer/hub/Hub.java @@ -16,8 +16,11 @@ import zone.themcgamer.core.plugin.MGZPlugin; import zone.themcgamer.core.plugin.Startup; import zone.themcgamer.core.world.MGZWorld; import zone.themcgamer.hub.command.SpawnCommand; +import zone.themcgamer.hub.holograms.HaroldHologram; +import zone.themcgamer.hub.holograms.WelcomeHologram; import zone.themcgamer.hub.listener.PlayerListener; import zone.themcgamer.hub.listener.WorldListener; +import zone.themcgamer.hub.npc.HaroldNPC; import zone.themcgamer.hub.scoreboard.HubScoreboard; /** @@ -57,6 +60,10 @@ public class Hub extends MGZPlugin { AccountManager.addMiniAccount(new DeliveryManManager(this, mySQLController, true)); + new HaroldHologram(this); + new WelcomeHologram(this); + new HaroldNPC(this); + commandManager.registerCommand(new SpawnCommand(this)); } } \ No newline at end of file diff --git a/hub/src/main/java/zone/themcgamer/hub/holograms/HaroldHologram.java b/hub/src/main/java/zone/themcgamer/hub/holograms/HaroldHologram.java new file mode 100644 index 0000000..4efe9d8 --- /dev/null +++ b/hub/src/main/java/zone/themcgamer/hub/holograms/HaroldHologram.java @@ -0,0 +1,70 @@ +package zone.themcgamer.hub.holograms; + +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.java.JavaPlugin; +import zone.themcgamer.core.common.Style; +import zone.themcgamer.core.deliveryMan.DeliveryManManager; +import zone.themcgamer.core.deliveryMan.event.ClaimEvent; +import zone.themcgamer.core.hologram.HologramManager; +import zone.themcgamer.core.module.Module; +import zone.themcgamer.core.module.ModuleInfo; +import zone.themcgamer.core.world.MGZWorld; +import zone.themcgamer.hub.Hub; + +import java.util.UUID; + +import static zone.themcgamer.core.deliveryMan.DeliveryManManager.DELIVERY_MAN_NAME; + +@ModuleInfo(name = "HologramHandler Manager") +public class HaroldHologram extends Module{ + + @Getter private final DeliveryManManager deliveryManManager; + @Getter private final HologramManager hologramManager; + + private String HAROLD_TITLE = "&a" + DELIVERY_MAN_NAME + "'s &fdelivery &cRewards"; + + public HaroldHologram(JavaPlugin plugin) { + super(plugin); + deliveryManManager = Module.getModule(DeliveryManManager.class); + hologramManager = Module.getModule(HologramManager.class); + } + + @EventHandler + private void onJoin(PlayerJoinEvent event) { + final Player player = event.getPlayer(); + final Location location = MGZWorld.get(Bukkit.getWorlds().get(0)).getDataPoint("HAROLD"); + + if (location != null) { + location.setYaw(Hub.INSTANCE.getSpawn().getYaw()); + hologramManager.addPlayerHologram(player.getUniqueId(), DELIVERY_MAN_NAME, hologramManager.createPlayerHologram(location.clone().add(0,3.2,0), player)) + .insertTextLine(0, Style.color(HAROLD_TITLE)); + updateHaroldLines(event.getPlayer()); + } + + } + + @EventHandler + private void onDeliveryManClaim(ClaimEvent event) { + updateHaroldLines(event.getPlayer()); + } + + private void updateHaroldLines(Player player){ + final UUID uuid = player.getUniqueId(); + hologramManager.fetchPlayerHologram(uuid, DELIVERY_MAN_NAME).ifPresent(hologram -> { + deliveryManManager.lookup(uuid).ifPresent(client -> { + if (client.getUnclaimedRewards(player) > 0) { + hologramManager.setTextPlayerHologram(uuid, DELIVERY_MAN_NAME,1,"&7You have &b" + client.getUnclaimedRewards(player) + " &7unclaimed deliveries!"); + hologramManager.setTextPlayerHologram(uuid, DELIVERY_MAN_NAME,2, ""); + } else { + hologramManager.setTextPlayerHologram(uuid,DELIVERY_MAN_NAME,1,"&7There are no deliveries available!"); + hologramManager.setTextPlayerHologram(uuid,DELIVERY_MAN_NAME,2,"&7Come back later..."); + } + }); + }); + } +} diff --git a/hub/src/main/java/zone/themcgamer/hub/holograms/WelcomeHologram.java b/hub/src/main/java/zone/themcgamer/hub/holograms/WelcomeHologram.java new file mode 100644 index 0000000..f6088e7 --- /dev/null +++ b/hub/src/main/java/zone/themcgamer/hub/holograms/WelcomeHologram.java @@ -0,0 +1,78 @@ +package zone.themcgamer.hub.holograms; + +import com.cryptomorin.xseries.XMaterial; +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; +import zone.themcgamer.core.common.Style; +import zone.themcgamer.core.game.MGZGame; +import zone.themcgamer.core.hologram.HologramManager; +import zone.themcgamer.core.module.Module; +import zone.themcgamer.core.module.ModuleInfo; +import zone.themcgamer.core.world.MGZWorld; +import zone.themcgamer.data.jedis.cache.CacheRepository; +import zone.themcgamer.data.jedis.cache.impl.PlayerStatusCache; +import zone.themcgamer.data.jedis.repository.RedisRepository; + +import java.util.HashMap; +import java.util.Optional; + +@ModuleInfo(name = "Welcome Hologram") +public class WelcomeHologram extends Module { + + private static final HashMap reactionRoles = new HashMap<>(); + + private int randomGameIndex; + + @Getter + private final HologramManager hologramManager; + + public WelcomeHologram(JavaPlugin plugin) { + super(plugin); + hologramManager = Module.getModule(HologramManager.class); + setup(); + run(); + } + + private void setup() { + final Location location = MGZWorld.get(Bukkit.getWorlds().get(0)).getDataPoint("LOOK_AT"); + if (location != null) { + new BukkitRunnable() { + @Override + public void run() { + Hologram hologram = hologramManager.addGlobalHologram("WELCOME", hologramManager.createGlobalHologram("WELCOME", location)); + hologram.insertItemLine(0, XMaterial.CRAFTING_TABLE.parseItem()); + hologram.insertTextLine(1, Style.color("&fWelcome to &2&lMc&6&lGamer&c&lZone&f!")); + hologram.insertTextLine(2, Style.color("&bUse the compass to warp to a &agame&b!")); + hologram.insertTextLine(3, Style.color("")); + hologram.insertTextLine(4, Style.color("&a/help &ffor help!")); + hologram.insertTextLine(5, Style.color("&a/store &ffor donating!")); + hologram.insertTextLine(6, Style.color("&a/discord &fjoin our discord!")); + hologram.insertTextLine(7, Style.color("")); + hologram.insertTextLine(8, Style.color("&ePlay with &b0 &eother gamers!")); + } + }.runTask(getPlugin()); + } + } + + private void run(){ + Optional cacheRepository = RedisRepository.getRepository(CacheRepository.class); + new BukkitRunnable() { + @Override + public void run() { + int online = 0; + if (cacheRepository.isPresent()) + online += cacheRepository.get().getCached().stream().filter(cacheItem -> cacheItem instanceof PlayerStatusCache).count(); + hologramManager.setTextGlobalHologram("WELCOME", 8, "&ePlay with &b" + online + " &eother gamers!"); + + if (++randomGameIndex >= MGZGame.values().length) + randomGameIndex = 0; + MGZGame game = MGZGame.values()[randomGameIndex]; + hologramManager.setItemGlobalHologram("WELCOME", 0, game.getIcon()); + } + }.runTaskTimer(getPlugin(), 2*20, 2*20); + } +} diff --git a/hub/src/main/java/zone/themcgamer/hub/listener/PlayerListener.java b/hub/src/main/java/zone/themcgamer/hub/listener/PlayerListener.java index 9823fc7..122d04e 100644 --- a/hub/src/main/java/zone/themcgamer/hub/listener/PlayerListener.java +++ b/hub/src/main/java/zone/themcgamer/hub/listener/PlayerListener.java @@ -26,6 +26,8 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.*; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; import zone.themcgamer.core.account.Account; import zone.themcgamer.core.account.AccountManager; import zone.themcgamer.core.account.menu.ProfileMenu; @@ -87,6 +89,7 @@ public class PlayerListener implements Listener { player.getInventory().setItem(7, SETTINGS); player.getInventory().setItem(8, PROFILE.setSkullOwner(player.getName()).toItemStack()); player.getInventory().setHeldItemSlot(0); + player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 900000, 2)); Optional optionalAccount = AccountManager.fromCache(player.getUniqueId()); if (optionalAccount.isEmpty()) diff --git a/hub/src/main/java/zone/themcgamer/hub/npc/HaroldNPC.java b/hub/src/main/java/zone/themcgamer/hub/npc/HaroldNPC.java new file mode 100644 index 0000000..98f97b1 --- /dev/null +++ b/hub/src/main/java/zone/themcgamer/hub/npc/HaroldNPC.java @@ -0,0 +1,70 @@ +package zone.themcgamer.hub.npc; + +import lombok.Getter; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.citizensnpcs.api.npc.NPC; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.plugin.java.JavaPlugin; +import zone.themcgamer.core.deliveryMan.DeliveryManManager; +import zone.themcgamer.core.deliveryMan.DeliveryManMenu; +import zone.themcgamer.core.module.Module; +import zone.themcgamer.core.module.ModuleInfo; +import zone.themcgamer.core.npc.NpcManager; +import zone.themcgamer.core.world.MGZWorld; +import zone.themcgamer.hub.Hub; + +@ModuleInfo(name = "NPCHandler") +public class HaroldNPC extends Module { + + @Getter private final NpcManager npcManager; + @Getter private final DeliveryManManager deliveryManManager; + + public HaroldNPC(JavaPlugin plugin) { + super(plugin); + deliveryManManager = Module.getModule(DeliveryManManager.class); + npcManager = Module.getModule(NpcManager.class); + + if (plugin.getServer().getPluginManager().isPluginEnabled("Citizens")) + loadHarold(); + } + + @EventHandler(priority = EventPriority.LOWEST) + private void onNPCLeftClick(NPCLeftClickEvent event) { + NpcManager.getNpc("HAROLD").ifPresent(npc -> { + if (event.getNPC() == npc && deliveryManManager != null) + new DeliveryManMenu(event.getClicker(), deliveryManManager).open(); + }); + } + + @EventHandler(priority = EventPriority.LOWEST) + private void onNPCRightClick(NPCRightClickEvent event) { + NpcManager.getNpc("HAROLD").ifPresent(npc -> { + if (event.getNPC() == npc && deliveryManManager != null) + new DeliveryManMenu(event.getClicker(), deliveryManManager).open(); + }); + } + + private void loadHarold(){ + final Location location = MGZWorld.get(Bukkit.getWorlds().get(0)).getDataPoint("HAROLD"); + if (location != null) { + location.setYaw(Hub.INSTANCE.getSpawn().getYaw()); + npcManager.addNpc("HAROLD", npcManager.createNpc("&7", EntityType.VILLAGER, location)); + //Have to be 20 ticks delay, otherwise you get a nullpointer due the npc's is'n spawned in yet. + Bukkit.getScheduler().runTaskLater(getPlugin(), this::setDefaults, 20); + } + } + + private void setDefaults() { + NpcManager.getNpc("HAROLD").ifPresent(npc -> { + npc.setProtected(true); + npc.getEntity().setSilent(true); + npc.getEntity().setCustomNameVisible(false); + }); + return; + } +} diff --git a/hub/src/main/resources/plugin.yml b/hub/src/main/resources/plugin.yml index 5e0a4a4..3467822 100644 --- a/hub/src/main/resources/plugin.yml +++ b/hub/src/main/resources/plugin.yml @@ -2,4 +2,7 @@ name: Hub version: 1.0-SNAPSHOT api-version: 1.13 main: zone.themcgamer.hub.Hub -author: MGZ Development Team \ No newline at end of file +author: MGZ Development Team +softdepend: + - Citizens + - HolographicDisplays \ No newline at end of file diff --git a/proxy/src/main/java/zone/themcgamer/proxy/hub/HubBalancer.java b/proxy/src/main/java/zone/themcgamer/proxy/hub/HubBalancer.java index c335fee..076ae25 100644 --- a/proxy/src/main/java/zone/themcgamer/proxy/hub/HubBalancer.java +++ b/proxy/src/main/java/zone/themcgamer/proxy/hub/HubBalancer.java @@ -59,6 +59,9 @@ public class HubBalancer implements Runnable, Listener { if (!serverStateChangeCommand.getNewState().isShuttingDownState()) return; MinecraftServer server = serverStateChangeCommand.getServer(); + System.out.println(server.getAddress()); + System.out.println(server.getHost()); + System.out.println(server.getPort()); removeServer(server.getId()); } }); @@ -78,6 +81,8 @@ public class HubBalancer implements Runnable, Listener { // If the player is joining the proxy, and the target server is the name of the server group, we wanna // find a hub for them to connect to + + System.out.println(event.getReason()); if (reason == ServerConnectEvent.Reason.JOIN_PROXY && event.getTarget().getName().equals(group.getName())) { ServerInfo serverInfo = sendToHub(player); if (serverInfo == null) { @@ -184,6 +189,8 @@ public class HubBalancer implements Runnable, Listener { return null; } System.out.println("Sending " + player.getName() + " to server \"" + target.getName() + "\""); + System.out.println(target.getSocketAddress()); + System.out.println(target.getAddress()); return target; } System.err.println("Cannot find a server to send " + player.getName() + " to!"); @@ -193,7 +200,7 @@ public class HubBalancer implements Runnable, Listener { private void registerServer(MinecraftServer minecraftServer) { ServerInfo serverInfo = proxy.getProxy().constructServerInfo(minecraftServer.getId(), - new InetSocketAddress(group.getPrivateAddress(), (int) minecraftServer.getPort()), "A MGZ Server", false); + new InetSocketAddress(minecraftServer.getAddress(), (int) minecraftServer.getPort()), "A MGZ Server", false); proxy.getProxy().getServers().put(minecraftServer.getId(), serverInfo); if (group.getServers().contains(minecraftServer)) hubs.put(minecraftServer.getId(), serverInfo); diff --git a/servercontroller/src/main/java/zone/themcgamer/controller/ServerController.java b/servercontroller/src/main/java/zone/themcgamer/controller/ServerController.java index f9f373a..f00e918 100644 --- a/servercontroller/src/main/java/zone/themcgamer/controller/ServerController.java +++ b/servercontroller/src/main/java/zone/themcgamer/controller/ServerController.java @@ -439,7 +439,7 @@ public class ServerController { ServerController.starting.add(server); minecraftServerRepository.post(server); - ProcessRunner processRunner = new ProcessRunner(new String[] { "/bin/sh", "/home/minecraft/createServer.sh", + ProcessRunner processRunner = new ProcessRunner(new String[] { "/bin/sh", "/home/minecraft/ftp/upload/createServer.sh", server.getGroup().getName(), server.getId(), group.getServerJar(), @@ -542,7 +542,7 @@ public class ServerController { String finalReason = reason; // Calling the stopServer.sh script - ProcessRunner processRunner = new ProcessRunner(new String[] { "/bin/sh", "/home/minecraft/stopServer.sh", + ProcessRunner processRunner = new ProcessRunner(new String[] { "/bin/sh", "/home/minecraft/ftp/upload/stopServer.sh", server.getGroup().getName(), server.getId() }); diff --git a/serverdata/build.gradle.kts b/serverdata/build.gradle.kts index 1ca8eb6..9b9f502 100644 --- a/serverdata/build.gradle.kts +++ b/serverdata/build.gradle.kts @@ -11,7 +11,7 @@ repositories { dependencies { api(project(":commons")) - implementation("redis.clients:jedis:3.4.1") + implementation("redis.clients:jedis:3.6.1") implementation("com.zaxxer:HikariCP:3.4.5") implementation("mysql:mysql-connector-java:8.0.23") testCompile("junit", "junit", "4.12") diff --git a/serverdata/src/main/java/zone/themcgamer/data/Rank.java b/serverdata/src/main/java/zone/themcgamer/data/Rank.java index 16349d3..5ad3fbd 100644 --- a/serverdata/src/main/java/zone/themcgamer/data/Rank.java +++ b/serverdata/src/main/java/zone/themcgamer/data/Rank.java @@ -16,38 +16,39 @@ public enum Rank { // was changed will have the default rank instead of the rank they originally had // Staff Ranks - OWNER("Owner", "§6", "§6§lOwner", RankCategory.STAFF), - MANAGER("Manager", "§e", "§e§lManager", RankCategory.STAFF), - DEVELOPER("Dev", "§9", "§9§lDev", RankCategory.STAFF), - JR_DEVELOPER("Jr.Dev", "§9", "§9§lJr.Dev", RankCategory.STAFF), - ADMIN("Admin", "§c", "§c§lAdmin", RankCategory.STAFF), - MODERATOR("Mod", "§2", "§2§lMod", RankCategory.STAFF), - HELPER("Helper", "§a", "§a§lHelper", RankCategory.STAFF), + OWNER("Owner", "Owners are the founders of the network. \nOwners manage different portions of the network, \nand they also ensure the best quality.", "§6", "§6§lOwner", RankCategory.STAFF), + MANAGER("Manager", "Managers work to make sure that everything \non the network including staff members and \nnetwork quality is going as it should.", "§e", "§e§lManager", RankCategory.STAFF), + DEVELOPER("Dev", "Developers are those who create things for \nthe network. Developers work together to ensure \nthe best quality for players of the network. \nWithout developers, this message wouldn't exist!", "§9", "§9§lDev", RankCategory.STAFF), + JR_DEVELOPER("Jr.Dev", "Junior Developers are developers who do not \nhave full access to the internals of the network, \nbut they are able to create things using \nthe network's API.", "§9", "§9§lJr.Dev", RankCategory.STAFF), + ADMIN("Admin", "Administrators are staff members that focus on \na specific portion of the network, and they \nall make sure everything is going as they should.", "§c", "§c§lAdmin", RankCategory.STAFF), + MODERATOR("Mod", "Moderators are staff members who were \npromoted from Helper, and they have more permissions \nthan they did as a Helper.", "§2", "§2§lMod", RankCategory.STAFF), + HELPER("Helper", "The Helper rank is the first staff moderation \nrank given to somebody when they join the \nstaff team. Think of them as trial moderators \nas they work their way up to Moderator.", "§a", "§a§lHelper", RankCategory.STAFF), // Other - SR_BUILDER("Sr.Builder", "§3", "§3§lSr.Builder", RankCategory.OTHER), - BUILDER("Builder", "§b", "§b§lBuilder", RankCategory.OTHER), - PARTNER("Partner", "§d", "§d§lPartner", RankCategory.OTHER), - YOUTUBER("YouTuber", "§c", "§c§lYouTuber", RankCategory.OTHER), + SR_BUILDER("Sr.Builder", "The Sr.Builder rank is given to those \nwho are considered head builders. They \nare more experienced builders, and they look over \nwhat the rest of the build team does.", "§3", "§3§lSr.Builder", RankCategory.OTHER), + BUILDER("Builder", "Builders are those who work with other \nBuilders to create amazing maps for you \nto play on. Without them, the world you're in \nprobably wouldn't exist.", "§b", "§b§lBuilder", RankCategory.OTHER), + PARTNER("Partner", "The Partner rank is given to those who \nare affiliated with those who partner \nwith McGamerZone.", "§d", "§d§lPartner", RankCategory.OTHER), + YOUTUBER("YouTuber", "YouTubers are content creators that record \nor stream content on McGamerZone that \ngets uploaded to YouTube. Say hi if \nyou see them around, you may be on YouTube!", "§c", "§c§lYouTuber", RankCategory.OTHER), // Donor Ranks - ULTIMATE("Ultimate", "§5", "§5§lUltimate", RankCategory.DONATOR), - EXPERT("Expert", "§b", "§b§lExpert", RankCategory.DONATOR), - HERO("Hero", "§e", "§e§lHero", RankCategory.DONATOR), - SKILLED("Skilled", "§6", "§6§lSkilled", RankCategory.DONATOR), - GAMER("Gamer", "§2", "§2§lGamer", RankCategory.DONATOR), + // TODO - Come up with creative descriptions for donor ranks. + ULTIMATE("Ultimate", "The fifth purchasable rank found at store.mcgamerzone.net", "§5", "§5§lUltimate", RankCategory.DONATOR), + EXPERT("Expert", "The fourth purchasable rank found at store.mcgamerzone.net", "§b", "§b§lExpert", RankCategory.DONATOR), + HERO("Hero", "The third purchasable rank found at store.mcgamerzone.net", "§e", "§e§lHero", RankCategory.DONATOR), + SKILLED("Skilled", "The second purchasable rank found at store.mcgamerzone.net", "§6", "§6§lSkilled", RankCategory.DONATOR), + GAMER("Gamer", "The first purchasable rank found at store.mcgamerzone.net", "§2", "§2§lGamer", RankCategory.DONATOR), - DEFAULT("None", "§7", "§7None", RankCategory.OTHER), + DEFAULT("None", "Default player rank", "§7", "§7None", RankCategory.OTHER), // Sub Ranks - BETA("Beta", "§5", null, "§5Beta", RankCategory.SUB); + BETA("Beta", "A beta tester for McGamerZone", "§5", null, "§5Beta", RankCategory.SUB); - private final String displayName, color, prefix; + private final String displayName, description, color, prefix; private String suffix; private RankCategory category; - Rank(String displayName, String color, String prefix, RankCategory category) { - this(displayName, color, prefix, null, category); + Rank(String displayName, String description, String color, String prefix, RankCategory category) { + this(displayName, description, color, prefix, null, category); } public String getNametag() { diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/JedisConstants.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/JedisConstants.java index e72f88c..5812b74 100644 --- a/serverdata/src/main/java/zone/themcgamer/data/jedis/JedisConstants.java +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/JedisConstants.java @@ -3,8 +3,10 @@ package zone.themcgamer.data.jedis; /** * @author Braydon */ + +// Maybe we should use env vars instead public class JedisConstants { public static final String HOST = "172.18.0.1"; - public static final String AUTH = "CWhsuGvpYPhZ321dsaDAwqjk231_mgz"; + public static final String AUTH = System.getenv("REDIS_PASSWORD"); public static final int SELECTED_DB = 0; } \ No newline at end of file diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/JedisController.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/JedisController.java index 08d7272..c5cf7ce 100644 --- a/serverdata/src/main/java/zone/themcgamer/data/jedis/JedisController.java +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/JedisController.java @@ -14,6 +14,8 @@ import zone.themcgamer.data.jedis.repository.impl.MinecraftServerRepository; import zone.themcgamer.data.jedis.repository.impl.NodeRepository; import zone.themcgamer.data.jedis.repository.impl.ServerGroupRepository; +import java.util.Map; + /** * @author Braydon * @implNote This class serves the purpose of connecting and initializing things that @@ -31,6 +33,7 @@ public class JedisController { * initialized without running into problems */ public JedisController start() { + pool = new JedisPool(JedisConstants.HOST); // Configuring redis and connecting to the server new JedisCommandHandler(); // Starting the command handler to handle commands over the network @@ -41,6 +44,9 @@ public class JedisController { new APIKeyRepository(this); minecraftServerRepository = new MinecraftServerRepository(this); + + // Adding a listener for the ServerStateChangeCommand that should remove the server from the cache if the + // Current server state is STOPPING JedisCommandHandler.getInstance().addListener(jedisCommand -> { if (jedisCommand instanceof ServerStateChangeCommand) { ServerStateChangeCommand serverStateChangeCommand = (ServerStateChangeCommand) jedisCommand; diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/command/impl/ClearChatCommand.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/command/impl/ClearChatCommand.java new file mode 100644 index 0000000..9e6d222 --- /dev/null +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/command/impl/ClearChatCommand.java @@ -0,0 +1,11 @@ +package zone.themcgamer.data.jedis.command.impl; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import zone.themcgamer.data.jedis.command.JedisCommand; + +@RequiredArgsConstructor @Getter +public class ClearChatCommand extends JedisCommand { + private final String serverId; + private final Integer lines; +} \ No newline at end of file diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/command/impl/discord/DiscordLinkConfirmCommand.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/command/impl/discord/DiscordLinkConfirmCommand.java new file mode 100644 index 0000000..93439e1 --- /dev/null +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/command/impl/discord/DiscordLinkConfirmCommand.java @@ -0,0 +1,13 @@ +package zone.themcgamer.data.jedis.command.impl.discord; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.UUID; + +@RequiredArgsConstructor +@Getter +public class DiscordLinkConfirmCommand { + private final UUID uuid; + private final Long discordId; +} diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/command/impl/discord/DiscordUnlinkCommand.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/command/impl/discord/DiscordUnlinkCommand.java new file mode 100644 index 0000000..dc6fa23 --- /dev/null +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/command/impl/discord/DiscordUnlinkCommand.java @@ -0,0 +1,10 @@ +package zone.themcgamer.data.jedis.command.impl.discord; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public class DiscordUnlinkCommand { + private final Long discordId; +} diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/data/APIKey.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/data/APIKey.java index 879b567..8b45c04 100644 --- a/serverdata/src/main/java/zone/themcgamer/data/jedis/data/APIKey.java +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/data/APIKey.java @@ -11,4 +11,5 @@ import zone.themcgamer.data.APIAccessLevel; public class APIKey { private final String key; private final APIAccessLevel accessLevel; -} \ No newline at end of file +} + diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/data/DiscordLink.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/data/DiscordLink.java new file mode 100644 index 0000000..17eebe8 --- /dev/null +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/data/DiscordLink.java @@ -0,0 +1,17 @@ +package zone.themcgamer.data.jedis.data; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.sql.Timestamp; +import java.util.UUID; + +/** + * @author Braydon + */ +@AllArgsConstructor @Getter +public class DiscordLink { + private final UUID uuid; + private final String token; + private final Timestamp timestamp; +} \ No newline at end of file diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/APIKeyRepository.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/APIKeyRepository.java index 785047a..0079d3e 100644 --- a/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/APIKeyRepository.java +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/APIKeyRepository.java @@ -6,6 +6,7 @@ import zone.themcgamer.data.jedis.JedisController; import zone.themcgamer.data.jedis.data.APIKey; import zone.themcgamer.data.jedis.repository.RedisRepository; + import java.util.*; import java.util.stream.Collectors; diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/AnnouncementSettingsRepository.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/AnnouncementSettingsRepository.java new file mode 100644 index 0000000..3a24aed --- /dev/null +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/AnnouncementSettingsRepository.java @@ -0,0 +1,8 @@ +package zone.themcgamer.data.jedis.repository.impl; + +import zone.themcgamer.data.jedis.repository.RedisRepository; + +public class AnnouncementSettingsRepository { + + +} diff --git a/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/DiscordLinkRepository.java b/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/DiscordLinkRepository.java new file mode 100644 index 0000000..9175530 --- /dev/null +++ b/serverdata/src/main/java/zone/themcgamer/data/jedis/repository/impl/DiscordLinkRepository.java @@ -0,0 +1,55 @@ +package zone.themcgamer.data.jedis.repository.impl; + +import zone.themcgamer.data.jedis.JedisController; +import zone.themcgamer.data.jedis.data.DiscordLink; +import zone.themcgamer.data.jedis.data.Node; +import zone.themcgamer.data.jedis.repository.RedisRepository; + +import java.util.*; + +/** + * @author Braydon + * @implNote This class serves the purpose of fetching all {@link Node}'s + * from Redis + */ +public class DiscordLinkRepository extends RedisRepository { + public DiscordLinkRepository(JedisController controller) { + super(controller, "discordLinking:*"); + } + + /*@Override + public Optional lookup(UUID uuid) { + return getCached().stream().filter(discordLink -> discordLink.getUuid().equals(uuid)).findFirst(); + }*/ + + @Override + public Optional lookup(String token) { + return getCached().stream().filter(discordLink -> discordLink.getToken().equals(token)).findFirst(); + } + + @Override + public String getKey(DiscordLink discordLink) { + return "discordLinking:" + discordLink.getUuid(); + } + + @Override + public Optional fromMap(Map map) { + return null; + } + + @Override + public long getExpiration(DiscordLink discordLink) { + return discordLink.getTimestamp().getTime(); + } + + @Override + public Map toMap(DiscordLink discordLink) { + Map data = new HashMap<>(); + data.put("uuid", discordLink.getUuid()); + data.put("token", discordLink.getToken()); + data.put("timeCreated", discordLink.getTimestamp()); + return data; + } + + +} diff --git a/serverdata/src/main/java/zone/themcgamer/data/mysql/MySQLConstants.java b/serverdata/src/main/java/zone/themcgamer/data/mysql/MySQLConstants.java index 11be520..f60c244 100644 --- a/serverdata/src/main/java/zone/themcgamer/data/mysql/MySQLConstants.java +++ b/serverdata/src/main/java/zone/themcgamer/data/mysql/MySQLConstants.java @@ -3,9 +3,11 @@ package zone.themcgamer.data.mysql; /** * @author Braydon */ -public class MySQLConstants { - public static final String HOST = "172.18.0.1"; - public static final String USERNAME = "mcgamerzone"; - public static final String AUTH = "n3oCqfGeCG7lUcOlqvUG2JfyKMtEZakG0eNIA_mGz"; +// Environment vars should be used here / in the future +public class MySQLConstants { + public static final String HOST = "localhost"; + + public static final String USERNAME = System.getenv("MYSQL_USERNAME"); + public static final String AUTH = System.getenv("MYSQL_PASSWORD"); } \ No newline at end of file diff --git a/serverdata/src/main/java/zone/themcgamer/data/mysql/MySQLController.java b/serverdata/src/main/java/zone/themcgamer/data/mysql/MySQLController.java index eb5016d..11e72fd 100644 --- a/serverdata/src/main/java/zone/themcgamer/data/mysql/MySQLController.java +++ b/serverdata/src/main/java/zone/themcgamer/data/mysql/MySQLController.java @@ -16,22 +16,32 @@ import java.sql.SQLException; */ @Getter public class MySQLController { + private final HikariDataSource dataSource; public MySQLController(boolean production) { - // Connecting to the MySQL server - HikariConfig config = new HikariConfig(); - config.setJdbcUrl("jdbc:mysql://" + MySQLConstants.HOST + ":3306/" + MySQLConstants.USERNAME + "_" + (production ? "production" : "dev") + "?allowMultiQueries=true"); + // Setting up the Hikari config && connecting to the MySQL server + dataSource = new HikariDataSource(setupConfig(production)); + // Setting up && creating the tables + createTables(setupTables()); + } + + private HikariConfig setupConfig(boolean production) { + final HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:mysql://" + MySQLConstants.HOST + ":3306/" + MySQLConstants.USERNAME + "_" + + (production ? "production" : "dev") + "?allowMultiQueries=true"); + config.setUsername(MySQLConstants.USERNAME); config.setPassword(MySQLConstants.AUTH); config.setDriverClassName("com.mysql.cj.jdbc.Driver"); config.addDataSourceProperty("cachePrepStmts", "true"); config.addDataSourceProperty("prepStmtCacheSize", "250"); config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); - dataSource = new HikariDataSource(config); + return config; + } - // Creating the tables - Table[] tables = new Table[] { + private Table[] setupTables() { + return new Table[] { new Table("accounts", new Column[] { new IntegerColumn("id", true, false), new StringColumn("uuid", 36, false), @@ -86,11 +96,15 @@ public class MySQLController { new StringColumn("kit", 50, false) }, new String[] { "accountId" }) }; - for (Table table : tables) { + } + + private void createTables(Table[] tablesArray) { + for (Table table : tablesArray) { try { table.create(this, true); - } catch (SQLException ex) { - ex.printStackTrace(); + }catch (Exception exception) { + System.out.println("Couldn't create table" + table.getName()); + exception.printStackTrace(); } } } diff --git a/serverdata/src/main/java/zone/themcgamer/data/mysql/repository/MySQLRepository.java b/serverdata/src/main/java/zone/themcgamer/data/mysql/repository/MySQLRepository.java index d48e31f..5055056 100644 --- a/serverdata/src/main/java/zone/themcgamer/data/mysql/repository/MySQLRepository.java +++ b/serverdata/src/main/java/zone/themcgamer/data/mysql/repository/MySQLRepository.java @@ -11,6 +11,9 @@ import java.util.function.Consumer; /** * @author Braydon */ + +// Maybe do all the CRUD operations? + @AllArgsConstructor public class MySQLRepository { protected final HikariDataSource dataSource;