dev #1
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
BlockAndSeek
|
||||
14
.idea/discord.xml
generated
Normal file
14
.idea/discord.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="PROJECT" />
|
||||
<option name="description" value="" />
|
||||
<option name="applicationTheme" value="default" />
|
||||
<option name="iconsTheme" value="default" />
|
||||
<option name="button1Title" value="" />
|
||||
<option name="button1Url" value="" />
|
||||
<option name="button2Title" value="" />
|
||||
<option name="button2Url" value="" />
|
||||
<option name="customApplicationId" value="" />
|
||||
</component>
|
||||
</project>
|
||||
13
.idea/modules/BlockAndSeek.test.iml
generated
Normal file
13
.idea/modules/BlockAndSeek.test.iml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="minecraft" name="Minecraft">
|
||||
<configuration>
|
||||
<autoDetectTypes>
|
||||
<platformType>ADVENTURE</platformType>
|
||||
</autoDetectTypes>
|
||||
<projectReimportVersion>1</projectReimportVersion>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,84 +0,0 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
import hdvtdev.blockAndSeek.eventListeners.DefaultEventListener;
|
||||
import hdvtdev.blockAndSeek.eventListeners.EventListener;
|
||||
import hdvtdev.blockAndSeek.eventListeners.ForceControlEventListener;
|
||||
import hdvtdev.blockAndSeek.managers.ConfigManager;
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class BlockAndSeek extends JavaPlugin {
|
||||
|
||||
private static JavaPlugin javaPlugin;
|
||||
|
||||
public static Plugin getInstance() {
|
||||
return javaPlugin;
|
||||
}
|
||||
|
||||
public static File getPluginDataFolder() {
|
||||
return javaPlugin.getDataFolder();
|
||||
}
|
||||
|
||||
public static File getServerDataFolder() {
|
||||
return javaPlugin.getServer().getPluginsFolder().getParentFile();
|
||||
}
|
||||
|
||||
public static InputStream getPluginResource(String resource) {
|
||||
return javaPlugin.getResource(resource);
|
||||
}
|
||||
|
||||
public static void saveResource(String file) {
|
||||
javaPlugin.saveResource(file, false);
|
||||
}
|
||||
|
||||
public static Logger getPluginLogger() {
|
||||
return javaPlugin.getLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
javaPlugin = this;
|
||||
|
||||
ConfigurationSerialization.registerClass(BlockAndSeekMap.class, "BlockAndSeekMap");
|
||||
ConfigurationSerialization.registerClass(Config.class, "BlockAndSeekConfig");
|
||||
|
||||
|
||||
LibsDisguises libsDisguises = (LibsDisguises) Bukkit.getPluginManager().getPlugin("LibsDisguises");
|
||||
if (libsDisguises == null) {
|
||||
getLogger().severe("LibsDisguises not found! It's required for the plugin to work!");
|
||||
super.onDisable();
|
||||
}
|
||||
|
||||
try {
|
||||
ConfigManager.loadAll();
|
||||
} catch (IOException e) {
|
||||
getLogger().severe("Failed to save some .yml configs!");
|
||||
}
|
||||
|
||||
PluginCommand command = Objects.requireNonNull(getCommand("blockandseek"));
|
||||
command.setExecutor(new CommandListener());
|
||||
|
||||
PluginManager manager = getServer().getPluginManager();
|
||||
manager.registerEvents(ConfigManager.getConfig().forceControl() ? new ForceControlEventListener() : new EventListener(), this);
|
||||
manager.registerEvents(new DefaultEventListener(), this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
//import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
//import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
//import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
|
||||
import hdvtdev.blockAndSeek.managers.*;
|
||||
import hdvtdev.blockAndSeek.roulette.RouletteCreator;
|
||||
import me.libraryaddict.disguise.DisguiseAPI;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class CommandListener implements TabExecutor {
|
||||
|
||||
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||
|
||||
|
||||
int argsLen = args.length;
|
||||
|
||||
if (argsLen == 0) {
|
||||
sender.sendMessage(Localization.get("bs-usage"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
switch (args[0]) {
|
||||
case "test" -> {
|
||||
if (sender instanceof Player player) {
|
||||
GamesManager.createGame("dust2");
|
||||
GamesManager.get("dust2").addPlayer(player);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
case "locale" -> {
|
||||
if (sender instanceof Player player) {
|
||||
player.sendMessage(player.locale().toLanguageTag());
|
||||
player.sendMessage("eq: " + player.locale().toLanguageTag().equals("en-US"));
|
||||
}
|
||||
}
|
||||
case "menu" -> {
|
||||
if (sender instanceof Player player) {
|
||||
GuiManager.Menu.open(player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case "morph" -> {
|
||||
if (sender instanceof Player player && args.length == 2) {
|
||||
Material material = Material.valueOf(args[1].toUpperCase());
|
||||
|
||||
PropManager.addPlayerDisguise(player, material.createBlockData());
|
||||
DisguiseAPI.disguiseToAll(player, new MiscDisguise(DisguiseType.FALLING_BLOCK, new ItemStack(material)));
|
||||
}
|
||||
}
|
||||
|
||||
case "damage" -> {
|
||||
if (sender instanceof Player player && args.length == 2) {
|
||||
player.damage(Double.parseDouble(args[1]));
|
||||
}
|
||||
}
|
||||
|
||||
case "health" -> {
|
||||
if (sender instanceof Player player && args.length == 2) {
|
||||
player.setHealth(Double.parseDouble(args[1]));
|
||||
}
|
||||
}
|
||||
|
||||
case "new" -> {
|
||||
if (sender instanceof Player player) {
|
||||
new RouletteCreator(player, List.of(
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.STONE), 10),
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.DIRT), 10),
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.LANTERN), 10),
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.TARGET), 10),
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.SCULK_SHRIEKER), 10),
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.FLOWER_POT), 10),
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.AZALEA_LEAVES), 10),
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.PUMPKIN), 10),
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.MELON), 10),
|
||||
new BlockAndSeekMap.Block(new ItemStack(Material.DIAMOND_BLOCK), 10)
|
||||
));
|
||||
}
|
||||
}
|
||||
case "foo" -> {
|
||||
if (sender instanceof Player player) {
|
||||
ItemStack foo = new ItemStack(Material.BROWN_DYE);
|
||||
ItemMeta fooMeta = foo.getItemMeta();
|
||||
fooMeta.displayName(MiniMessage.miniMessage().deserialize("<gradient:#00FF00:#01A368><bold>SoundMaker3000"));
|
||||
fooMeta.getPersistentDataContainer().set(Keys.SOUND_ITEM, PersistentDataType.BOOLEAN, true);
|
||||
foo.setItemMeta(fooMeta);
|
||||
player.getInventory().addItem(foo);
|
||||
}
|
||||
}
|
||||
case "bbb" -> {
|
||||
if (sender instanceof Player player) {
|
||||
PropManager.changePropDirection(player);
|
||||
}
|
||||
}
|
||||
case "container" -> {
|
||||
if (sender instanceof Player player) {
|
||||
var container = player.getPersistentDataContainer();
|
||||
player.sendMessage("containers: " + container.getKeys());
|
||||
|
||||
}
|
||||
}
|
||||
case "def" -> {
|
||||
if (sender instanceof Player player) {
|
||||
player.setVisibleByDefault(true);
|
||||
player.setInvisible(false);
|
||||
player.setInvulnerable(false);
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
player.setGlowing(false);
|
||||
player.clearActivePotionEffects();
|
||||
player.setHealth(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getDefaultValue());
|
||||
player.setFoodLevel(20);
|
||||
Utils.setLevelWithBar(player, 0);
|
||||
DisguiseAPI.undisguiseToAll(player);
|
||||
PersistentDataContainer dataContainer = player.getPersistentDataContainer();
|
||||
for (var key : dataContainer.getKeys()) {
|
||||
dataContainer.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
case "map" -> {
|
||||
if (sender.hasPermission("blockandseek.manage")) {
|
||||
if (argsLen > 1) {
|
||||
switch (args[1]) {
|
||||
case "list" -> {
|
||||
StringBuilder buffer = new StringBuilder(Localization.get("maps-available"));
|
||||
String listElement = Localization.get("maps-available-element");
|
||||
Set<String> readyMaps = null; //TODO ConfigManager.getReadyMaps();
|
||||
for (String map : ConfigManager.getAllMaps()) {
|
||||
buffer.append("\n").append(listElement.replace("{map}", map).replace("{color-status}",
|
||||
readyMaps.contains(map) ? "<green>" : "<red>"));
|
||||
}
|
||||
sender.sendMessage(miniMessage.deserialize(buffer.toString()));
|
||||
}
|
||||
default -> {
|
||||
if (ConfigManager.getAllMaps().contains(args[1])) {
|
||||
if (argsLen > 3) {
|
||||
switch (args[2]) {
|
||||
case "setduration" -> {
|
||||
try {
|
||||
int duration = Integer.parseInt(args[3]);
|
||||
if (duration > 0) {
|
||||
sender.sendMessage(args[1]);
|
||||
var map = MapsManager.getMap(args[1]);
|
||||
map.setDuration(duration);
|
||||
MapsManager.saveMap(args[1], map);
|
||||
sender.sendMessage("duration set");
|
||||
} else sender.sendMessage("idk");
|
||||
|
||||
} catch (NumberFormatException | IOException e) {
|
||||
sender.sendMessage("idk");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
sender.sendMessage(Localization.getComponent("not-enough-arguments", "{command}", "/blockandseek map", "{help}", "[MAP NAME | COMMANDS]"));
|
||||
|
||||
} else sender.sendMessage(Localization.getComponent("not-enough-permissions"));
|
||||
}
|
||||
case "reload" -> {
|
||||
if (sender.hasPermission("blockandseek.manage")) {
|
||||
if (argsLen > 1) {
|
||||
switch (args[1]) {
|
||||
case "localization" -> {
|
||||
try {
|
||||
|
||||
ConfigManager.load("localization.yml");
|
||||
sender.sendMessage(Localization.getComponentWithPrefix("successful-reload", "{config}", "localization.yml"));
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(Localization.getComponentWithPrefix("failed-reload", "{config}", "localization.yml", "{e}", e.getMessage()));
|
||||
}
|
||||
|
||||
}
|
||||
case "maps" -> {
|
||||
try {
|
||||
ConfigManager.load(null);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
sender.sendMessage(Localization.get("maps-reload"));
|
||||
}
|
||||
}
|
||||
} else
|
||||
sender.sendMessage(Localization.get("not-enough-arguments", "{usage}", "<green>/blockandseek reload <gold>[messages | maps]<white>"));
|
||||
|
||||
} else sender.sendMessage(Localization.get("not-enough-permissions"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||
return !sender.hasPermission("blockandseek.manage") ? List.of() : switch (args.length) {
|
||||
case 1 -> List.of("info", "map", "reload");
|
||||
case 2 -> switch (args[0]) {
|
||||
case "reload" -> List.of("localization", "config");
|
||||
case "map" -> {
|
||||
List<String> mapCommands = new ArrayList<>(MapsManager.getAllMaps());
|
||||
mapCommands.add("create");
|
||||
mapCommands.add("list");
|
||||
yield mapCommands;
|
||||
}
|
||||
default -> List.of();
|
||||
};
|
||||
case 3 -> {
|
||||
if (MapsManager.getAllMaps().contains(args[1])) {
|
||||
yield List.of("status", "setspawn", "setlobby", "setduration", "setminplayers", "setmaxplayers", "addblock", "deleteblock");
|
||||
}
|
||||
yield List.of();
|
||||
}
|
||||
case 4 -> switch (args[2]) {
|
||||
case "setspawn", "setlobby" -> {
|
||||
if (sender instanceof Player player) {
|
||||
Location location = player.getLocation().toCenterLocation();
|
||||
yield List.of(String.format("%s %s %s", location.getX(), location.getY(), location.getZ()));
|
||||
} else yield List.of();
|
||||
}
|
||||
case "setduration" -> List.of("[<duration>]");
|
||||
case "setminplayers", "setmaxplayers" -> List.of("[<count>]");
|
||||
case "addblock", "removeblock" ->
|
||||
Arrays.stream(Material.values()).map(Objects::toString).map(String::toLowerCase).toList();
|
||||
default -> List.of();
|
||||
};
|
||||
case 5 -> args[2].equalsIgnoreCase("addblock") ? List.of("[<chance>]") : List.of();
|
||||
|
||||
default -> List.of();
|
||||
};
|
||||
}
|
||||
|
||||
/* TODO
|
||||
public static void registerCompletions(Commodore commodore, PluginCommand command) {
|
||||
commodore.register(command, LiteralArgumentBuilder.literal("blockandseek")
|
||||
.then(RequiredArgumentBuilder.argument("idk", StringArgumentType.greedyString()).suggests((a, b) -> {
|
||||
b.suggest("sometextidk");
|
||||
|
||||
return b.buildFuture();
|
||||
}).executes(o -> {
|
||||
System.out.println(23238923);
|
||||
return 1;
|
||||
})));
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public record Config(@NotNull Location defaultSpawn, boolean forceControl) implements ConfigurationSerializable {
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> serialize() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("default-spawn", defaultSpawn.serialize());
|
||||
map.put("force-control", Boolean.valueOf(forceControl));
|
||||
return map;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Config deserialize(@NotNull Map<String, Object> args) {
|
||||
Map<String, Object> location = (Map<String, Object>) args.get("default-spawn");
|
||||
List<Integer> cords = location == null || location.isEmpty() ? List.of() : (List<Integer>) location.get("location");
|
||||
World world = location == null || location.isEmpty() ? null : Bukkit.getWorld((String) location.get("world"));
|
||||
if (world == null) {
|
||||
world = Bukkit.createWorld(new WorldCreator("world"));
|
||||
}
|
||||
if (cords.isEmpty() || cords.size() < 3) {
|
||||
Location spawn = world.getSpawnLocation();
|
||||
cords = List.of((int) spawn.getX(), (int) spawn.getY(), (int) spawn.getZ());
|
||||
}
|
||||
return new Config(new Location(world, cords.getFirst(), cords.get(1), cords.get(2)), (Boolean) args.get("force-control"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
import hdvtdev.blockAndSeek.managers.ConfigManager;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
import net.kyori.adventure.title.Title;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class Localization {
|
||||
|
||||
private static volatile Map<String, Map<String, String>> localization = Collections.unmodifiableMap(ConfigManager.getLocalization());
|
||||
|
||||
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||
private static final PlainTextComponentSerializer plainText = PlainTextComponentSerializer.plainText();
|
||||
private static final Component prefix = miniMessage.deserialize("<gold>[<bold><blue>BlockAndSeek<reset><gold>] ");
|
||||
private static final Component empty = Component.empty();
|
||||
|
||||
public static void update() {
|
||||
localization = Collections.unmodifiableMap(ConfigManager.getLocalization());
|
||||
}
|
||||
|
||||
public static ItemStack translateItem(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull String... replacements) {
|
||||
ItemStack translatedItem = itemStack.clone();
|
||||
ItemMeta itemMeta = translatedItem.getItemMeta();
|
||||
String key = plainText.serialize(itemMeta.displayName());
|
||||
itemMeta.displayName(getComponent(player.locale().toLanguageTag(), key, replacements));
|
||||
translatedItem.setItemMeta(itemMeta);
|
||||
return translatedItem;
|
||||
}
|
||||
|
||||
public static void sendMessage(@NotNull Iterable<Player> players, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
|
||||
for (Player player : players) {
|
||||
sendMessage(player, addPrefix, key, replacements);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendMessage(@NotNull Player player, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
|
||||
Component component = getComponent(player.locale().toLanguageTag(), key, replacements);
|
||||
player.sendMessage(addPrefix ? prefix.append(component) : component);
|
||||
}
|
||||
|
||||
public static void sendActionBar(@NotNull Iterable<Player> players, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
|
||||
for (Player player : players) {
|
||||
sendActionBar(player, addPrefix, key, replacements);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String get(String a) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Component getComponent(String a) {
|
||||
return empty;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Component getComponentWithPrefix(String... a) {
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
public static void sendActionBar(@NotNull Player player, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
|
||||
Component component = getComponent(player.locale().toLanguageTag(), key, replacements);
|
||||
player.sendActionBar(addPrefix ? prefix.append(component) : component);
|
||||
}
|
||||
|
||||
public static void sendTitle(@NotNull Iterable<Player> players, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
|
||||
for (Player player : players) {
|
||||
sendTitle(player, addPrefix, key, replacements);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendTitle(@NotNull Player player, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
|
||||
Component component = getComponent(player.locale().toLanguageTag(), key, replacements);
|
||||
player.showTitle(Title.title(addPrefix ? prefix.append(component) : component, empty));
|
||||
}
|
||||
|
||||
public static @NotNull Component getComponent(@NotNull Player p, @NotNull String key, @NotNull String... replacements) {
|
||||
return getComponent(p.locale().toLanguageTag(), key, replacements);
|
||||
}
|
||||
|
||||
public static @NotNull Component getComponent(@NotNull String lang, @NotNull String key, @NotNull String... replacements) {
|
||||
return miniMessage.deserialize(get(lang, key, replacements));
|
||||
}
|
||||
|
||||
public static @NotNull String get(@NotNull String lang, @NotNull String key, @NotNull String... replacements) {
|
||||
|
||||
String s = localization.getOrDefault(lang, localization.get("en-US")).get(key);
|
||||
if (s != null) {
|
||||
for (int i = 0; i < replacements.length; i += 2) {
|
||||
s = s.replace(replacements[i], replacements[i + 1]);
|
||||
}
|
||||
} else return "Unknown localization: " + key;
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,279 +0,0 @@
|
||||
package hdvtdev.blockAndSeek.eventListeners;
|
||||
|
||||
import hdvtdev.blockAndSeek.BlockAndSeek;
|
||||
import hdvtdev.blockAndSeek.Keys;
|
||||
import hdvtdev.blockAndSeek.Utils;
|
||||
import hdvtdev.blockAndSeek.managers.GamesManager;
|
||||
import hdvtdev.blockAndSeek.managers.GuiManager;
|
||||
import hdvtdev.blockAndSeek.managers.PropManager;
|
||||
import hdvtdev.blockAndSeek.roulette.RouletteCreator;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDismountEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static hdvtdev.blockAndSeek.Utils.isInOneTeam;
|
||||
import static hdvtdev.blockAndSeek.Utils.playerInGame;
|
||||
|
||||
public class DefaultEventListener implements Listener {
|
||||
|
||||
private static final BukkitScheduler scheduler = Bukkit.getScheduler();
|
||||
private static final Set<Player> coolDown = ConcurrentHashMap.newKeySet();
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
private static final ConcurrentHashMap<Player, BukkitTask> tasks = new ConcurrentHashMap<>();
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void createTask(Player player, BukkitTask bukkitTask) {
|
||||
tasks.put(player, bukkitTask);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void stopTask(Player player) {
|
||||
BukkitTask task = tasks.remove(player);
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (player.getVehicle() instanceof ArmorStand armorStand) {
|
||||
PersistentDataContainer armorStandContainer = armorStand.getPersistentDataContainer();
|
||||
if (armorStandContainer.has(Keys.FROZEN_PLAYER)) {
|
||||
armorStandContainer.remove(Keys.FROZEN_PLAYER);
|
||||
armorStand.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockDamage(BlockDamageEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (player.getPersistentDataContainer().has(Keys.SEEKER)) {
|
||||
if (PropManager.unfreeze(event.getBlock().getBlockData())) {
|
||||
event.setCancelled(true);
|
||||
} else {
|
||||
player.damage(2);
|
||||
Utils.setLevelWithBar(player, (int) Math.round(player.getHealth() * 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRightClick(PlayerInteractEvent event) {
|
||||
if (event.getHand() != EquipmentSlot.HAND) return;
|
||||
Action action = event.getAction();
|
||||
Player player = event.getPlayer();
|
||||
if (action.isRightClick() && !coolDown.contains(player)) {
|
||||
|
||||
|
||||
ItemStack itemInHand = player.getInventory().getItemInMainHand();
|
||||
ItemMeta meta = itemInHand.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
PersistentDataContainer itemData = meta.getPersistentDataContainer();
|
||||
if (itemData.has(Keys.FREEZE_ITEM) && playerInGame(player)) {
|
||||
coolDown.add(player);
|
||||
scheduler.runTaskLater(BlockAndSeek.getInstance(), () -> coolDown.remove(player), 3L);
|
||||
PropManager.freeze(player);
|
||||
event.setCancelled(true);
|
||||
} else if (itemData.has(Keys.MENU_ITEM)) {
|
||||
GuiManager.Menu.open(player);
|
||||
event.setCancelled(true);
|
||||
} else if (itemData.has(Keys.LEAVE_ITEM)) {
|
||||
String game = player.getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING);
|
||||
GamesManager.get(game).removePlayer(player);
|
||||
event.setCancelled(true);
|
||||
} else if (itemData.has(Keys.FACE_CHANGING_ITEM)) {
|
||||
PropManager.changePropDirection(player);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityDismount(EntityDismountEvent event) {
|
||||
Player player = (Player) event.getEntity();
|
||||
if (event.getDismounted() instanceof ArmorStand armorStand && armorStand.getPersistentDataContainer().has(Keys.FROZEN_PLAYER)) {
|
||||
PropManager.freeze(player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
PersistentDataContainer container = player.getPersistentDataContainer();
|
||||
|
||||
String arena = container.get(Keys.GAME, PersistentDataType.STRING);
|
||||
if (arena != null) {
|
||||
GamesManager.get(arena).removePlayer(player);
|
||||
PropManager.removePlayerDisguise(player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
String game = player.getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING);
|
||||
if (game != null) {
|
||||
event.deathMessage(null);
|
||||
event.setDroppedExp(0);
|
||||
event.getDrops().clear();
|
||||
scheduler.runTask(BlockAndSeek.getInstance(), () -> GamesManager.get(game).setSpectator(player, player.getKiller()));
|
||||
//without scheduler strange things are happening idk
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClose(InventoryCloseEvent event) {
|
||||
|
||||
Player player = (Player) event.getPlayer();
|
||||
InventoryHolder holder = event.getInventory().getHolder();
|
||||
|
||||
|
||||
if (holder instanceof RouletteCreator rouletteCreator) {
|
||||
|
||||
Boolean isClosedByPlayer = rouletteCreator.isClosedByPlayer();
|
||||
|
||||
if (isClosedByPlayer != null) {
|
||||
RouletteCreator.Task task = rouletteCreator.getTask();
|
||||
if (isClosedByPlayer) {
|
||||
if (!task.rouletteTask().isCancelled()) {
|
||||
Utils.firstDisguise(player, rouletteCreator.randomPropItem());
|
||||
} else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem());
|
||||
task.cancelBoth();
|
||||
} else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
Inventory inventory = event.getClickedInventory();
|
||||
|
||||
|
||||
if (inventory != null) {
|
||||
|
||||
InventoryHolder holder = inventory.getHolder();
|
||||
int slot = event.getSlot();
|
||||
ItemStack item = inventory.getItem(slot);
|
||||
|
||||
if (holder instanceof RouletteCreator rouletteCreator) {
|
||||
RouletteCreator.Task task = rouletteCreator.getTask();
|
||||
|
||||
if (task.rouletteTask().isCancelled()) {
|
||||
if (slot == 21 || slot == 23 || slot == 25) {
|
||||
task.autoCloseTask().cancel();
|
||||
Utils.firstDisguise(player, inventory.getItem(slot));
|
||||
rouletteCreator.closeInventory();
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
} else {
|
||||
if (slot == 36) {
|
||||
task.cancelBoth();
|
||||
Utils.firstDisguise(player, rouletteCreator.randomPropItem());
|
||||
rouletteCreator.closeInventory();
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (item != null) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta != null) {
|
||||
PersistentDataContainer itemData = meta.getPersistentDataContainer();
|
||||
|
||||
if (itemData.has(Keys.GAME_PAGE)) {
|
||||
GuiManager.Menu.Games.open(player);
|
||||
event.setCancelled(true);
|
||||
} else if (itemData.has(Keys.GAME)) {
|
||||
String game = itemData.get(Keys.GAME, PersistentDataType.STRING);
|
||||
if (game != null) {
|
||||
GamesManager.get(game).addPlayer(player);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//TODO MOVE TO EVENT LISTENER
|
||||
if (player.getPersistentDataContainer().has(Keys.GAME)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRegainHealth(EntityRegainHealthEvent event) {
|
||||
if (event.getEntity() instanceof Player player) {
|
||||
PersistentDataContainer container = player.getPersistentDataContainer();
|
||||
if (container.has(Keys.SEEKER)) {
|
||||
event.setCancelled(true);
|
||||
} else if (container.has(Keys.HIDER)) {
|
||||
if (!PropManager.isPlayerDisguised(player)) event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerDamage(EntityDamageByEntityEvent event) {
|
||||
if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) {
|
||||
if (isInOneTeam(damager, victim)) {
|
||||
event.setCancelled(true);
|
||||
} else if (victim.getPersistentDataContainer().has(Keys.SEEKER)) {
|
||||
event.setDamage(0);
|
||||
} else if (damager.getPersistentDataContainer().has(Keys.SEEKER)) {
|
||||
double maxHealth = 20.0;
|
||||
double currentHealth = damager.getHealth();
|
||||
if (currentHealth < maxHealth) {
|
||||
double newHealth = Math.min(currentHealth + event.getDamage(), maxHealth);
|
||||
damager.setHealth(newHealth);
|
||||
Utils.setLevelWithBar(damager, (int) Math.round(damager.getHealth() * 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
package hdvtdev.blockAndSeek.managers;
|
||||
|
||||
import hdvtdev.blockAndSeek.BlockAndSeek;
|
||||
import hdvtdev.blockAndSeek.BlockAndSeekMap;
|
||||
import hdvtdev.blockAndSeek.Config;
|
||||
import hdvtdev.blockAndSeek.Localization;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
private static volatile Map<String, Map<String, String>> localization;
|
||||
private static volatile Config config;
|
||||
private static Map<String, BlockAndSeekMap> maps = new ConcurrentHashMap<>();
|
||||
|
||||
private static final File mapsFile = new File(BlockAndSeek.getPluginDataFolder(), "maps.yml");
|
||||
|
||||
public static Config getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
public static Set<String> getAllMaps() {
|
||||
return YamlConfiguration.loadConfiguration(mapsFile).getKeys(false);
|
||||
}
|
||||
|
||||
public static void loadAll() throws IOException {
|
||||
load("config.yml");
|
||||
load("localization.yml");
|
||||
load("maps.yml");
|
||||
}
|
||||
|
||||
public static void load(String file) throws IOException {
|
||||
|
||||
File conf = new File(BlockAndSeek.getPluginDataFolder(), file);
|
||||
|
||||
YamlConfiguration defaultConfiguration = YamlConfiguration.loadConfiguration(
|
||||
new InputStreamReader(BlockAndSeek.getPluginResource(file)));
|
||||
|
||||
if (!conf.exists()) {
|
||||
BlockAndSeek.saveResource(file);
|
||||
|
||||
|
||||
/*
|
||||
switch (file) {
|
||||
case "config.yml" -> config = defaultConfiguration.getSerializable("config", Config.class);
|
||||
case "localization.yml" -> {
|
||||
Map<String, Map<String, String>> confMap = new HashMap<>();
|
||||
Map<String, String> lang = new HashMap<>();
|
||||
for (String key : defaultConfiguration.getConfigurationSection("en-US").getKeys(false)) {
|
||||
lang.put(key, defaultConfiguration.getString(key, "NULL"));
|
||||
}
|
||||
confMap.put("en-US", lang);
|
||||
localization = confMap;
|
||||
Localization.update();
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
switch (file) {
|
||||
case "config.yml" -> loadConfig(conf, defaultConfiguration);
|
||||
case "localization.yml" -> loadLocalization(conf, defaultConfiguration);
|
||||
case "maps.yml" -> MapsManager.loadMaps();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void loadConfig(File configurationFile, YamlConfiguration defaultConfiguration) {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configurationFile);
|
||||
configuration.setDefaults(defaultConfiguration);
|
||||
|
||||
config = configuration.getSerializable("config", Config.class);
|
||||
}
|
||||
|
||||
private static void loadLocalization(File configurationFile, YamlConfiguration defaultConfiguration) throws IOException {
|
||||
|
||||
Map<String, Map<String, String>> confMap = new HashMap<>();
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configurationFile);
|
||||
|
||||
ConfigurationSection defaultSection = defaultConfiguration.getConfigurationSection("en-US");
|
||||
|
||||
for (String langKey : configuration.getKeys(false)) {
|
||||
ConfigurationSection configSection = configuration.getConfigurationSection(langKey);
|
||||
Map<String, String> langMap = new HashMap<>();
|
||||
|
||||
if (configSection != null) {
|
||||
for (String key : defaultSection.getKeys(false)) {
|
||||
if (configSection.contains(key)) {
|
||||
langMap.put(key, configSection.getString(key, defaultSection.getString(key, "NULL")));
|
||||
} else {
|
||||
String value = defaultSection.getString(key, "NULL");
|
||||
configSection.set(key, value);
|
||||
langMap.put(key, value);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
BlockAndSeek.getPluginLogger().warning("No any language found in the configuration! Using default en-US.");
|
||||
for (String key : defaultSection.getKeys(false)) {
|
||||
langMap.put(key, defaultSection.getString(key, "NULL"));
|
||||
}
|
||||
}
|
||||
|
||||
confMap.put(langKey, langMap);
|
||||
}
|
||||
|
||||
|
||||
configuration.save(configurationFile);
|
||||
|
||||
localization = confMap;
|
||||
Localization.update();
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, Map<String, String>> getLocalization() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
package hdvtdev.blockAndSeek.managers;
|
||||
|
||||
import hdvtdev.blockAndSeek.BlockAndSeekGame;
|
||||
import hdvtdev.blockAndSeek.Keys;
|
||||
import hdvtdev.blockAndSeek.Localization;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GuiManager {
|
||||
|
||||
private static final ItemStack filler1 = new ItemStack(Material.ORANGE_STAINED_GLASS_PANE);
|
||||
private static final ItemStack filler2 = new ItemStack(Material.BLUE_STAINED_GLASS_PANE);
|
||||
private static final ItemStack filler3 = new ItemStack(Material.GREEN_STAINED_GLASS_PANE);
|
||||
|
||||
private GuiManager() {
|
||||
}
|
||||
|
||||
public static void fill(Inventory inventory) {
|
||||
int size = inventory.getSize();
|
||||
for (int i = 0; i < size; i++) {
|
||||
inventory.setItem(i, i % 2 == 0 ? filler1 : filler2);
|
||||
}
|
||||
}
|
||||
|
||||
public static void fillAlt(Inventory inventory) {
|
||||
int size = inventory.getSize();
|
||||
for (int i = 0; i < size; i++) {
|
||||
inventory.setItem(i, i % 2 == 0 ? filler3 : filler2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Menu implements InventoryHolder {
|
||||
|
||||
public static final Menu instance = new Menu();
|
||||
|
||||
|
||||
private Menu() {
|
||||
}
|
||||
|
||||
public static void open(Player player) {
|
||||
|
||||
Inventory inventory = Bukkit.createInventory(instance, 27, Localization.getComponent(player, "menu-item"));
|
||||
inventory.setItem(13, Localization.translateItem(player, ItemManager.getGamesPageItem()));
|
||||
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Inventory getInventory() {
|
||||
return Bukkit.createInventory(instance, 27, Component.text("raw"));
|
||||
}
|
||||
|
||||
public static class Games implements InventoryHolder {
|
||||
|
||||
private static final ItemStack defaultGameItem = new ItemStack(Material.CLOCK);
|
||||
|
||||
private Games() {
|
||||
}
|
||||
|
||||
public static void open(Player player) {
|
||||
|
||||
Inventory gamesMenu = Bukkit.createInventory(new Games(), 45, Localization.getComponent(player, "games-page-item"));
|
||||
for (String game : GamesManager.getAvailableGames()) {
|
||||
BlockAndSeekGame blockAndSeekGame = GamesManager.get(game);
|
||||
ItemStack gameItem = defaultGameItem.clone();
|
||||
ItemMeta meta = gameItem.getItemMeta();
|
||||
meta.getPersistentDataContainer().set(Keys.GAME, PersistentDataType.STRING, game);
|
||||
meta.displayName(Component.text("game-name"));
|
||||
meta.lore(List.of(Localization.getComponent(
|
||||
player,
|
||||
"game-player-count",
|
||||
"{players}", String.valueOf(blockAndSeekGame.playerCount()),
|
||||
"{max-players}", String.valueOf(blockAndSeekGame.maxPlayers())
|
||||
)));
|
||||
gameItem.setItemMeta(meta);
|
||||
gamesMenu.addItem(Localization.translateItem(player, gameItem, "{name}", game));
|
||||
}
|
||||
|
||||
|
||||
if (player.hasPermission("blockandseek.manage")) {
|
||||
gamesMenu.setItem(44, ItemManager.getCreateGameButton());
|
||||
}
|
||||
|
||||
player.openInventory(gamesMenu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Inventory getInventory() {
|
||||
return Bukkit.createInventory(null, 9);
|
||||
}
|
||||
|
||||
|
||||
public static abstract class Maps implements InventoryHolder {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package hdvtdev.blockAndSeek.managers;
|
||||
|
||||
import hdvtdev.blockAndSeek.BlockAndSeek;
|
||||
import hdvtdev.blockAndSeek.BlockAndSeekMap;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MapsManager {
|
||||
|
||||
private static volatile Map<String, BlockAndSeekMap> allMaps = new ConcurrentHashMap<>();
|
||||
private static final Map<String, BlockAndSeekMap> readyMaps = new ConcurrentHashMap<>();
|
||||
|
||||
private static final File mapsFile = new File(BlockAndSeek.getPluginDataFolder(), "maps.yml");
|
||||
|
||||
public static Set<String> getAllMaps() {
|
||||
return allMaps.keySet();
|
||||
}
|
||||
|
||||
public static BlockAndSeekMap getMap(String name) {
|
||||
return allMaps.get(name);
|
||||
}
|
||||
|
||||
public static void saveMap(String name, BlockAndSeekMap map) throws IOException {
|
||||
var conf = YamlConfiguration.loadConfiguration(mapsFile);
|
||||
if (conf.contains(name)) conf.set(name, null);
|
||||
conf.set(name, map);
|
||||
conf.save(mapsFile);
|
||||
}
|
||||
|
||||
public static void loadMaps() {
|
||||
Map<String, BlockAndSeekMap> confMap = new ConcurrentHashMap<>();
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(mapsFile);
|
||||
|
||||
for (String map : configuration.getKeys(false)) {
|
||||
|
||||
|
||||
BlockAndSeekMap blockAndSeekMap = configuration.getSerializable(map, BlockAndSeekMap.class, BlockAndSeekMap.defaultMap());
|
||||
if (blockAndSeekMap.isReady()) readyMaps.put(map, blockAndSeekMap);
|
||||
confMap.put(map, blockAndSeekMap);
|
||||
}
|
||||
|
||||
allMaps = confMap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
package hdvtdev.blockAndSeek.managers;
|
||||
|
||||
import hdvtdev.blockAndSeek.Keys;
|
||||
import me.libraryaddict.disguise.DisguiseAPI;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Directional;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class PropManager {
|
||||
|
||||
private static final Map<Player, FreezeData> frozenPlayers = new ConcurrentHashMap<>();
|
||||
private static final Map<Player, BlockData> playerDisguise = new ConcurrentHashMap<>();
|
||||
private static final Map<BlockData, Player> disguisePlayer = new ConcurrentHashMap<>();
|
||||
|
||||
private static final Disguise hideDisguise = new MiscDisguise(DisguiseType.LLAMA_SPIT);
|
||||
private static final Vector zeroVelocity = new Vector(0, 0, 0);
|
||||
|
||||
public static boolean isPlayerDisguised(Player player) {
|
||||
return frozenPlayers.containsKey(player);
|
||||
}
|
||||
|
||||
public static void addPlayerDisguise(Player player, BlockData blockData) {
|
||||
disguisePlayer.put(blockData, player);
|
||||
playerDisguise.put(player, blockData);
|
||||
}
|
||||
|
||||
public static void removePlayerDisguise(Player player) {
|
||||
disguisePlayer.remove(playerDisguise.remove(player));
|
||||
}
|
||||
|
||||
public static void changePropDirection(Player player) {
|
||||
|
||||
if (frozenPlayers.containsKey(player)) {
|
||||
Block block = player.getLocation().getBlock();
|
||||
BlockData blockData = block.getBlockData();
|
||||
if (blockData instanceof Directional directional) {
|
||||
|
||||
BlockFace face = switch (directional.getFacing()) {
|
||||
case NORTH -> BlockFace.EAST;
|
||||
case EAST -> BlockFace.SOUTH;
|
||||
case SOUTH -> BlockFace.WEST;
|
||||
case WEST -> directional.getFaces().contains(BlockFace.UP) ? BlockFace.UP : BlockFace.NORTH;
|
||||
case UP -> BlockFace.DOWN;
|
||||
case DOWN -> BlockFace.NORTH;
|
||||
default -> null;
|
||||
};
|
||||
if (face != null && directional.getFaces().contains(face)) {
|
||||
directional.setFacing(face);
|
||||
block.setBlockData(blockData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void unfreezeIfFrozen(Player player) {
|
||||
Location location = player.getLocation();
|
||||
FreezeData data = frozenPlayers.remove(player);
|
||||
if (data != null) {
|
||||
unfreeze(player, location, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean unfreeze(BlockData blockData) {
|
||||
Player player = disguisePlayer.get(blockData);
|
||||
if (player != null) {
|
||||
freeze(player);
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
private static void unfreeze(Player player, Location location, FreezeData data) {
|
||||
|
||||
Location blockLocation = location.getBlock().getLocation();
|
||||
location.getWorld().setBlockData(blockLocation, data.blockData);
|
||||
player.getPersistentDataContainer().remove(Keys.FROZEN_PLAYER);
|
||||
|
||||
player.setFreezeTicks(0);
|
||||
data.armorStand.remove();
|
||||
player.setInvulnerable(false);
|
||||
|
||||
Keys.NO_COLLIDE_TEAM.removeEntry(player.getName());
|
||||
|
||||
if (data.disguise != null) DisguiseAPI.disguiseToAll(player, data.disguise);
|
||||
|
||||
}
|
||||
|
||||
public static boolean freeze(Player player) {
|
||||
Location location = player.getLocation();
|
||||
FreezeData data = frozenPlayers.remove(player);
|
||||
if (data != null) {
|
||||
unfreeze(player, location, data);
|
||||
} else {
|
||||
|
||||
Block block = location.getBlock();
|
||||
BlockData blockData = block.getBlockData();
|
||||
Location blockLocation = block.getLocation();
|
||||
Location centerLocation = blockLocation.toCenterLocation();
|
||||
Location upperBlockLocation = centerLocation.clone();
|
||||
upperBlockLocation.setY(upperBlockLocation.getY() + 0.25);
|
||||
|
||||
if (!upperBlockLocation.getBlock().isSolid() && !blockLocation.getBlock().isSolid()) {
|
||||
|
||||
|
||||
location.getWorld().setBlockData(blockLocation, playerDisguise.get(player));
|
||||
|
||||
centerLocation.setY(centerLocation.getY() - 0.85);
|
||||
|
||||
player.setVelocity(zeroVelocity);
|
||||
player.setInvulnerable(true);
|
||||
player.getPersistentDataContainer().set(Keys.FROZEN_PLAYER, PersistentDataType.BOOLEAN, true);
|
||||
Keys.NO_COLLIDE_TEAM.addEntry(player.getName());
|
||||
|
||||
|
||||
ArmorStand armorStand = location.getWorld().spawn(centerLocation, ArmorStand.class, stand -> {
|
||||
stand.setVisible(false);
|
||||
stand.setVisible(false);
|
||||
stand.setCollidable(false);
|
||||
stand.setGravity(true);
|
||||
stand.setSmall(true);
|
||||
stand.setCanMove(false);
|
||||
stand.addPassenger(player);
|
||||
stand.getPersistentDataContainer().set(Keys.FROZEN_PLAYER, PersistentDataType.BOOLEAN, true);
|
||||
stand.setInvulnerable(true);
|
||||
});
|
||||
|
||||
|
||||
Disguise disguise = DisguiseAPI.getDisguise(player);
|
||||
|
||||
DisguiseAPI.disguiseToAll(player, hideDisguise);
|
||||
|
||||
player.setFreezeTicks(40);
|
||||
|
||||
|
||||
frozenPlayers.put(player, new FreezeData(armorStand, blockData, disguise));
|
||||
} else return false;
|
||||
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private record FreezeData(ArmorStand armorStand, BlockData blockData, Disguise disguise) {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
182
src/main/java/hdvtdev/blockandseek/BlockAndSeek.java
Normal file
182
src/main/java/hdvtdev/blockandseek/BlockAndSeek.java
Normal file
@@ -0,0 +1,182 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
|
||||
import hdvtdev.blockAndSeek.eventListeners.RequiredEventListener;
|
||||
import hdvtdev.blockAndSeek.eventListeners.EventListener;
|
||||
import hdvtdev.blockAndSeek.eventListeners.ForceControlEventListener;
|
||||
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bukkit.CloudBukkitCapabilities;
|
||||
import org.incendo.cloud.bukkit.parser.PlayerParser;
|
||||
import org.incendo.cloud.execution.ExecutionCoordinator;
|
||||
import org.incendo.cloud.paper.LegacyPaperCommandManager;
|
||||
import org.incendo.cloud.parser.standard.IntegerParser;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class BlockAndSeek extends JavaPlugin {
|
||||
|
||||
private static JavaPlugin javaPlugin;
|
||||
private static LegacyPaperCommandManager<CommandSender> commandManager;
|
||||
private static final String perm = "blockandseek.manage";
|
||||
|
||||
public static Plugin getInstance() {
|
||||
return javaPlugin;
|
||||
}
|
||||
|
||||
public static File getPluginDataFolder() {
|
||||
return javaPlugin.getDataFolder();
|
||||
}
|
||||
|
||||
public static File getServerDataFolder() {
|
||||
return javaPlugin.getServer().getPluginsFolder().getParentFile();
|
||||
}
|
||||
|
||||
public static void saveResource(String file) {
|
||||
javaPlugin.saveResource(file, false);
|
||||
}
|
||||
|
||||
public static Logger getPluginLogger() {
|
||||
return javaPlugin.getLogger();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
javaPlugin = this;
|
||||
|
||||
LibsDisguises libsDisguises = (LibsDisguises) Bukkit.getPluginManager().getPlugin("LibsDisguises");
|
||||
if (libsDisguises == null) {
|
||||
getLogger().severe("LibsDisguises not found! It's required for the plugin to work!");
|
||||
super.onDisable();
|
||||
}
|
||||
|
||||
this.init();
|
||||
|
||||
if (!Config.loadConfig()) getPluginLogger().warning("Failed to load BlockAndSeek config.toml! Using default config...");
|
||||
|
||||
|
||||
PluginCommand command = Objects.requireNonNull(getCommand("blockandseek"));
|
||||
|
||||
|
||||
PluginManager manager = getServer().getPluginManager();
|
||||
manager.registerEvents(Config.forceControl() ? new ForceControlEventListener() : new EventListener(), this);
|
||||
manager.registerEvents(new RequiredEventListener(), this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void init() {
|
||||
try {
|
||||
|
||||
File dataFolder = getDataFolder();
|
||||
|
||||
if (!dataFolder.exists()) {
|
||||
dataFolder.mkdirs();
|
||||
}
|
||||
|
||||
File mapsFolder = new File(dataFolder, "maps");
|
||||
if (!mapsFolder.exists()) {
|
||||
mapsFolder.mkdirs();
|
||||
}
|
||||
|
||||
File langsFolder = new File(dataFolder, "languages");
|
||||
if (!langsFolder.exists()) {
|
||||
langsFolder.mkdirs();
|
||||
}
|
||||
|
||||
File defaultLangFile = new File(langsFolder, "en_US.yml");
|
||||
|
||||
if (!defaultLangFile.exists()) {
|
||||
saveResource("languages/en_US.yml", false);
|
||||
}
|
||||
|
||||
commandManager = LegacyPaperCommandManager.createNative(
|
||||
this,
|
||||
ExecutionCoordinator.simpleCoordinator()
|
||||
);
|
||||
|
||||
|
||||
if (commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) {
|
||||
try {
|
||||
commandManager.registerBrigadier();
|
||||
} catch (IllegalStateException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.registerCommands();
|
||||
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Cloud err: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void registerCommands() {
|
||||
|
||||
Command.Builder<CommandSender> root = commandManager.commandBuilder("blockandseek");
|
||||
|
||||
|
||||
commandManager.command(root
|
||||
.literal("reload")
|
||||
.permission(perm)
|
||||
.handler(context -> {
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
|
||||
commandManager.command(root
|
||||
.literal("inttest")
|
||||
.required("text", IntegerParser.integerParser(0, 64))
|
||||
|
||||
.handler(context -> {
|
||||
String text = context.get("text");
|
||||
context.sender().sendMessage(text);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
commandManager.command(root
|
||||
.literal("map")
|
||||
.permission(perm)
|
||||
.required("map", StringParser.stringParser())
|
||||
.required("action", StringParser.stringParser())
|
||||
.handler(context -> {
|
||||
Player target = context.get("target");
|
||||
int amount = context.getOrDefault("amount", 1);
|
||||
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
113
src/main/java/hdvtdev/blockandseek/BlocksGenerator.java
Normal file
113
src/main/java/hdvtdev/blockandseek/BlocksGenerator.java
Normal file
@@ -0,0 +1,113 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.data.AnaloguePowerable;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Openable;
|
||||
import org.bukkit.block.data.Powerable;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public class BlocksGenerator {
|
||||
|
||||
private static boolean isSupported(Material type, BlockData data) {
|
||||
|
||||
if (type.isAir() || type.hasGravity() || !type.isSolid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data instanceof Powerable
|
||||
|| data instanceof Openable
|
||||
|| data instanceof AnaloguePowerable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return switch (type) {
|
||||
case CACTUS, FARMLAND,
|
||||
TNT, DISPENSER, DROPPER, HOPPER,
|
||||
PISTON, STICKY_PISTON, OBSERVER,
|
||||
COMMAND_BLOCK, REPEATING_COMMAND_BLOCK,
|
||||
CHAIN_COMMAND_BLOCK,
|
||||
SCULK_SENSOR, SCULK_SHRIEKER,
|
||||
DAYLIGHT_DETECTOR, JUKEBOX,
|
||||
TURTLE_EGG, DRAGON_EGG,
|
||||
BAMBOO, BAMBOO_SAPLING,
|
||||
CAKE, LECTERN, COMPOSTER,
|
||||
CAMPFIRE, SOUL_CAMPFIRE,
|
||||
BEEHIVE, BEE_NEST
|
||||
-> false;
|
||||
default -> true;
|
||||
};
|
||||
}
|
||||
|
||||
public static void getSortedBlockStats(Location center, int chunkRadius, Consumer<List<Map.Entry<Material, Long>>> callback) {
|
||||
World world = center.getWorld();
|
||||
if (world == null) return;
|
||||
|
||||
|
||||
List<ChunkSnapshot> snapshots = new ArrayList<>();
|
||||
|
||||
int centerX = center.getBlockX() >> 4;
|
||||
int centerZ = center.getBlockZ() >> 4;
|
||||
|
||||
|
||||
for (int x = centerX - chunkRadius; x <= centerX + chunkRadius; x++) {
|
||||
for (int z = centerZ - chunkRadius; z <= centerZ + chunkRadius; z++) {
|
||||
if (world.isChunkLoaded(x, z)) {
|
||||
Chunk chunk = world.getChunkAt(x, z);
|
||||
snapshots.add(chunk.getChunkSnapshot(false, false, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Map<Material, Long> counts = new HashMap<>();
|
||||
|
||||
int minH = world.getMinHeight();
|
||||
int maxH = world.getMaxHeight();
|
||||
|
||||
for (ChunkSnapshot snap : snapshots) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = minH; y < maxH; y++) {
|
||||
|
||||
|
||||
BlockData data = snap.getBlockData(x, y, z);
|
||||
Material type = data.getMaterial();
|
||||
|
||||
if (isSupported(type, data)) {
|
||||
counts.put(type, counts.getOrDefault(type, 0L) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<Map.Entry<Material, Long>> sortedList = new ArrayList<>(counts.entrySet());
|
||||
sortedList.sort(Map.Entry.comparingByValue());
|
||||
|
||||
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.accept(sortedList);
|
||||
}
|
||||
}.runTask(BlockAndSeek.getInstance());
|
||||
}
|
||||
}.runTaskAsynchronously(BlockAndSeek.getInstance());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
58
src/main/java/hdvtdev/blockandseek/CommandBuilder.java
Normal file
58
src/main/java/hdvtdev/blockandseek/CommandBuilder.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CommandBuilder {
|
||||
|
||||
private final List<Node> forest = new ArrayList<>();
|
||||
|
||||
public Node addNode(String name) {
|
||||
Node node = new Node(name);
|
||||
forest.add(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String tryGet(String fullPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static void printTree(Node node, String indent) {
|
||||
System.out.println(indent + "- " + node.getName());
|
||||
for (Node child : node.getChildren()) {
|
||||
printTree(child, indent + " ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Node {
|
||||
private final String name;
|
||||
private final List<Node> children;
|
||||
|
||||
public Node(String name) {
|
||||
this.name = name;
|
||||
this.children = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addChild(Node child) {
|
||||
this.children.add(child);
|
||||
}
|
||||
|
||||
public List<Node> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/main/java/hdvtdev/blockandseek/CommandListener.java
Normal file
21
src/main/java/hdvtdev/blockandseek/CommandListener.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CommandListener implements TabExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
80
src/main/java/hdvtdev/blockandseek/Config.java
Normal file
80
src/main/java/hdvtdev/blockandseek/Config.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
import eu.okaeri.configs.ConfigManager;
|
||||
import eu.okaeri.configs.OkaeriConfig;
|
||||
import eu.okaeri.configs.annotation.Comment;
|
||||
import eu.okaeri.configs.annotation.Exclude;
|
||||
import eu.okaeri.configs.serdes.commons.SerdesCommons;
|
||||
import eu.okaeri.configs.yaml.bukkit.YamlBukkitConfigurer;
|
||||
import eu.okaeri.configs.yaml.bukkit.serdes.SerdesBukkit;
|
||||
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.WorldCreator;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class Config extends OkaeriConfig {
|
||||
|
||||
@Exclude
|
||||
private static final AtomicReference<Config> config = new AtomicReference<>(new Config());
|
||||
|
||||
@Comment("Server options.")
|
||||
private Server server = new Server(false);
|
||||
@Comment("Spawn location. Useless if the Server.forceControl is false.")
|
||||
private Location spawn = Objects.requireNonNull(Bukkit.createWorld(new WorldCreator("world"))).getSpawnLocation();
|
||||
@Comment("Show hidden BlockAndSeek commands.")
|
||||
private boolean enableDebugCommands = false;
|
||||
|
||||
|
||||
public static boolean debugEnabled() {
|
||||
return config.get().enableDebugCommands;
|
||||
}
|
||||
|
||||
public static boolean forceControl() {
|
||||
return config.get().server.forceControl;
|
||||
}
|
||||
|
||||
public static Location spawn() {
|
||||
return config.get().spawn;
|
||||
}
|
||||
|
||||
|
||||
public static boolean loadConfig() {
|
||||
try {
|
||||
Config conf = ConfigManager.create(Config.class, (it) -> {
|
||||
it.withConfigurer(
|
||||
new YamlBukkitConfigurer(),
|
||||
new SerdesBukkit(),
|
||||
new SerdesCommons()
|
||||
);
|
||||
it.withBindFile(new File(BlockAndSeek.getPluginDataFolder(), "config.yml"));
|
||||
it.withLogger(BlockAndSeek.getPluginLogger());
|
||||
it.saveDefaults();
|
||||
});
|
||||
|
||||
config.setRelease(conf);
|
||||
} catch (Exception e) {
|
||||
BlockAndSeek.getPluginLogger().severe("Failed to load config.yml: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class Server {
|
||||
|
||||
private boolean forceControl = false;
|
||||
|
||||
public Server(boolean forceControl) {
|
||||
this.forceControl = forceControl;
|
||||
}
|
||||
|
||||
public boolean isForceControl() {
|
||||
return forceControl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
12
src/main/java/hdvtdev/blockandseek/GuiHolder.java
Normal file
12
src/main/java/hdvtdev/blockandseek/GuiHolder.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
public interface GuiHolder extends InventoryHolder {
|
||||
void onClick(InventoryClickEvent event);
|
||||
default void showInventory(Player player) {
|
||||
player.openInventory(getInventory());
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,10 @@ public class Keys {
|
||||
public static final NamespacedKey HIDER = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekHider");
|
||||
public static final NamespacedKey SEEKER = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekSeeker");
|
||||
|
||||
public static final NamespacedKey LANG_KEY = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekLangKey");
|
||||
|
||||
|
||||
|
||||
public static final Team NO_COLLIDE_TEAM;
|
||||
|
||||
static {
|
||||
83
src/main/java/hdvtdev/blockandseek/Localization.java
Normal file
83
src/main/java/hdvtdev/blockandseek/Localization.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public final class Localization {
|
||||
|
||||
private Localization() {}
|
||||
|
||||
private static final String defaultLanguage = "en_US";
|
||||
private static final MiniMessage mm = MiniMessage.miniMessage();
|
||||
|
||||
private static final AtomicReference<Map<String, Map<String, String>>> translations = new AtomicReference<>();
|
||||
|
||||
public static Component get(Player player, String key, String... placeholders) {
|
||||
return get(player.locale().toString(), key, placeholders);
|
||||
}
|
||||
|
||||
public static Component get(String lang, String key, String... placeholders) {
|
||||
String raw = translations.get().get(lang).getOrDefault(key, "?" + key + "?");
|
||||
if (placeholders.length % 2 == 0) {
|
||||
for (int i = 0; i < placeholders.length; i++) {
|
||||
raw = raw.replace(placeholders[i], placeholders[++i]);
|
||||
}
|
||||
} else BlockAndSeek.getPluginLogger().warning("Wrong amount of placeholders for key: " + key);
|
||||
|
||||
return mm.deserialize(raw);
|
||||
}
|
||||
|
||||
public static ItemStack translateItem(Player player, ItemStack itemStack, String key) {
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
itemMeta.displayName(get(player, key));
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public static boolean loadTranslations() {
|
||||
/*
|
||||
Path path = BlockAndSeek.getPluginDataFolder().toPath().resolve("translations");
|
||||
if (Files.notExists(path)) {
|
||||
try {
|
||||
Files.createDirectories(path);
|
||||
} catch (IOException e) {
|
||||
BlockAndSeek.getPluginLogger().severe("Failed to create \"translations\" dir: " + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
File[] files = path.toFile().listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
String lang = file.getName().split(".toml")[0];
|
||||
Map<String, String> translation = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : new Toml().read(file).entrySet()) {
|
||||
translation.put(entry.getKey(), entry.getValue().toString());
|
||||
}
|
||||
translations.get().put(lang, translation);
|
||||
}
|
||||
} else {
|
||||
BlockAndSeek.getPluginLogger().severe("Failed to load translations! " + path + " returned null.");
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,20 @@
|
||||
package hdvtdev.blockAndSeek;
|
||||
|
||||
import hdvtdev.blockAndSeek.managers.PropManager;
|
||||
|
||||
import me.libraryaddict.disguise.DisguiseAPI;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
|
||||
|
||||
import me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public final class Utils {
|
||||
|
||||
@@ -28,15 +36,17 @@ public final class Utils {
|
||||
return player.getPersistentDataContainer().has(Keys.GAME);
|
||||
}
|
||||
|
||||
public static void firstDisguise(Player player, ItemStack prop) {
|
||||
DisguiseAPI.disguiseToAll(player, new MiscDisguise(DisguiseType.FALLING_BLOCK, prop));
|
||||
PropManager.addPlayerDisguise(player, prop.getType().createBlockData());
|
||||
}
|
||||
|
||||
public static boolean hasPermsToDamage(Player p1, Player p2) {
|
||||
PersistentDataContainer c1 = p1.getPersistentDataContainer();
|
||||
PersistentDataContainer c2 = p2.getPersistentDataContainer();
|
||||
return (c1.has(Keys.SEEKER) || c1.has(Keys.HIDER)) && (c2.has(Keys.SEEKER) || c2.has(Keys.HIDER));
|
||||
}
|
||||
|
||||
public static void clearPlayer(Player p) {
|
||||
PersistentDataContainer container = p.getPersistentDataContainer();
|
||||
container.remove(Keys.SEEKER);
|
||||
container.remove(Keys.HIDER);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
@@ -58,6 +59,7 @@ public class ForceControlEventListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerDamage(EntityDamageByEntityEvent event) {
|
||||
|
||||
if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) {
|
||||
if (!Utils.hasPermsToDamage(damager, victim)) {
|
||||
event.setCancelled(true);
|
||||
@@ -65,5 +67,14 @@ public class ForceControlEventListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onFallDamage(EntityDamageEvent e) {
|
||||
if (e.getEntity() instanceof Player) {
|
||||
if (e.getCause() == EntityDamageEvent.DamageCause.FALL) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package hdvtdev.blockAndSeek.eventListeners;
|
||||
|
||||
import hdvtdev.blockAndSeek.Keys;
|
||||
import hdvtdev.blockAndSeek.Utils;
|
||||
import hdvtdev.blockAndSeek.GuiHolder;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDismountEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
|
||||
import static hdvtdev.blockAndSeek.Utils.isInOneTeam;
|
||||
|
||||
public class RequiredEventListener implements Listener {
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockDamage(BlockDamageEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRightClick(PlayerInteractEvent event) {
|
||||
if (event.getHand() != EquipmentSlot.HAND) return;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityDismount(EntityDismountEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClose(InventoryCloseEvent event) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent e) {
|
||||
if (e.getInventory().getHolder() instanceof GuiHolder gui) {
|
||||
e.setCancelled(true);
|
||||
gui.onClick(e);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRegainHealth(EntityRegainHealthEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerDamage(EntityDamageByEntityEvent event) {
|
||||
if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) {
|
||||
if (isInOneTeam(damager, victim)) {
|
||||
event.setCancelled(true);
|
||||
} else if (victim.getPersistentDataContainer().has(Keys.SEEKER)) {
|
||||
event.setDamage(0);
|
||||
} else if (damager.getPersistentDataContainer().has(Keys.SEEKER)) {
|
||||
double maxHealth = 20.0;
|
||||
double currentHealth = damager.getHealth();
|
||||
if (currentHealth < maxHealth) {
|
||||
double newHealth = Math.min(currentHealth + event.getDamage(), maxHealth);
|
||||
damager.setHealth(newHealth);
|
||||
Utils.setLevelWithBar(damager, (int) Math.round(damager.getHealth() * 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package hdvtdev.blockAndSeek.managers;
|
||||
|
||||
import hdvtdev.blockAndSeek.BlockAndSeek;
|
||||
import hdvtdev.blockAndSeek.BlockAndSeekGame;
|
||||
import hdvtdev.blockAndSeek.BlockAndSeekMap;
|
||||
import hdvtdev.blockAndSeek.objects.BlockAndSeekGame;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -32,16 +30,7 @@ public class GamesManager {
|
||||
public static @Nullable String createGame(String name) {
|
||||
if (games.containsKey(name)) return name; //TODO use copy or create copy
|
||||
|
||||
if (Bukkit.getWorld(name) == null) {
|
||||
if (new File(BlockAndSeek.getServerDataFolder(), name).exists()) {
|
||||
Bukkit.createWorld(new WorldCreator(name));
|
||||
} else return null;
|
||||
}
|
||||
|
||||
BlockAndSeekMap map = MapsManager.getMap(name);
|
||||
BlockAndSeekGame game = new BlockAndSeekGame(name, map);
|
||||
|
||||
games.put(name, game);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -34,41 +34,34 @@ public class ItemManager {
|
||||
static {
|
||||
|
||||
ItemMeta freezeMeta = freezeItem.getItemMeta();
|
||||
freezeMeta.displayName(Component.text("freeze-item"));
|
||||
freezeMeta.getPersistentDataContainer().set(Keys.FREEZE_ITEM, PersistentDataType.BOOLEAN, true);
|
||||
freezeItem.setItemMeta(freezeMeta);
|
||||
|
||||
ItemMeta faceChangingMeta = faceChangingItem.getItemMeta();
|
||||
faceChangingMeta.displayName(Component.text("face-changing-item"));
|
||||
faceChangingMeta.getPersistentDataContainer().set(Keys.FACE_CHANGING_ITEM, PersistentDataType.BOOLEAN, true);
|
||||
faceChangingItem.setItemMeta(faceChangingMeta);
|
||||
|
||||
ItemMeta swordMeta = seekerSword.getItemMeta();
|
||||
swordMeta.displayName(Component.text("seeker-sword"));
|
||||
swordMeta.addEnchant(Enchantment.DAMAGE_ALL, 2, false);
|
||||
swordMeta.setUnbreakable(true);
|
||||
swordMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_ATTRIBUTES);
|
||||
seekerSword.setItemMeta(swordMeta);
|
||||
|
||||
ItemMeta menuMeta = menuItem.getItemMeta();
|
||||
menuMeta.displayName(Component.text("menu-item"));
|
||||
menuMeta.getPersistentDataContainer().set(Keys.MENU_ITEM, PersistentDataType.BOOLEAN, true);
|
||||
menuMeta.addEnchant(Enchantment.ARROW_INFINITE, 1, true);
|
||||
menuMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
menuItem.setItemMeta(menuMeta);
|
||||
|
||||
ItemMeta gamesMeta = games.getItemMeta();
|
||||
gamesMeta.displayName(Component.text("games-page-item"));
|
||||
gamesMeta.getPersistentDataContainer().set(Keys.GAME_PAGE, PersistentDataType.BOOLEAN, true);
|
||||
games.setItemMeta(gamesMeta);
|
||||
|
||||
ItemMeta leaveMeta = leaveItem.getItemMeta();
|
||||
leaveMeta.displayName(Component.text("leave-item"));
|
||||
leaveMeta.getPersistentDataContainer().set(Keys.LEAVE_ITEM, PersistentDataType.BOOLEAN, true);
|
||||
leaveItem.setItemMeta(leaveMeta);
|
||||
|
||||
ItemMeta createGameButtonMeta = createGameButton.getItemMeta();
|
||||
createGameButtonMeta.displayName(Component.text("create-game-item"));
|
||||
createGameButton.setItemMeta(createGameButtonMeta);
|
||||
|
||||
|
||||
@@ -82,12 +75,12 @@ public class ItemManager {
|
||||
public static void setSeekerSet(Player seeker) {
|
||||
PlayerInventory inventory = seeker.getInventory();
|
||||
inventory.clear();
|
||||
inventory.addItem(Localization.translateItem(seeker, seekerSword));
|
||||
inventory.addItem(Localization.translateItem(seeker, seekerSword, "seeker_sword"));
|
||||
ItemStack[] armor = new ItemStack[]{
|
||||
Localization.translateItem(seeker, seekerBoots),
|
||||
Localization.translateItem(seeker, seekerLeggings),
|
||||
Localization.translateItem(seeker, seekerChestplate),
|
||||
Localization.translateItem(seeker, seekerHelmet)
|
||||
Localization.translateItem(seeker, seekerBoots, "seeker_boots"),
|
||||
Localization.translateItem(seeker, seekerLeggings, "seeker_leggings"),
|
||||
Localization.translateItem(seeker, seekerChestplate, "seeker_chestplate"),
|
||||
Localization.translateItem(seeker, seekerHelmet, "seeker_helmet")
|
||||
};
|
||||
inventory.setArmorContents(armor);
|
||||
|
||||
@@ -109,11 +102,11 @@ public class ItemManager {
|
||||
public static void defaultInventory(Player player) {
|
||||
PlayerInventory inventory = player.getInventory();
|
||||
inventory.clear();
|
||||
inventory.addItem(Localization.translateItem(player, menuItem));
|
||||
inventory.addItem(Localization.translateItem(player, menuItem, "menu_item"));
|
||||
}
|
||||
|
||||
public static ItemStack getFaceChangingItem() {
|
||||
return faceChangingItem;
|
||||
public static void giveFaceChangingItem(Player player) {
|
||||
player.getInventory().addItem(Localization.translateItem(player, faceChangingItem, "face_changing_item"));
|
||||
}
|
||||
|
||||
public static ItemStack getLeaveItem() {
|
||||
54
src/main/java/hdvtdev/blockandseek/managers/MapsManager.java
Normal file
54
src/main/java/hdvtdev/blockandseek/managers/MapsManager.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package hdvtdev.blockAndSeek.managers;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public final class MapsManager {
|
||||
|
||||
private MapsManager() {
|
||||
}
|
||||
|
||||
public static SuggestionProvider<CommandSender> worldSuggestions = (context, input) ->
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
List<Suggestion> suggestions = new ArrayList<>();
|
||||
|
||||
File container = Bukkit.getWorldContainer();
|
||||
|
||||
File[] files = container.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isDirectory() && new File(file, "level.dat").exists()) {
|
||||
suggestions.add(Suggestion.suggestion(file.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return suggestions;
|
||||
});
|
||||
|
||||
public static SuggestionProvider<CommandSender> mapSuggestions = (context, input) ->
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
List<Suggestion> suggestions = new ArrayList<>();
|
||||
|
||||
File container = new File(Bukkit.getPluginsFolder(), "maps");
|
||||
|
||||
File[] files = container.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
String name = file.getName();
|
||||
if (file.isFile() && name.endsWith(".toml")) {
|
||||
suggestions.add(Suggestion.suggestion(name.replace(".toml", ""))); //baddd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return suggestions;
|
||||
});
|
||||
}
|
||||
76
src/main/java/hdvtdev/blockandseek/managers/PropManager.java
Normal file
76
src/main/java/hdvtdev/blockandseek/managers/PropManager.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package hdvtdev.blockAndSeek.managers;
|
||||
|
||||
import hdvtdev.blockAndSeek.BlockAndSeek;
|
||||
import me.libraryaddict.disguise.DisguiseAPI;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class PropManager {
|
||||
|
||||
private final Map<UUID, PropData> players = new HashMap<>();
|
||||
|
||||
public PropState freezeOrUnfreeze(Player player) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
PropData propData = players.remove(uuid);
|
||||
Location location = player.getLocation();
|
||||
|
||||
Block originalBlock = location.getBlock();
|
||||
|
||||
if (propData != null) {
|
||||
|
||||
originalBlock.setBlockData(propData.blockData);
|
||||
|
||||
} else {
|
||||
|
||||
BlockData originalBlockData = originalBlock.getBlockData();
|
||||
BlockData disguiseBlockData = getPlayerDisguiseData(player);
|
||||
|
||||
|
||||
players.put(uuid, new PropData(null, originalBlockData, null));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return PropState.FAILED;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static BlockData getPlayerDisguiseData(Player player) {
|
||||
Disguise disguise = DisguiseAPI.getDisguise(player);
|
||||
if (disguise instanceof MiscDisguise miscDisguise && miscDisguise.getType() == DisguiseType.FALLING_BLOCK) {
|
||||
FallingBlockWatcher watcher = (FallingBlockWatcher) miscDisguise.getWatcher();
|
||||
return watcher.getBlockData();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public enum PropState {
|
||||
FROZEN,
|
||||
UNFROZEN,
|
||||
FAILED
|
||||
}
|
||||
|
||||
private record PropData(ArmorStand armorStand, BlockData blockData, Disguise disguise) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package hdvtdev.blockAndSeek.managers;
|
||||
|
||||
import hdvtdev.blockAndSeek.objects.BlockAndSeekGame;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class StateManager {
|
||||
|
||||
private final Map<UUID, BlockAndSeekGame.PlayerType> playerToState = new HashMap<>();
|
||||
private final Map<BlockAndSeekGame.PlayerType, Set<UUID>> stateToPlayers = new HashMap<>();
|
||||
|
||||
|
||||
public void setPlayerState(UUID uuid, BlockAndSeekGame.PlayerType newState) {
|
||||
|
||||
BlockAndSeekGame.PlayerType oldState = playerToState.get(uuid);
|
||||
if (oldState != null && oldState.equals(newState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldState != null) {
|
||||
removeUuidFromStateSet(oldState, uuid);
|
||||
}
|
||||
|
||||
playerToState.put(uuid, newState);
|
||||
|
||||
stateToPlayers.computeIfAbsent(newState, k -> new HashSet<>()).add(uuid);
|
||||
}
|
||||
|
||||
public int playerCount() {
|
||||
return playerToState.size();
|
||||
}
|
||||
|
||||
public BlockAndSeekGame.PlayerType getState(UUID uuid) {
|
||||
return playerToState.get(uuid);
|
||||
}
|
||||
|
||||
public Set<UUID> getPlayersInState(BlockAndSeekGame.PlayerType state) {
|
||||
return Collections.unmodifiableSet(stateToPlayers.getOrDefault(state, Collections.emptySet()));
|
||||
}
|
||||
|
||||
public void removePlayer(UUID uuid) {
|
||||
BlockAndSeekGame.PlayerType oldState = playerToState.remove(uuid);
|
||||
if (oldState != null) {
|
||||
removeUuidFromStateSet(oldState, uuid);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeUuidFromStateSet(BlockAndSeekGame.PlayerType state, UUID uuid) {
|
||||
Set<UUID> uuids = stateToPlayers.get(state);
|
||||
if (uuids != null) {
|
||||
uuids.remove(uuid);
|
||||
if (uuids.isEmpty()) {
|
||||
stateToPlayers.remove(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@ package hdvtdev.blockAndSeek.managers;
|
||||
|
||||
|
||||
import hdvtdev.blockAndSeek.BlockAndSeek;
|
||||
|
||||
import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
38
src/main/java/hdvtdev/blockandseek/menus/GamesMenu.java
Normal file
38
src/main/java/hdvtdev/blockandseek/menus/GamesMenu.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package hdvtdev.blockAndSeek.menus;
|
||||
|
||||
import hdvtdev.blockAndSeek.Localization;
|
||||
import hdvtdev.blockAndSeek.GuiHolder;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class GamesMenu implements GuiHolder {
|
||||
|
||||
|
||||
private final Inventory inventory;
|
||||
|
||||
public GamesMenu(Player player) {
|
||||
Component title = Localization.get(player, "games_menu");
|
||||
this.inventory = Bukkit.createInventory(this, 54, title);
|
||||
initInventory();
|
||||
}
|
||||
|
||||
private void initInventory() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(InventoryClickEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package hdvtdev.blockAndSeek.objects;
|
||||
|
||||
import hdvtdev.blockAndSeek.managers.StateManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BlockAndSeekGame {
|
||||
|
||||
private final BlockAndSeekMap map;
|
||||
private final World world;
|
||||
private final StateManager stateManager = new StateManager();
|
||||
|
||||
public BlockAndSeekGame(BlockAndSeekMap blockAndSeekMap) {
|
||||
this.map = blockAndSeekMap;
|
||||
this.world = Objects.requireNonNull(Bukkit.getWorld(blockAndSeekMap.world()));
|
||||
}
|
||||
|
||||
public boolean addPlayer(Player player) {
|
||||
if (stateManager.playerCount() < map.maxPlayers()) {
|
||||
stateManager.setPlayerState(player.getUniqueId(), PlayerType.NONE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removePlayer(Player player) {
|
||||
stateManager.removePlayer(player.getUniqueId());
|
||||
}
|
||||
|
||||
public enum PlayerType {
|
||||
NONE,
|
||||
PROP,
|
||||
SEEKER,
|
||||
SPECTATOR
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package hdvtdev.blockAndSeek.objects;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
public record BlockAndSeekMap(String world, Cords spawn, Cords lobby,
|
||||
int minPlayers, int maxPlayers, int duration, int seekerSpawnDelay, int delayBeforeEnd) {
|
||||
|
||||
public static void prepareWorld(World world) {
|
||||
if (Integer.parseInt(Bukkit.getMinecraftVersion().replaceAll("[^0-9]", "")) >= 1215) {
|
||||
String cmd = "execute in " + world.getKey() + " run gamerule locatorBar true";
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package hdvtdev.blockandseek.objects;
|
||||
|
||||
public interface GamePhase {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package hdvtdev.blockAndSeek.objects;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public record PropBlock(ItemStack block, int chance) {
|
||||
public PropBlock(ItemStack block, Rarity rarity) {
|
||||
this(block, rarity.toChance());
|
||||
}
|
||||
}
|
||||
23
src/main/java/hdvtdev/blockandseek/objects/Rarity.java
Normal file
23
src/main/java/hdvtdev/blockandseek/objects/Rarity.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package hdvtdev.blockAndSeek.objects;
|
||||
|
||||
public enum Rarity {
|
||||
|
||||
COMMON,// 38%
|
||||
UNCOMMON,// 27%
|
||||
RARE,// 19%
|
||||
EPIC,// 10%
|
||||
MYTHIC,// 4%
|
||||
LEGENDARY; // 2%
|
||||
|
||||
public int toChance() {
|
||||
return switch (this.ordinal()) {
|
||||
case 1 -> 27;
|
||||
case 2 -> 19;
|
||||
case 3 -> 10;
|
||||
case 4 -> 4;
|
||||
case 5 -> 2;
|
||||
default -> 38;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
package hdvtdev.blockAndSeek.roulette;
|
||||
|
||||
import hdvtdev.blockAndSeek.BlockAndSeek;
|
||||
import hdvtdev.blockAndSeek.BlockAndSeekMap;
|
||||
import hdvtdev.blockAndSeek.Localization;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -18,7 +15,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/*
|
||||
public final class RouletteCreator implements InventoryHolder {
|
||||
|
||||
|
||||
@@ -167,3 +164,6 @@ public final class RouletteCreator implements InventoryHolder {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
@@ -1,12 +1,11 @@
|
||||
package hdvtdev.blockAndSeek.roulette;
|
||||
|
||||
import com.lewdev.probabilitylib.ProbabilityCollection;
|
||||
import hdvtdev.blockAndSeek.BlockAndSeekMap;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
public class RouletteGenerator {
|
||||
|
||||
private final ProbabilityCollection<ItemStack> probabilityCollection = new ProbabilityCollection<>();
|
||||
@@ -25,3 +24,5 @@ public class RouletteGenerator {
|
||||
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -1,5 +1,7 @@
|
||||
package hdvtdev.blockAndSeek.roulette;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -7,7 +9,7 @@ public class RouletteList<T> {
|
||||
private final List<T> items;
|
||||
private int currentIndex;
|
||||
|
||||
public RouletteList(List<T> items) {
|
||||
public RouletteList(@NotNull List<T> items) {
|
||||
this.items = Objects.requireNonNull(items);
|
||||
this.currentIndex = 0;
|
||||
if (items.isEmpty()) {
|
||||
@@ -1,19 +0,0 @@
|
||||
config:
|
||||
==: hdvtdev.blockAndSeek.Config # <-- DO NOT CHANGE THIS FIELD!!!
|
||||
# A place to teleport players to after the game is over
|
||||
# Example:
|
||||
# default-spawn:
|
||||
# - world: "your world"
|
||||
# location:
|
||||
# - 0 #x
|
||||
# - 60 #y
|
||||
# - 0 #z
|
||||
default-spawn: { }
|
||||
|
||||
# If force-control set to true plugin will control typical aspects such as
|
||||
# disabling breaking blocks, disabling damage in lobbies, etc.
|
||||
# WARN: DO NOT USE THIS WITH OTHER PLUGINS THAT PROVIDE SIMILAR FUNCTIONALITY
|
||||
force-control: false
|
||||
|
||||
# planned
|
||||
# auto-update: false
|
||||
0
src/main/resources/languages/en_US.yml
Normal file
0
src/main/resources/languages/en_US.yml
Normal file
@@ -1,40 +0,0 @@
|
||||
en-US:
|
||||
#Maps
|
||||
maps-available: "<gold>Available maps: <white>"
|
||||
maps-available-element: "- {color-status}{map}<white>"
|
||||
map-lobby-sidebar: "<bold><gradient:#FFFF00:#FFD700:#FFA500>{map}"
|
||||
|
||||
not-enough-permissions: "<red><bold>You do not have permission to run this command."
|
||||
not-enough-arguments: "<red><bold>Too few arguments to run command {command}. Arguments example: {help}"
|
||||
|
||||
successful-reload: "<green>Successfully reloaded <yellow><u>{config}<green>."
|
||||
failed-reload: "<red>Failed to reload <yellow><u>{config}<red>. Error: {e}"
|
||||
|
||||
seekers-won: "<bold><yellow>Seekers <red>won!"
|
||||
hiders-won: "<bold><yellow>Hiders <green>won!"
|
||||
hiders-solo-win: "<bold><yellow>{hider} <green>won this game!"
|
||||
hider-was-found: "<yellow><bold>{hider}<reset><gold> was found by <red><bold>{seeker}"
|
||||
hider-died: "<yellow><bold>{hider}<reset><gold> somehow died xd"
|
||||
|
||||
game-time-left: "<gold>Time left: <yellow>{time}<gold>s"
|
||||
game-players-count: "<yellow>{players} <gold>of <yellow>{max-players}"
|
||||
player-join: "<yellow><bold>{player} <reset><gold>joined. <yellow><bold>{players}"
|
||||
player-leave: "<yellow><bold>{player} <reset><gold>leaved. <yellow><bold>{players}"
|
||||
game-title: "<bold><gold>{title}"
|
||||
|
||||
wait-time-left: "<gold>Game starts in: <yellow><bold>{time}s"
|
||||
|
||||
#items
|
||||
freeze-item: "<gradient:#084CFB:#ADF3FD><bold>Freeze"
|
||||
seeker-armor: "<gradient:#8B0000:#B22222:#DC143C><bold>Seeker armor"
|
||||
|
||||
menu-item: "<gradient:#FFD700:#FFF200:#FFFF00><bold>BlockAndSeek Menu"
|
||||
games-page-item: "<gradient:#006400:#228B22:#00FF7F><bold>Games"
|
||||
|
||||
create-game-item: "<green><bold>Create new game"
|
||||
game-name: "<green>{name}"
|
||||
game-player-count: "<yellow>{players}<gold> of <yellow>{max-players}<gold> players"
|
||||
leave-item: "<red>Leave game"
|
||||
|
||||
roulette-title: "<bold><gold>Props Roulette"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# DO NOT edit this file manually! Use plugin commands to edit maps instead.
|
||||
Reference in New Issue
Block a user