idk some "cool" stuff

This commit is contained in:
hdvt
2025-06-28 00:36:06 +03:00
parent 54eb07cc86
commit e63ac83c17
17 changed files with 499 additions and 312 deletions

View File

@@ -0,0 +1,277 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import hdvtdev.blockAndSeek.Localization;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class ConfigManager {
private static volatile Map<String, Map<String, String>> localization;
private static volatile Map<String, String> config;
private static Map<String, BlockAndSeekMap> maps = new ConcurrentHashMap<>();
private static final File mapsFile = new File(BlockAndSeek.getPluginDataFolder(), "maps.yml");
public static BlockAndSeekMap getMap(String name) {
return maps.get(name);
}
public static Set<String> getAllMaps() {
return YamlConfiguration.loadConfiguration(mapsFile).getKeys(false);
}
public enum MapStatus {
SPAWN_REQUIRED,
LOBBY_REQUIRED,
DURATION_REQUIRED,
BLOCKS_REQUIRED,
MIN_PLAYERS_REQUIRED,
MAX_PLAYERS_REQUIRED
}
public static Set<String> getReadyMaps() {
return maps.keySet();
}
public static @Nullable Set<MapStatus> checkMap(String name) {
Set<MapStatus> status = new HashSet<>();
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(mapsFile);
ConfigurationSection section = configuration.getConfigurationSection(name);
if (section != null) {
List<Integer> spawn = section.getIntegerList("spawn");
if (spawn.size() != 3) status.add(MapStatus.SPAWN_REQUIRED);
List<Integer> lobby = section.getIntegerList("lobby");
if (lobby.size() != 3) status.add(MapStatus.LOBBY_REQUIRED);
int duration = section.getInt("duration");
if (duration <= 0) status.add(MapStatus.DURATION_REQUIRED);
int minPlayers = section.getInt("min-players");
if (minPlayers <= 0) status.add(MapStatus.MIN_PLAYERS_REQUIRED);
int maxPlayers = section.getInt("max-players");
if (maxPlayers <= 0) status.add(MapStatus.MAX_PLAYERS_REQUIRED);
List<BlockAndSeekMap.Block> blocks = section.getMapList("blocks").stream().map(
block -> {
try {
return new BlockAndSeekMap.Block(
new ItemStack(Material.valueOf(((String) block.get("block")).toUpperCase())),
(int) block.get("chance")
);
} catch (IllegalArgumentException | ClassCastException ignored) {
return null;
}
}
).toList();
if (blocks.isEmpty() || new HashSet<>(blocks).size() == 1) status.add(MapStatus.BLOCKS_REQUIRED);
if (status.isEmpty())
maps.put(name, new BlockAndSeekMap(spawn, lobby, duration, minPlayers, maxPlayers, blocks));
} else return null;
return status;
}
public static boolean addDefaultMap(String name) {
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(mapsFile);
if (configuration.get(name) != null) return false;
ConfigurationSection section = configuration.createSection(name);
section.set("spawn", List.of());
section.set("lobby", List.of());
section.set("duration", 0);
section.set("min-players", 0);
section.set("max-players", 0);
section.set("blocks", List.of(Map.of()));
try {
configuration.save(mapsFile);
} catch (IOException ignored) {
return false;
}
return true;
}
public static boolean setMapProperty(String map, String property, Object value) {
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(mapsFile);
ConfigurationSection section = configuration.getConfigurationSection(map);
if (section != null) {
section.set(property, value);
try {
configuration.save(mapsFile);
} catch (IOException e) {
return false;
}
}
return true;
}
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" -> {
Map<String, String> confMap = new HashMap<>();
for (String key : defaultConfiguration.getKeys(false)) {
confMap.put(key, defaultConfiguration.getString(key, "NULL"));
}
config = confMap;
}
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();
}
}
} else {
switch (file) {
case "config.yml" -> loadConfig(conf, defaultConfiguration);
case "localization.yml" -> loadLocalization(conf, defaultConfiguration);
case "maps.yml" -> loadMaps(conf);
}
}
}
private static void loadMaps(File configurationFile) throws IOException {
Map<String, BlockAndSeekMap> confMap = new ConcurrentHashMap<>();
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configurationFile);
for (String map : configuration.getKeys(false)) {
ConfigurationSection section = configuration.getConfigurationSection(map);
if (section != null) {
List<Integer> spawn = section.getIntegerList("spawn");
List<Integer> lobby = section.getIntegerList("lobby");
int duration = section.getInt("duration");
int minPlayers = section.getInt("min-players");
int maxPlayers = section.getInt("max-players");
List<BlockAndSeekMap.Block> blocks = section.getMapList("blocks").stream().map(
block -> {
try {
return new BlockAndSeekMap.Block(
new ItemStack(Material.valueOf(((String) block.get("block")).toUpperCase())),
(int) block.get("chance")
);
} catch (IllegalArgumentException | ClassCastException | NullPointerException ignored) {
return null;
}
}
).filter(Objects::nonNull).toList();
if (!spawn.isEmpty() && !lobby.isEmpty() && duration > 0 && !blocks.isEmpty() && minPlayers > 0 && maxPlayers > 0) {
confMap.put(map, new BlockAndSeekMap(spawn, lobby, duration, minPlayers, maxPlayers, blocks));
}
}
maps = confMap;
}
}
private static void loadConfig(File configurationFile, YamlConfiguration defaultConfiguration) throws IOException {
ConcurrentHashMap<String, String> confMap = new ConcurrentHashMap<>();
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configurationFile);
for (String key : defaultConfiguration.getKeys(false)) {
if (configuration.isSet(key)) {
confMap.put(key, configuration.getString(key, defaultConfiguration.getString(key, "NULL")));
} else {
String value = defaultConfiguration.getString(key, "NULL");
configuration.set(key, value);
confMap.put(key, value);
}
}
configuration.save(configurationFile);
config = confMap;
}
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;
}
public static Map<String, Map<String, String>> getLocalization() {
return localization;
}
}

View File

@@ -0,0 +1,92 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeekContainer;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.disguisetypes.Disguise;
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.Player;
import org.bukkit.util.Vector;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class FreezeManager {
private static final Map<Player, FreezeData> frozenPlayers = new ConcurrentHashMap<>();
private static final Vector velocity = new Vector(0, 0, 0);
public static boolean freeze(Player player, Material material) {
Location location = player.getLocation();
if (frozenPlayers.containsKey(player)) {
FreezeData data = frozenPlayers.remove(player);
Location blockLocation = location.getBlock().getLocation();
for (Player p : Bukkit.getOnlinePlayers()) {
p.sendBlockChange(blockLocation, data.blockData);
}
ArmorStand armorStand = data.armorStand;
armorStand.removePassenger(player);
armorStand.remove();
player.setInvulnerable(false);
BlockAndSeekContainer.NO_COLLIDE_TEAM.removeEntry(player.getName());
if (data.disguise() != null) DisguiseAPI.disguiseToAll(player, data.disguise);
} 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() + 1);
if (!upperBlockLocation.getBlock().isSolid() && !blockLocation.getBlock().isSolid()) {
for (Player p : Bukkit.getOnlinePlayers()) {
p.sendBlockChange(blockLocation, material.createBlockData());
}
centerLocation.setY(centerLocation.getY() - 0.5);
player.setVelocity(velocity);
player.setInvulnerable(true);
BlockAndSeekContainer.NO_COLLIDE_TEAM.addEntry(player.getName());
ArmorStand armorStand = location.getWorld().spawn(centerLocation, ArmorStand.class);
armorStand.setInvulnerable(true);
armorStand.setSmall(true);
armorStand.setGravity(true);
armorStand.setCanMove(false);
armorStand.setInvisible(true);
armorStand.setCollidable(false);
armorStand.addPassenger(player);
Disguise disguise = DisguiseAPI.getDisguise(player);
DisguiseAPI.undisguiseToAll(player);
frozenPlayers.put(player, new FreezeData(armorStand, blockData, disguise));
} else return false;
}
return true;
}
private record FreezeData(ArmorStand armorStand, BlockData blockData, Disguise disguise) {
}
}

View File

@@ -0,0 +1,171 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.BlockAndSeekGame;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import hdvtdev.blockAndSeek.Localization;
import hdvtdev.blockAndSeek.roulette.RouletteCreator;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.WorldCreator;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scoreboard.Criteria;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import java.io.File;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class GamesManager {
private static final ConcurrentHashMap<String, BlockAndSeekGame> games = new ConcurrentHashMap<>();
public static boolean isExist(String name) {
return games.containsKey(name);
}
public static Set<String> getAvailableGames() {
return games.keySet();
}
public static int createGame(String name) {
if (games.containsKey(name)) return 1;
if (Bukkit.getWorld(name) == null) {
if (new File(BlockAndSeek.getServerDataFolder(), name).exists()) {
Bukkit.createWorld(new WorldCreator(name));
} else return 2;
}
BlockAndSeekMap map = ConfigManager.getMap(name);
BlockAndSeekGame game = new BlockAndSeekGame(name, map.maxPlayers());
List<Integer> spawnCords = map.spawn();
List<Integer> lobbyCords = map.lobby();
games.put(name, game);
new BukkitRunnable() {
int duration = map.duration();
int waitTime = 30;
final Location spawn = new Location(Bukkit.getWorld(name), spawnCords.getFirst(), spawnCords.get(1), spawnCords.get(2));
final Location lobby = new Location(Bukkit.getWorld(name), lobbyCords.getFirst(), lobbyCords.get(1), lobbyCords.get(2));
@Override
public void run() {
if (!game.isStarted()) {
int playerCount = game.playerCount();
for (Player player : game.getPlayers()) {
player.sendActionBar(Component.text("Игроков " + playerCount + "/12")); //TODO!
}
if (playerCount >= map.minPlayers()) {
if (waitTime == 0 || playerCount == map.maxPlayers()) {
game.start();
Player seeker = game.selectRandomSeeker();
seeker.teleport(spawn);
for (Player player : game.getHiders()) {
player.teleport(spawn);
RouletteCreator.createRoulette(player, null, true, map.blocks());
}
} else {
if (waitTime < 5 || waitTime % 5 == 0) {
for (Player player : game.getPlayers()) {
player.sendMessage(Localization.getLangComponentWithPrefix(player.locale().toLanguageTag(), "wait-time-left", "{time}", String.valueOf(waitTime)));
}
}
waitTime--;
}
} else waitTime = 10;
} else {
if (game.hidersCount() == 0) {
for (Player player : game.getPlayers()) {
player.showTitle(Title.title(Localization.getComponent("seekers-won"), Component.text("")));
}
game.end();
games.remove(name);
this.cancel();
}
for (Player player : game.getPlayers()) {
player.sendActionBar(Localization.getComponent("game-time-left", "{time}", String.valueOf(duration)));
}
if (duration == 0) {
if (game.hidersCount() == 1) {
for (Player player : game.getPlayers()) {
player.showTitle(Title.title(Localization.getComponent("hiders-solo-win", "{player}", player.getName()), Component.text("")));
}
} else {
for (Player player : game.getPlayers()) {
player.showTitle(Title.title(Localization.getComponent("hiders-won"), Component.text("")));
}
}
game.end();
games.remove(name);
this.cancel();
} else duration--;
}
}
}.runTaskTimer(BlockAndSeek.getInstance(), 0L, 20L);
return 0;
}
public static BlockAndSeekGame get(String name) {
return games.get(name);
}
private static Scoreboard updateScoreboard(Scoreboard scoreboard, int players, int maxPlayers) {
Objective objective = scoreboard.getObjective(DisplaySlot.SIDEBAR);
for (String o : scoreboard.getEntries()) {
scoreboard.resetScores(o);
}
objective.getScore(" ").setScore(3);
objective.getScore(Localization.getComponent("game-players-count", "{players}", String.valueOf(players), "{max-players}", String.valueOf(maxPlayers)).toString()).setScore(2);
objective.getScore(" ").setScore(1);
objective.getScore(Localization.getComponent("wait-time-left", "{time}", String.valueOf(30)).toString()).setScore(0);
return scoreboard;
}
private static Scoreboard newLobbyScoreboard(String name, int players, int maxPlayers) {
Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
Objective objective = scoreboard.registerNewObjective(name, Criteria.DUMMY, Localization.getComponent(" game-title", "{title}", name));
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
objective.getScore(" ").setScore(3);
objective.getScore(Localization.getComponent("game-players-count", "{players}", String.valueOf(players), "{max-players}", String.valueOf(maxPlayers)).toString()).setScore(2);
objective.getScore(" ").setScore(1);
objective.getScore(Localization.getComponent("wait-time-left", "{time}", String.valueOf(30)).toString()).setScore(0);
return scoreboard;
}
}

View File

@@ -0,0 +1,11 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import java.util.Map;
public class MapsManager {
private static final Map<String, BlockAndSeekMap> maps = null;
}