summaryrefslogtreewikicommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/Main.java62
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/command/Confirm.java62
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/command/world/Create.java66
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/command/world/Delete.java74
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/command/world/List.java46
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/command/world/Tp.java49
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java4
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/configuration/Maps.java2
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/database/Database.java2
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java8
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/util/Location.java22
-rw-r--r--src/main/java/net/tylermurphy/hideAndSeek/world/WorldLoader.java2
-rw-r--r--src/main/resources/lang/localization_en-US.yml14
-rw-r--r--src/main/resources/plugin.yml10
14 files changed, 416 insertions, 7 deletions
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/Main.java b/src/main/java/net/tylermurphy/hideAndSeek/Main.java
index 12e4bf4..656f60d 100644
--- a/src/main/java/net/tylermurphy/hideAndSeek/Main.java
+++ b/src/main/java/net/tylermurphy/hideAndSeek/Main.java
@@ -23,6 +23,9 @@ import net.tylermurphy.hideAndSeek.command.*;
import net.tylermurphy.hideAndSeek.command.map.*;
import net.tylermurphy.hideAndSeek.command.map.blockhunt.Enabled;
import net.tylermurphy.hideAndSeek.command.map.set.*;
+import net.tylermurphy.hideAndSeek.command.world.Create;
+import net.tylermurphy.hideAndSeek.command.world.Delete;
+import net.tylermurphy.hideAndSeek.command.world.Tp;
import net.tylermurphy.hideAndSeek.configuration.*;
import net.tylermurphy.hideAndSeek.database.Database;
import net.tylermurphy.hideAndSeek.game.*;
@@ -39,6 +42,7 @@ import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -56,16 +60,28 @@ public class Main extends JavaPlugin implements Listener {
private EntityHider entityHider;
private Game game;
private CommandGroup commandGroup;
+ private boolean loaded;
public void onEnable() {
+
+ long start = System.currentTimeMillis();
+
+ getLogger().info("Loading Kenshin's Hide and Seek");
Main.instance = this;
- this.updateVersion();
+
+ getLogger().info("Getting minecraft version...");
+ this.updateVersion();;
try {
+ getLogger().info("Loading config.yml...");
Config.loadConfig();
+ getLogger().info("Loading maps.yml...");
Maps.loadMaps();
+ getLogger().info("Loading localization.yml...");
Localization.loadLocalization();
+ getLogger().info("Loading items.yml...");
Items.loadItems();
+ getLogger().info("Loading leaderboard.yml...");
Leaderboard.loadLeaderboard();
} catch (Exception e) {
getLogger().severe(e.getMessage());
@@ -73,12 +89,18 @@ public class Main extends JavaPlugin implements Listener {
return;
}
+ getLogger().info("Creating internal scoreboard...");
this.board = new Board();
+ getLogger().info("Connecting to database...");
this.database = new Database();
+ getLogger().info("Loading disguises...");
this.disguiser = new Disguiser();
+ getLogger().info("Loading entity hider...");
this.entityHider = new EntityHider(this, EntityHider.Policy.BLACKLIST);
+ getLogger().info("Registering listeners...");
this.registerListeners();
+ getLogger().info("Registering commands...");
this.commandGroup = new CommandGroup("hs",
new Help(),
new Reload(),
@@ -111,21 +133,38 @@ public class Main extends JavaPlugin implements Listener {
new Debug(),
new GoTo()
),
+ new CommandGroup("world",
+ new Create(),
+ new Delete(),
+ new net.tylermurphy.hideAndSeek.command.world.List(),
+ new Tp()
+ ),
new SetExitLocation(),
new Top(),
- new Wins()
+ new Wins(),
+ new Confirm()
);
+ getLogger().info("Loading game...");
game = new Game(null, board);
+ getLogger().info("Scheduling tick tasks...");
getServer().getScheduler().runTaskTimer(this, this::onTick,0,1).getTaskId();
+ getLogger().info("Registering outgoing bungeecord plugin channel...");
Bukkit.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
+ getLogger().info("Checking for PlaceholderAPI...");
if (getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) {
+ getLogger().info("PlaceholderAPI found...");
+ getLogger().info("Registering PlaceholderAPI expansion...");
new PAPIExpansion().register();
}
+ long end = System.currentTimeMillis();
+ getLogger().info("Finished loading plugin ("+(end-start)+"ms)");
+ loaded = true;
+
}
public void onDisable() {
@@ -222,5 +261,24 @@ public class Main extends JavaPlugin implements Listener {
public boolean supports(int v){
return version >= v;
}
+
+ public java.util.List<String> getWorlds() {
+ java.util.List<String> worlds = new ArrayList<>();
+ File[] containers = getWorldContainer().listFiles();
+ if(containers != null) {
+ Arrays.stream(containers).forEach(file -> {
+ if (!file.isDirectory()) return;
+ String[] files = file.list();
+ if (files == null) return;
+ if (!Arrays.asList(files).contains("session.lock") && !Arrays.asList(files).contains("level.dat")) return;
+ worlds.add(file.getName());
+ });
+ }
+ return worlds;
+ }
+
+ public boolean isLoaded() {
+ return loaded;
+ }
} \ No newline at end of file
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/Confirm.java b/src/main/java/net/tylermurphy/hideAndSeek/command/Confirm.java
new file mode 100644
index 0000000..a25185d
--- /dev/null
+++ b/src/main/java/net/tylermurphy/hideAndSeek/command/Confirm.java
@@ -0,0 +1,62 @@
+package net.tylermurphy.hideAndSeek.command;
+
+import net.tylermurphy.hideAndSeek.command.util.ICommand;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+import java.util.function.Consumer;
+
+import static net.tylermurphy.hideAndSeek.configuration.Config.errorPrefix;
+import static net.tylermurphy.hideAndSeek.configuration.Localization.message;
+
+public class Confirm implements ICommand {
+
+ public static final Map<UUID, Confirmation> confirmations = new HashMap<>();
+
+ public void execute(Player sender, String[] args) {
+ Confirmation confirmation = confirmations.get(sender.getUniqueId());
+ confirmations.remove(sender.getUniqueId());
+ if(confirmation == null) {
+ sender.sendMessage(errorPrefix + message("NO_CONFIRMATION"));
+ } else {
+ long now = System.currentTimeMillis();
+ float secs = (now - confirmation.start) / 1000F;
+ if(secs > 10) {
+ sender.sendMessage(errorPrefix + message("CONFIRMATION_TIMED_OUT"));
+ return;
+ }
+ confirmation.callback.accept(confirmation.data);
+ }
+ }
+
+ public String getLabel() {
+ return "confirm";
+ }
+
+ public String getUsage() {
+ return "";
+ }
+
+ public String getDescription() {
+ return "Confirm another command if required";
+ }
+
+ public List<String> autoComplete(@NotNull String parameter, @NotNull String typed) {
+ return null;
+ }
+
+ public static class Confirmation {
+ public final Consumer<String> callback;
+ public final String data;
+ public final long start;
+
+ public Confirmation(String data, Consumer<String> callback) {
+ this.callback = callback;
+ this.data = data;
+ this.start = System.currentTimeMillis();
+ }
+
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/world/Create.java b/src/main/java/net/tylermurphy/hideAndSeek/command/world/Create.java
new file mode 100644
index 0000000..5ab9039
--- /dev/null
+++ b/src/main/java/net/tylermurphy/hideAndSeek/command/world/Create.java
@@ -0,0 +1,66 @@
+package net.tylermurphy.hideAndSeek.command.world;
+
+import net.tylermurphy.hideAndSeek.Main;
+import net.tylermurphy.hideAndSeek.command.util.ICommand;
+import net.tylermurphy.hideAndSeek.util.Location;
+import org.bukkit.WorldType;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static net.tylermurphy.hideAndSeek.configuration.Config.errorPrefix;
+import static net.tylermurphy.hideAndSeek.configuration.Config.messagePrefix;
+import static net.tylermurphy.hideAndSeek.configuration.Localization.message;
+
+public class Create implements ICommand {
+
+ public void execute(Player sender, String[] args) {
+ List<String> worlds = Main.getInstance().getWorlds();
+ if(worlds.contains(args[0])) {
+ sender.sendMessage(errorPrefix + message("WORLD_EXISTS").addAmount(args[0]));
+ }
+ WorldType type;
+ if(args[1].equals("normal")) {
+ type = WorldType.NORMAL;
+ } else if(args[1].equals("flat")) {
+ type = WorldType.FLAT;
+ } else {
+ sender.sendMessage(errorPrefix + message("INVALID_WORLD_TYPE").addAmount(args[1]));
+ return;
+ }
+
+ Location temp = new Location(args[0], 0, 0, 0);
+
+ if (temp.load(type) == null) {
+ sender.sendMessage(errorPrefix + message("WORLD_ADDED_FAILED"));
+ } else {
+ sender.sendMessage(messagePrefix + message("WORLD_ADDED").addAmount(args[0]));
+ }
+
+ }
+
+ public String getLabel() {
+ return "create";
+ }
+
+ public String getUsage() {
+ return "<name> <type>";
+ }
+
+ public String getDescription() {
+ return "Create a new world";
+ }
+
+ public List<String> autoComplete(@NotNull String parameter, @NotNull String typed) {
+ if(parameter.equals("name")) {
+ return Collections.singletonList("name");
+ }
+ if(parameter.equals("type")) {
+ return Arrays.asList("normal", "flat");
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/world/Delete.java b/src/main/java/net/tylermurphy/hideAndSeek/command/world/Delete.java
new file mode 100644
index 0000000..4800e08
--- /dev/null
+++ b/src/main/java/net/tylermurphy/hideAndSeek/command/world/Delete.java
@@ -0,0 +1,74 @@
+package net.tylermurphy.hideAndSeek.command.world;
+
+import net.tylermurphy.hideAndSeek.Main;
+import net.tylermurphy.hideAndSeek.command.Confirm;
+import net.tylermurphy.hideAndSeek.command.util.ICommand;
+import net.tylermurphy.hideAndSeek.world.WorldLoader;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.List;
+
+import static net.tylermurphy.hideAndSeek.configuration.Config.errorPrefix;
+import static net.tylermurphy.hideAndSeek.configuration.Config.messagePrefix;
+import static net.tylermurphy.hideAndSeek.configuration.Localization.message;
+
+public class Delete implements ICommand {
+
+ public void execute(Player sender, String[] args) {
+ java.util.List<String> worlds = Main.getInstance().getWorlds();
+ if(!worlds.contains(args[0])) {
+ sender.sendMessage(errorPrefix + message("WORLD_DOESNT_EXIST").addAmount(args[0]));
+ }
+
+ Confirm.Confirmation confirmation = new Confirm.Confirmation(args[0], world -> {
+ java.util.List<String> worlds_now = Main.getInstance().getWorlds();
+ if(!worlds_now.contains(world)) {
+ sender.sendMessage(errorPrefix + message("WORLD_DOESNT_EXIST").addAmount(world));
+ }
+ World bukkit_world = Bukkit.getWorld(world);
+ if(bukkit_world != null && bukkit_world.getPlayers().size() > 0) {
+ sender.sendMessage(errorPrefix + message("WORLD_NOT_EMPTY"));
+ return;
+ }
+ String path = Main.getInstance().getWorldContainer().getPath() + File.separator + world;
+ if (!Bukkit.getServer().unloadWorld(world, false)) {
+ sender.sendMessage(errorPrefix + message("WORLD_REMOVED_FAILED"));
+ return;
+ }
+ try {
+ WorldLoader.deleteDirectory(new File(path));
+ } catch (Exception e) {
+ sender.sendMessage(errorPrefix + message("WORLD_REMOVED_FAILED"));
+ return;
+ }
+ sender.sendMessage(messagePrefix + message("WORLD_REMOVED").addAmount(world));
+ });
+
+ Confirm.confirmations.put(sender.getUniqueId(), confirmation);
+ sender.sendMessage(messagePrefix + message("CONFIRMATION"));
+
+ }
+
+ public String getLabel() {
+ return "delete";
+ }
+
+ public String getUsage() {
+ return "<name>";
+ }
+
+ public String getDescription() {
+ return "Delete a world";
+ }
+
+ public List<String> autoComplete(@NotNull String parameter, @NotNull String typed) {
+ if(parameter.equals("name")) {
+ return Main.getInstance().getWorlds();
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/world/List.java b/src/main/java/net/tylermurphy/hideAndSeek/command/world/List.java
new file mode 100644
index 0000000..2c0f745
--- /dev/null
+++ b/src/main/java/net/tylermurphy/hideAndSeek/command/world/List.java
@@ -0,0 +1,46 @@
+package net.tylermurphy.hideAndSeek.command.world;
+
+import net.tylermurphy.hideAndSeek.Main;
+import net.tylermurphy.hideAndSeek.command.util.ICommand;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import static net.tylermurphy.hideAndSeek.configuration.Config.errorPrefix;
+import static net.tylermurphy.hideAndSeek.configuration.Config.messagePrefix;
+import static net.tylermurphy.hideAndSeek.configuration.Localization.message;
+
+public class List implements ICommand {
+
+ public void execute(Player sender, String[] args) {
+ java.util.List<String> worlds = Main.getInstance().getWorlds();
+ if(worlds.isEmpty()) {
+ sender.sendMessage(errorPrefix + message("NO_WORLDS"));
+ } else {
+ StringBuilder response = new StringBuilder(messagePrefix + message("LIST_WORLDS"));
+ for (String world : worlds) {
+ boolean loaded = Bukkit.getWorld(world) != null;
+ response.append("\n ").append(world).append(": ").append(loaded ? ChatColor.GREEN + "LOADED" : ChatColor.YELLOW + "NOT LOADED").append(ChatColor.WHITE);
+ }
+ sender.sendMessage(response.toString());
+ }
+ }
+
+ public String getLabel() {
+ return "list";
+ }
+
+ public String getUsage() {
+ return "";
+ }
+
+ public String getDescription() {
+ return "List all worlds in the server";
+ }
+
+ public java.util.List<String> autoComplete(@NotNull String parameter, @NotNull String typed) {
+ return null;
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/world/Tp.java b/src/main/java/net/tylermurphy/hideAndSeek/command/world/Tp.java
new file mode 100644
index 0000000..b166297
--- /dev/null
+++ b/src/main/java/net/tylermurphy/hideAndSeek/command/world/Tp.java
@@ -0,0 +1,49 @@
+package net.tylermurphy.hideAndSeek.command.world;
+
+import net.tylermurphy.hideAndSeek.Main;
+import net.tylermurphy.hideAndSeek.command.util.ICommand;
+import net.tylermurphy.hideAndSeek.util.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+import static net.tylermurphy.hideAndSeek.configuration.Config.errorPrefix;
+import static net.tylermurphy.hideAndSeek.configuration.Localization.message;
+
+public class Tp implements ICommand {
+ public void execute(Player sender, String[] args) {
+ Location test = new Location(args[0], 0, 0,0);
+ if(!test.exists()) {
+ sender.sendMessage(errorPrefix + message("WORLD_DOESNT_EXIT"));
+ return;
+ }
+ World world = test.load();
+ if(world == null) {
+ sender.sendMessage(errorPrefix + message("WORLD_LOAD_FAILED"));
+ return;
+ }
+ Location loc = new Location(world.getName(), world.getSpawnLocation());
+ loc.teleport(sender);
+ }
+
+ public String getLabel() {
+ return "tp";
+ }
+
+ public String getUsage() {
+ return "<world>";
+ }
+
+ public String getDescription() {
+ return "Teleport to another world";
+ }
+
+ public List<String> autoComplete(@NotNull String parameter, @NotNull String typed) {
+ if(parameter.equals("world")) {
+ return Main.getInstance().getWorlds();
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java
index eda8470..be699ec 100644
--- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java
+++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java
@@ -318,11 +318,11 @@ public class ConfigManager {
int index = 0;
for(String part : parts) {
if (index == 0) {
- index = yaml.indexOf(part + ":", index);
+ index = yaml.indexOf("\n" + part + ":", index) + 1;
} else {
index = yaml.indexOf(" " + part + ":", index) + 1;
}
- if (index == -1) break;
+ if (index == 0) break;
}
return index;
}
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Maps.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Maps.java
index 98ba4a0..d691fa9 100644
--- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Maps.java
+++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Maps.java
@@ -3,6 +3,7 @@ package net.tylermurphy.hideAndSeek.configuration;
import java.util.*;
import java.util.stream.Collectors;
+import net.tylermurphy.hideAndSeek.Main;
import net.tylermurphy.hideAndSeek.util.Location;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@@ -72,6 +73,7 @@ public class Maps {
ConfigurationSection data = maps.getConfigurationSection(name);
if(data == null) return null;
Map map = new Map(name);
+ Main.getInstance().getLogger().info("Loading map: " + name + "...");
map.setSpawn(getSpawn(data, "game"));
map.setLobby(getSpawn(data, "lobby"));
map.setSeekerLobby(getSpawn(data, "seeker"));
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java b/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java
index e7bfb26..d2fb40d 100644
--- a/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java
+++ b/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java
@@ -45,8 +45,10 @@ public class Database {
public Database(){
if(databaseType.equals("SQLITE")) {
+ Main.getInstance().getLogger().info("SQLITE database chosen");
connection = new SQLiteConnection();
} else {
+ Main.getInstance().getLogger().info("MYSQL database chosen");
connection = new MySQLConnection();
}
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java
index b7c1b1d..56f53f6 100644
--- a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java
+++ b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java
@@ -21,6 +21,7 @@ package net.tylermurphy.hideAndSeek.database.connections;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
+import net.tylermurphy.hideAndSeek.Main;
import java.sql.Connection;
import java.sql.SQLException;
@@ -35,6 +36,13 @@ public class MySQLConnection implements DatabaseConnection {
HikariConfig config = new HikariConfig();
+ Main.getInstance().getLogger().info("Database host: " + databaseHost);
+ Main.getInstance().getLogger().info("Database port: " + databasePort);
+ Main.getInstance().getLogger().info("Database user: " + databaseUser);
+ Main.getInstance().getLogger().info("Database pass: xxxxxxxxxxx");
+ Main.getInstance().getLogger().info("Database name: " + databaseName);
+
+
config.setJdbcUrl("jdbc:mariadb://"+databaseHost+":"+databasePort+"/"+databaseName);
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/util/Location.java b/src/main/java/net/tylermurphy/hideAndSeek/util/Location.java
index 2abdb9b..efc4329 100644
--- a/src/main/java/net/tylermurphy/hideAndSeek/util/Location.java
+++ b/src/main/java/net/tylermurphy/hideAndSeek/util/Location.java
@@ -4,6 +4,7 @@ import net.tylermurphy.hideAndSeek.Main;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;
+import org.bukkit.WorldType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@@ -42,13 +43,30 @@ public class Location {
this.z = z;
}
- public World load() {
+ public Location(@NotNull String world, @NotNull org.bukkit.Location location) {
+ this.world = world;
+ this.x = location.getX();
+ this.y = location.getY();
+ this.z = location.getZ();
+ }
+
+ public World load(WorldType type) {
World bukkitWorld = Bukkit.getWorld(world);
if(bukkitWorld != null) return bukkitWorld;
- Bukkit.getServer().createWorld(new WorldCreator(world));
+ if (type == null) {
+ Bukkit.getServer().createWorld(new WorldCreator(world));
+ } else {
+ Bukkit.getServer().createWorld(new WorldCreator(world).type(type));
+ }
return Bukkit.getWorld(world);
}
+ public World load() {
+ if(!exists()) return null;
+ if(!Main.getInstance().isLoaded()) return null;
+ return load(null);
+ }
+
private org.bukkit.Location toBukkit() {
return new org.bukkit.Location(
Bukkit.getWorld(world),
diff --git a/src/main/java/net/tylermurphy/hideAndSeek/world/WorldLoader.java b/src/main/java/net/tylermurphy/hideAndSeek/world/WorldLoader.java
index b3be907..6ea1773 100644
--- a/src/main/java/net/tylermurphy/hideAndSeek/world/WorldLoader.java
+++ b/src/main/java/net/tylermurphy/hideAndSeek/world/WorldLoader.java
@@ -155,7 +155,7 @@ public class WorldLoader {
out.close();
}
- private void deleteDirectory(File directoryToBeDeleted) {
+ public static void deleteDirectory(File directoryToBeDeleted) {
File[] allContents = directoryToBeDeleted.listFiles();
if (allContents != null) {
for (File file : allContents) {
diff --git a/src/main/resources/lang/localization_en-US.yml b/src/main/resources/lang/localization_en-US.yml
index d62153d..61d562b 100644
--- a/src/main/resources/lang/localization_en-US.yml
+++ b/src/main/resources/lang/localization_en-US.yml
@@ -107,6 +107,20 @@ Localization:
BLOCKHUNT_BLOCK_REMOVED: "Removed {AMOUNT} from blockhunt config."
BLOCKHUNT_LIST_BLOCKS: "The following blockhunt blocks are:"
NO_BLOCKS: "There are no blockhunt blocks in this map."
+ WORLD_EXISTS: "A world named {AMOUNT} already exists."
+ WORLD_DOESNT_EXIST: "There is no world named {AMOUNT} that exists."
+ WORLD_ADDED: "Created a world named {AMOUNT}."
+ WORLD_ADDED_FAILED: "Failed to create new world."
+ WORLD_REMOVED: "Deleted a world named {AMOUNT}."
+ WORLD_REMOVED_FAILED: "Failed to delete world."
+ WORLD_NOT_EMPTY: "World must be empty to be deleted."
+ LIST_WORLDS: "The following worlds are:"
+ NO_WORLDS: "Failed to fetch any worlds."
+ WORLD_LOAD_FAILED: "Failed to load world."
+ INVALID_WORLD_TYPE: "Invalid world type: {AMOUNT}."
+ NO_CONFIRMATION: "You have nothing to confirm."
+ CONFIRMATION_TIMED_OUT: "The confirmation has timed out."
+ CONFIRMATION: "Run /hs confirm within 10s to confirm."
# DO NOT EDIT IT OR IT MAY BREAK OR RESET FILE
version: 4
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 92c6483..c6ce455 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -62,4 +62,14 @@ permissions:
default: op
hs.map.blockhunt.list:
default: op
+ hs.world.create:
+ default: op
+ hs.world.delete:
+ default: op
+ hs.world.list:
+ default: op
+ hs.world.tp:
+ default: op
+ hs.confirm:
+ default: op