Update from Git Manager GUI
This commit is contained in:
@@ -4,6 +4,7 @@ import io.github.mviper.bomberman.commands.BaseCommand;
|
||||
import io.github.mviper.bomberman.game.GamePlayer;
|
||||
import io.github.mviper.bomberman.game.GameSave;
|
||||
import io.github.mviper.bomberman.game.GameSettings;
|
||||
import io.github.mviper.bomberman.game.JoinSignListener;
|
||||
import io.github.mviper.bomberman.utils.DataRestorer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
@@ -30,7 +31,9 @@ public class Bomberman extends JavaPlugin implements Listener {
|
||||
instance = this;
|
||||
|
||||
ConfigurationSerialization.registerClass(GameSettings.class);
|
||||
ConfigurationSerialization.registerClass(GameSettings.class, "io.github.mdsimmo.bomberman.game.GameSettings");
|
||||
ConfigurationSerialization.registerClass(DataRestorer.class, "io.github.mviper.bomberman.game.Game$BuildFlags");
|
||||
ConfigurationSerialization.registerClass(DataRestorer.class, "io.github.mdsimmo.bomberman.game.Game$BuildFlags");
|
||||
|
||||
getDataFolder().mkdirs();
|
||||
|
||||
@@ -39,9 +42,9 @@ public class Bomberman extends JavaPlugin implements Listener {
|
||||
bukkitBmCmd.setExecutor(bmCmd);
|
||||
bukkitBmCmd.setTabCompleter(bmCmd);
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||
new BmPlaceholder().register();
|
||||
}
|
||||
Bukkit.getPluginManager().registerEvents(new JoinSignListener(), this);
|
||||
|
||||
// Placeholder expansion registration disabled to avoid console startup noise.
|
||||
|
||||
// Update the old file system
|
||||
GameSave.updatePre080Saves();
|
||||
@@ -66,7 +69,9 @@ public class Bomberman extends JavaPlugin implements Listener {
|
||||
|
||||
// Copy resources
|
||||
saveResource("config.yml", true);
|
||||
if (!Files.exists(language())) {
|
||||
saveResource("messages.yml", false);
|
||||
}
|
||||
saveResource("default_messages.yml", true);
|
||||
saveResource("games/templates/purple.game.zip", true);
|
||||
saveResource("games/templates/experimental.game.zip", true);
|
||||
|
||||
@@ -62,11 +62,13 @@ import java.util.regex.Pattern;
|
||||
|
||||
public class Game implements Formattable, Listener {
|
||||
private static final Bomberman PLUGIN = Bomberman.instance;
|
||||
private static final int AUTO_START_DELAY_SECONDS = 3;
|
||||
|
||||
private final GameSave save;
|
||||
public final String name;
|
||||
private final Set<Player> players = new HashSet<>();
|
||||
private boolean running = false;
|
||||
private boolean countingDown = false;
|
||||
private final YamlConfiguration tempData;
|
||||
private Box box;
|
||||
private Set<Location> spawns;
|
||||
@@ -149,6 +151,26 @@ public class Game implements Formattable, Listener {
|
||||
return save.origin;
|
||||
}
|
||||
|
||||
public int getPlayerCount() {
|
||||
return players.size();
|
||||
}
|
||||
|
||||
public int getMaxPlayers() {
|
||||
return getSpawns().size();
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
public boolean isCountingDown() {
|
||||
return countingDown;
|
||||
}
|
||||
|
||||
public boolean contains(Location location) {
|
||||
return location != null && getBox().contains(location);
|
||||
}
|
||||
|
||||
public Clipboard getClipboard() throws IOException {
|
||||
return save.getSchematic();
|
||||
}
|
||||
@@ -193,7 +215,6 @@ public class Game implements Formattable, Listener {
|
||||
}
|
||||
|
||||
private Set<Location> searchSpawns() {
|
||||
PLUGIN.getLogger().info("Searching for spawns...");
|
||||
Set<Location> result = new HashSet<>();
|
||||
try {
|
||||
Clipboard clipboard = getClipboard();
|
||||
@@ -215,7 +236,6 @@ public class Game implements Formattable, Listener {
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to search spawns", e);
|
||||
}
|
||||
PLUGIN.getLogger().info(" " + result.size() + " spawns found");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -326,6 +346,11 @@ public class Game implements Formattable, Listener {
|
||||
|
||||
GamePlayer.spawnGamePlayer(event.player, this, gameSpawn);
|
||||
players.add(event.player);
|
||||
|
||||
if (!running && players.size() > 1) {
|
||||
BmRunStartCountDownIntent.startGame(this, AUTO_START_DELAY_SECONDS, false);
|
||||
}
|
||||
|
||||
event.setHandled();
|
||||
}
|
||||
|
||||
@@ -420,6 +445,7 @@ public class Game implements Formattable, Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
countingDown = true;
|
||||
StartTimer.createTimer(this, event.delay);
|
||||
event.setHandled();
|
||||
}
|
||||
@@ -429,6 +455,7 @@ public class Game implements Formattable, Listener {
|
||||
if (event.game != this) {
|
||||
return;
|
||||
}
|
||||
countingDown = false;
|
||||
running = true;
|
||||
removeCages();
|
||||
GameProtection.protect(this, getBox());
|
||||
@@ -466,6 +493,7 @@ public class Game implements Formattable, Listener {
|
||||
if (event.game != this) {
|
||||
return;
|
||||
}
|
||||
countingDown = false;
|
||||
if (!running) {
|
||||
event.cancelFor(Text.STOP_NOT_STARTED.format(new Context(false).plus("game", this)));
|
||||
}
|
||||
@@ -476,6 +504,7 @@ public class Game implements Formattable, Listener {
|
||||
if (event.game != this) {
|
||||
return;
|
||||
}
|
||||
countingDown = false;
|
||||
if (running) {
|
||||
running = false;
|
||||
BmGameBuildIntent.build(this);
|
||||
|
||||
@@ -281,7 +281,7 @@ public class GamePlayer implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
|
||||
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOW)
|
||||
public void onPlayerBreakBlockWithWrongTool(PlayerInteractEvent event) {
|
||||
if (event.getPlayer() != player) {
|
||||
return;
|
||||
@@ -290,6 +290,12 @@ public class GamePlayer implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldBypassSpawnProtection(event.getClickedBlock() != null ? event.getClickedBlock().getLocation() : null)) {
|
||||
event.setCancelled(false);
|
||||
event.setUseInteractedBlock(Event.Result.ALLOW);
|
||||
event.setUseItemInHand(Event.Result.ALLOW);
|
||||
}
|
||||
|
||||
String key = event.getClickedBlock() != null
|
||||
? event.getClickedBlock().getBlockData().getMaterial().getKey().toString()
|
||||
: null;
|
||||
@@ -310,12 +316,17 @@ public class GamePlayer implements Listener {
|
||||
event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.MINING_FATIGUE, 20, 1));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
|
||||
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOW)
|
||||
public void onPlayerPlaceBlock(BlockPlaceEvent event) {
|
||||
if (event.getPlayer() != player) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldBypassSpawnProtection(event.getBlockPlaced().getLocation())) {
|
||||
event.setCancelled(false);
|
||||
event.setBuild(true);
|
||||
}
|
||||
|
||||
String key = event.getBlockAgainst().getBlockData().getMaterial().getKey().toString();
|
||||
var nbt = BukkitAdapter.adapt(event.getItemInHand()).getNbtData();
|
||||
var list = nbt != null ? nbt.getList("CanPlaceOn", StringTag.class) : null;
|
||||
@@ -327,11 +338,17 @@ public class GamePlayer implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
@EventHandler(ignoreCancelled = false, priority = EventPriority.HIGHEST)
|
||||
public void onPlayerPlaceTNT(BlockPlaceEvent event) {
|
||||
if (event.getPlayer() != player) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldBypassSpawnProtection(event.getBlockPlaced().getLocation())) {
|
||||
event.setCancelled(false);
|
||||
event.setBuild(true);
|
||||
}
|
||||
|
||||
var block = event.getBlock();
|
||||
if (block.getType() == game.getSettings().getBombItem()) {
|
||||
if (!Bomb.spawnBomb(game, player, block)) {
|
||||
@@ -340,6 +357,10 @@ public class GamePlayer implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldBypassSpawnProtection(Location location) {
|
||||
return game.isRunning() && game.contains(location);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
|
||||
public void onPlayerMoved(PlayerMoveEvent event) {
|
||||
if (event.getPlayer() != player) {
|
||||
|
||||
@@ -5,9 +5,12 @@ import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import io.github.mviper.bomberman.Bomberman;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
@@ -96,31 +99,100 @@ public class GameSave {
|
||||
try {
|
||||
loadGame(file);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof IOException) {
|
||||
PLUGIN.getLogger().warning("Skipping save '" + file + "': " + e.getMessage());
|
||||
} else {
|
||||
PLUGIN.getLogger().log(Level.WARNING, "Exception occurred while loading: " + file, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
PLUGIN.getLogger().log(Level.WARNING, "Exception occurred while listing saves", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static GameSave loadSave(Path zipFile) throws IOException {
|
||||
PLUGIN.getLogger().info("Reading " + zipFile);
|
||||
try (FileSystem fs = FileSystems.newFileSystem(zipFile, (ClassLoader) null)) {
|
||||
Path configPath = fs.getPath("config.yml");
|
||||
try (var reader = Files.newBufferedReader(configPath)) {
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(reader);
|
||||
String name = config.getString("name");
|
||||
Location origin = config.getSerializable("origin", Location.class);
|
||||
Object parsed = new Yaml().load(reader);
|
||||
if (!(parsed instanceof Map<?, ?> config)) {
|
||||
throw new IOException("Cannot read 'config.yml' in '" + zipFile + "'");
|
||||
}
|
||||
|
||||
String name = asString(config.get("name"));
|
||||
Location origin = parseLocation(config.get("origin"), zipFile);
|
||||
if (name == null || origin == null) {
|
||||
throw new IOException("Cannot read 'config.yml' in '" + zipFile + "'");
|
||||
}
|
||||
PLUGIN.getLogger().info(" Data read");
|
||||
|
||||
return new GameSave(name, origin, zipFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Location parseLocation(Object source, Path zipFile) throws IOException {
|
||||
if (source instanceof Location location) {
|
||||
return location;
|
||||
}
|
||||
if (!(source instanceof Map<?, ?> map)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String worldName = asString(map.get("world"));
|
||||
if (worldName == null) {
|
||||
throw new IOException("Cannot read world from 'config.yml' in '" + zipFile + "'");
|
||||
}
|
||||
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (world == null) {
|
||||
throw new IOException("Unknown world '" + worldName + "' in '" + zipFile + "'");
|
||||
}
|
||||
|
||||
Double x = asDouble(map.get("x"));
|
||||
Double y = asDouble(map.get("y"));
|
||||
Double z = asDouble(map.get("z"));
|
||||
if (x == null || y == null || z == null) {
|
||||
throw new IOException("Cannot read coordinates from 'config.yml' in '" + zipFile + "'");
|
||||
}
|
||||
|
||||
Float yaw = asFloat(map.get("yaw"));
|
||||
Float pitch = asFloat(map.get("pitch"));
|
||||
return new Location(world, x, y, z, yaw != null ? yaw : 0.0f, pitch != null ? pitch : 0.0f);
|
||||
}
|
||||
|
||||
private static String asString(Object value) {
|
||||
return value instanceof String text ? text : null;
|
||||
}
|
||||
|
||||
private static Double asDouble(Object value) {
|
||||
if (value instanceof Number number) {
|
||||
return number.doubleValue();
|
||||
}
|
||||
if (value instanceof String text) {
|
||||
try {
|
||||
return Double.parseDouble(text);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Float asFloat(Object value) {
|
||||
if (value instanceof Number number) {
|
||||
return number.floatValue();
|
||||
}
|
||||
if (value instanceof String text) {
|
||||
try {
|
||||
return Float.parseFloat(text);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Game loadGame(Path zipFile) throws IOException {
|
||||
return new Game(loadSave(zipFile));
|
||||
}
|
||||
@@ -129,8 +201,6 @@ public class GameSave {
|
||||
try (DirectoryStream<Path> files = Files.newDirectoryStream(PLUGIN.gameSaves(), "*.yml")) {
|
||||
for (Path file : files) {
|
||||
try {
|
||||
PLUGIN.getLogger().info("Updating old save: " + file);
|
||||
|
||||
YamlConfiguration config;
|
||||
try (var reader = Files.newBufferedReader(file)) {
|
||||
config = YamlConfiguration.loadConfiguration(reader);
|
||||
@@ -153,7 +223,6 @@ public class GameSave {
|
||||
settings = builder.build();
|
||||
|
||||
if (name == null || schema == null || origin == null) {
|
||||
PLUGIN.getLogger().info(" Skipping update as file missing data");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -190,14 +259,12 @@ public class GameSave {
|
||||
return cached;
|
||||
}
|
||||
|
||||
PLUGIN.getLogger().info("Reading schematic data: " + zipPath.getFileName());
|
||||
try (FileSystem fs = FileSystems.newFileSystem(zipPath, (ClassLoader) null)) {
|
||||
Path arenaPath = fs.getPath("arena.schem");
|
||||
Clipboard schematic;
|
||||
try (var reader = Files.newInputStream(arenaPath)) {
|
||||
schematic = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getReader(reader).read();
|
||||
}
|
||||
PLUGIN.getLogger().info("Data read");
|
||||
schematicCache = new WeakReference<>(schematic);
|
||||
return schematic;
|
||||
} catch (IOException e) {
|
||||
@@ -213,7 +280,6 @@ public class GameSave {
|
||||
return settingsCache;
|
||||
}
|
||||
|
||||
PLUGIN.getLogger().info("Reading game settings: " + zipPath.getFileName());
|
||||
try (FileSystem fs = FileSystems.newFileSystem(zipPath, (ClassLoader) null)) {
|
||||
Path settingsPath = fs.getPath("settings.yml");
|
||||
try (var reader = Files.newBufferedReader(settingsPath)) {
|
||||
@@ -223,7 +289,6 @@ public class GameSave {
|
||||
settings = new GameSettingsBuilder().build();
|
||||
}
|
||||
settingsCache = settings;
|
||||
PLUGIN.getLogger().info("Data read");
|
||||
return settings;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
package io.github.mviper.bomberman.game;
|
||||
|
||||
import io.github.mviper.bomberman.Bomberman;
|
||||
import io.github.mviper.bomberman.commands.Permissions;
|
||||
import io.github.mviper.bomberman.events.BmGameLookupIntent;
|
||||
import io.github.mviper.bomberman.events.BmPlayerJoinGameIntent;
|
||||
import io.github.mviper.bomberman.messaging.Context;
|
||||
import io.github.mviper.bomberman.messaging.Message;
|
||||
import io.github.mviper.bomberman.messaging.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
public class JoinSignListener implements Listener {
|
||||
private static final Bomberman PLUGIN = Bomberman.instance;
|
||||
private static final long REFRESH_INTERVAL_TICKS = 40L;
|
||||
private static final String HEADER = "[Bomberman]";
|
||||
private static final String SHORT_HEADER = "[bm]";
|
||||
private static final String JOIN_ACTION = "join";
|
||||
|
||||
public JoinSignListener() {
|
||||
Bukkit.getScheduler().runTaskTimer(PLUGIN, this::refreshLoadedSigns, REFRESH_INTERVAL_TICKS, REFRESH_INTERVAL_TICKS);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
|
||||
public void onSignCreate(SignChangeEvent event) {
|
||||
if (!isBombermanHeader(event.getLine(0))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Permissions.CONFIGURE.isAllowedBy(event.getPlayer())) {
|
||||
Text.DENY_PERMISSION.format(new Context(false)).sendTo(event.getPlayer());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
String gameName = extractGameName(event.getLine(1), event.getLine(2));
|
||||
if (gameName.isEmpty()) {
|
||||
Message.error("Join-Schild ungültig. Verwende Zeile 2 oder 3 für den Spielnamen.").sendTo(event.getPlayer());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (BmGameLookupIntent.find(gameName) == null) {
|
||||
Message.error("Spiel '" + gameName + "' wurde nicht gefunden.").sendTo(event.getPlayer());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
applySignFormat(event, gameName);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
|
||||
public void onSignUse(PlayerInteractEvent event) {
|
||||
if (event.getHand() != EquipmentSlot.HAND || event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getClickedBlock() == null) {
|
||||
return;
|
||||
}
|
||||
if (!(event.getClickedBlock().getState() instanceof Sign sign)) {
|
||||
return;
|
||||
}
|
||||
if (!isBombermanHeader(sign.getLine(0))) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (!Permissions.JOIN.isAllowedBy(player)) {
|
||||
Text.DENY_PERMISSION.format(new Context(false)).sendTo(player);
|
||||
return;
|
||||
}
|
||||
|
||||
String gameName = extractGameName(sign.getLine(1), sign.getLine(2));
|
||||
if (gameName.isEmpty()) {
|
||||
Message.error("Dieses Join-Schild ist ungültig.").sendTo(player);
|
||||
return;
|
||||
}
|
||||
|
||||
Game game = BmGameLookupIntent.find(gameName);
|
||||
if (game == null) {
|
||||
Message.error("Spiel '" + gameName + "' wurde nicht gefunden.").sendTo(player);
|
||||
return;
|
||||
}
|
||||
|
||||
var joinEvent = BmPlayerJoinGameIntent.join(game, player);
|
||||
if (joinEvent.isCancelled()) {
|
||||
if (joinEvent.cancelledReason() != null) {
|
||||
joinEvent.cancelledReason().sendTo(player);
|
||||
} else {
|
||||
Text.COMMAND_CANCELLED.format(new Context(false)
|
||||
.plus("game", game)
|
||||
.plus("player", player))
|
||||
.sendTo(player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Text.JOIN_SUCCESS.format(new Context(false)
|
||||
.plus("game", game)
|
||||
.plus("player", player))
|
||||
.sendTo(player);
|
||||
}
|
||||
|
||||
private void refreshLoadedSigns() {
|
||||
for (var world : Bukkit.getWorlds()) {
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
for (var state : chunk.getTileEntities()) {
|
||||
if (state instanceof Sign sign && isBombermanHeader(sign.getLine(0))) {
|
||||
refreshSign(sign);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshSign(Sign sign) {
|
||||
String gameName = extractGameName(sign.getLine(1), sign.getLine(2));
|
||||
if (gameName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Game game = BmGameLookupIntent.find(gameName);
|
||||
if (game == null) {
|
||||
updateSign(sign,
|
||||
ChatColor.DARK_BLUE + HEADER,
|
||||
ChatColor.GOLD + gameName,
|
||||
ChatColor.DARK_RED + "Offline",
|
||||
ChatColor.GRAY + "Spiel fehlt");
|
||||
return;
|
||||
}
|
||||
|
||||
updateSign(sign,
|
||||
ChatColor.DARK_BLUE + HEADER,
|
||||
ChatColor.GOLD + game.getName(),
|
||||
statusLine(game),
|
||||
playersLine(game));
|
||||
}
|
||||
|
||||
private void applySignFormat(SignChangeEvent event, String gameName) {
|
||||
Game game = BmGameLookupIntent.find(gameName);
|
||||
if (game == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setLine(0, ChatColor.DARK_BLUE + HEADER);
|
||||
event.setLine(1, ChatColor.GOLD + game.getName());
|
||||
event.setLine(2, statusLine(game));
|
||||
event.setLine(3, playersLine(game));
|
||||
}
|
||||
|
||||
private void updateSign(Sign sign, String line0, String line1, String line2, String line3) {
|
||||
if (sameLine(sign.getLine(0), line0)
|
||||
&& sameLine(sign.getLine(1), line1)
|
||||
&& sameLine(sign.getLine(2), line2)
|
||||
&& sameLine(sign.getLine(3), line3)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sign.setLine(0, line0);
|
||||
sign.setLine(1, line1);
|
||||
sign.setLine(2, line2);
|
||||
sign.setLine(3, line3);
|
||||
sign.update(true, false);
|
||||
}
|
||||
|
||||
private String statusLine(Game game) {
|
||||
if (game.isRunning()) {
|
||||
return ChatColor.RED + "Läuft";
|
||||
}
|
||||
if (game.isCountingDown()) {
|
||||
return ChatColor.YELLOW + "Startet";
|
||||
}
|
||||
return ChatColor.GREEN + "Wartet";
|
||||
}
|
||||
|
||||
private String playersLine(Game game) {
|
||||
return ChatColor.GRAY + Integer.toString(game.getPlayerCount()) + "/" + game.getMaxPlayers() + " Spieler";
|
||||
}
|
||||
|
||||
private boolean sameLine(String current, String expected) {
|
||||
return normalize(current).equalsIgnoreCase(normalize(expected));
|
||||
}
|
||||
|
||||
private static boolean isBombermanHeader(String value) {
|
||||
String normalized = normalize(value);
|
||||
return HEADER.equalsIgnoreCase(normalized) || SHORT_HEADER.equalsIgnoreCase(normalized);
|
||||
}
|
||||
|
||||
private static String extractGameName(String secondLine, String thirdLine) {
|
||||
String lineTwo = normalize(secondLine);
|
||||
String lineThree = normalize(thirdLine);
|
||||
if (JOIN_ACTION.equalsIgnoreCase(lineTwo)) {
|
||||
return lineThree;
|
||||
}
|
||||
return lineTwo;
|
||||
}
|
||||
|
||||
private static String normalize(String value) {
|
||||
return value == null ? "" : ChatColor.stripColor(value).trim();
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
# BOMBERMAN CONFIG #
|
||||
# #
|
||||
# Refer to the Bomberman Wiki for help on configuration: #
|
||||
# https://github.com/mviper/bomberman/wiki #
|
||||
# https://git.viper.ipv64.net/M_Viper/Bombermann #
|
||||
# #
|
||||
# There is nothing to configure in this file. All configuration #
|
||||
# is done on a per-game basis. #
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# You can overwrite anything by setting the value in messages.yml #
|
||||
# #
|
||||
# Refer to the Bomberman wiki for help on configuring messages: #
|
||||
# https://github.com/mviper/bomberman/wiki/Localisation #
|
||||
# https://git.viper.ipv64.net/M_Viper/Bombermann #
|
||||
# #
|
||||
# This file is automatically generated and will be reset on next #
|
||||
# server reload. #
|
||||
|
||||
@@ -5,7 +5,7 @@ api-version: 1.21
|
||||
load: POSTWORLD
|
||||
|
||||
author: M_Viper
|
||||
website: https://github.com/mviper/bomberman
|
||||
website: https://git.viper.ipv64.net/M_Viper/Bombermann
|
||||
|
||||
commands:
|
||||
bomberman:
|
||||
|
||||
Reference in New Issue
Block a user