playerDatas) {
*/
public void addPlayerToDatabase(PlayerData playerData) {
if(!Database.getInstance().isConnected) return;
- Query.query("INSERT INTO playerData (name, UUID, introduction, usesPlugin, difficulty, bestParkourTime) VALUES (:name, :uuid, :introduction, :usesPlugin, :difficulty, :bestParkourTime);")
+ Query.query("INSERT INTO playerData (name, UUID, introduction, usesPlugin, difficulty, bestParkourTime, isInTeam, uuidOfTeam, isTeamOperator) VALUES (:name, :uuid, :introduction, :usesPlugin, :difficulty, :bestParkourTime, :isInTeam, :uuidOfTeam, :isTeamOperator);")
.single(Call.of()
.bind("name", playerData.getName())
- .bind("uuid", playerData.getUUID(), UUIDAdapter.AS_STRING)
+ .bind("uuid", playerData.getUniqueId(), UUIDAdapter.AS_STRING)
.bind("introduction", playerData.getIntroduction())
.bind("usesPlugin", playerData.getUsesPlugin())
.bind("difficulty", playerData.getDifficulty())
- .bind("bestParkourTime", playerData.getBestParkourTime()))
+ .bind("bestParkourTime", playerData.getBestParkourTime())
+ .bind("isInTeam", playerData.isInTeam())
+ .bind("uuidOfTeam", playerData.getUuidOfTeam(), UUIDAdapter.AS_STRING)
+ .bind("isTeamOperator", playerData.isTeamOperator()))
.insert();
}
@@ -139,19 +186,22 @@ public void addPlayerToDatabase(PlayerData playerData) {
* This method fetches all player data records from the database and checks
* if the player with the given UUID is present in the list.
*
- * @param playerDataPlayerToCheck The player data to check.
+ * @param playerDataToCheck The player data to check.
* @return true if the player is in the database, false otherwise.
*/
- public boolean checkIfPlayerIsInDatabase(PlayerData playerDataPlayerToCheck) {
- if(!Database.getInstance().isConnected) return HandlePlayers.getKnownPlayers().containsKey(playerDataPlayerToCheck.getUUID()); // does not return false or true to prevent unpredictable behavior
- List playerDatas = getAllPlayerDatas();
- boolean isInDatabase = false;
- if(playerDatas.isEmpty()) return false;
- for (PlayerData playerDataToCompare : playerDatas) {
- if(playerDataToCompare.getUUID().equals(playerDataPlayerToCheck.getUUID())) {
- isInDatabase = true;
- }
- }
- return isInDatabase;
+ public boolean checkIfPlayerIsInDatabase(PlayerData playerDataToCheck) {
+ return checkIfPlayerIsInDatabase(playerDataToCheck.getUniqueId());
+ }
+
+ public boolean checkIfPlayerIsInDatabase(UUID uuidOfPlayerToCheck) {
+ if(!Database.getInstance().isConnected) return HandlePlayers.getKnownPlayers().containsKey(uuidOfPlayerToCheck); // does not return false or true to prevent unpredictable behavior
+ List data = Query.query("SELECT UUID FROM playerData WHERE UUID = :UUID;")
+ .single(Call.of()
+ .bind("UUID", uuidOfPlayerToCheck, UUIDAdapter.AS_STRING))
+ .map(row -> UUID.fromString(row.getString("UUID")))
+ .all();
+
+ Main.getMainLogger().warning("CheckIfPlayerIsInDatabase for: " + Bukkit.getOfflinePlayer(uuidOfPlayerToCheck).getName() + ", found " + !data.isEmpty());
+ return !data.isEmpty();
}
}
diff --git a/src/main/java/de/j/deathMinigames/database/TeamEnderchestsDatabase.java b/src/main/java/de/j/deathMinigames/database/TeamEnderchestsDatabase.java
new file mode 100644
index 00000000..1eac5c30
--- /dev/null
+++ b/src/main/java/de/j/deathMinigames/database/TeamEnderchestsDatabase.java
@@ -0,0 +1,88 @@
+package de.j.deathMinigames.database;
+
+import de.chojo.sadu.queries.api.call.Call;
+import de.chojo.sadu.queries.api.query.Query;
+import de.chojo.sadu.queries.call.adapter.UUIDAdapter;
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.Team;
+import de.j.stationofdoom.teams.TeamsMainMenuGUI;
+import net.kyori.adventure.text.Component;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.UUID;
+
+public class TeamEnderchestsDatabase {
+ private static volatile TeamEnderchestsDatabase instance;
+
+ public TeamEnderchestsDatabase() {}
+
+ public static TeamEnderchestsDatabase getInstance() {
+ if (instance == null) {
+ synchronized (TeamEnderchestsDatabase.class) {
+ if (instance == null) {
+ instance = new TeamEnderchestsDatabase();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public void createTable() {
+ if(!Database.getInstance().isConnected) return;
+ Query.query("CREATE TABLE IF NOT EXISTS teamEnderchests (uuidOfTeam VARCHAR(255), name VARCHAR(255), amount INTEGER, material VARCHAR(255));")
+ .single()
+ .insert();
+ }
+
+ public Inventory getTeamEnderchest(UUID uuidOfTeam) {
+ Inventory inv = Bukkit.createInventory(null, 27, "Team Enderchest");
+ if(!Database.getInstance().isConnected) return inv;
+ Query.query("SELECT * FROM teamEnderchests WHERE uuidOfTeam = ?;")
+ .single(Call.of()
+ .bind(uuidOfTeam, UUIDAdapter.AS_STRING))
+ .map(row -> {
+ ItemStack itemStack;
+ try {
+ itemStack = new ItemStack(Material.valueOf(row.getString("material")), row.getInt("amount"));
+ ItemMeta itemMeta = itemStack.getItemMeta();
+ if(row.getString("name") != null && !row.getString("name").isEmpty()) itemMeta.displayName(Component.text(row.getString("name")));
+ itemStack.setItemMeta(itemMeta);
+ }
+ catch (NullPointerException e) {
+ Main.getMainLogger().warning("Could not find material of " + row.getString("material") + " in team enderchests of team " + uuidOfTeam);
+ itemStack = new ItemStack(Material.STONE, 1);
+ itemStack.getItemMeta().displayName(Component.text("Could not find material of " + row.getString("material")));
+ }
+ inv.addItem(itemStack);
+ return itemStack;
+ })
+ .all();
+ return inv;
+ }
+
+ public void updateTeamEnderchestsOfAllTeams() {
+ if(!Database.getInstance().isConnected) return;
+ for (Team team : TeamsMainMenuGUI.teams) {
+ UUID uuidOfTeam = team.getUuid();
+ Query.query("DELETE FROM teamEnderchests WHERE uuidOfTeam = ?;")
+ .single(Call.of()
+ .bind(uuidOfTeam, UUIDAdapter.AS_STRING))
+ .delete();
+ if(team.inventory == null) continue;
+ for (ItemStack itemStack : team.inventory.getContents()) {
+ if(itemStack == null) continue;
+ Query.query("INSERT INTO teamEnderchests (uuidOfTeam, name, amount, material) VALUES (?, ?, ?, ?);")
+ .single(Call.of()
+ .bind(uuidOfTeam, UUIDAdapter.AS_STRING)
+ .bind(itemStack.getItemMeta().displayName() != null ? itemStack.getItemMeta().getDisplayName() : null)
+ .bind(itemStack.getAmount())
+ .bind(itemStack.getType().toString()))
+ .insert();
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/j/deathMinigames/database/TeamsDatabase.java b/src/main/java/de/j/deathMinigames/database/TeamsDatabase.java
new file mode 100644
index 00000000..a9861bdc
--- /dev/null
+++ b/src/main/java/de/j/deathMinigames/database/TeamsDatabase.java
@@ -0,0 +1,166 @@
+package de.j.deathMinigames.database;
+
+
+import de.chojo.sadu.queries.api.call.Call;
+import de.chojo.sadu.queries.api.query.Query;
+import de.chojo.sadu.queries.call.adapter.UUIDAdapter;
+import de.j.deathMinigames.main.HandlePlayers;
+import de.j.deathMinigames.main.PlayerData;
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.HandleTeams;
+import de.j.stationofdoom.teams.Team;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+
+public class TeamsDatabase {
+ private static volatile TeamsDatabase instance;
+
+ public TeamsDatabase() {}
+
+ public static TeamsDatabase getInstance() {
+ if (instance == null) {
+ synchronized (TeamsDatabase.class) {
+ if (instance == null) {
+ instance = new TeamsDatabase();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public void createTable() {
+ if(!Database.getInstance().isConnected) return;
+ Query.query("CREATE TABLE IF NOT EXISTS teams (name VARCHAR(255), color VARCHAR(255), locked BOOLEAN, uuid VARCHAR(255), world VARCHAR(255), protectedLocationX INT, protectedLocationY INT, protectedLocationZ INT);")
+ .single()
+ .insert();
+ }
+
+ public List getTeams() {
+ if(!Database.getInstance().isConnected) return new ArrayList<>();
+ List teams = new ArrayList<>();
+ Query.query("SELECT * FROM teams;")
+ .single()
+ .map(row -> new Team(row.getString("name"),
+ row.getString("color"),
+ row.getBoolean("locked"),
+ row.getString("uuid"),
+ row.getString("world"),
+ row.getInt("protectedLocationX"),
+ row.getInt("protectedLocationY"),
+ row.getInt("protectedLocationZ")))
+ .all()
+ .forEach(team -> teams.add(team));
+ Main.getMainLogger().info("Found " + teams.size() + " team(s):");
+ for (Team team : teams) {
+ Main.getMainLogger().info(team.getName());
+ try {
+ Query.query("SELECT isInTeam, uuid, isTeamOperator FROM playerData WHERE uuidOfTeam = ?;")
+ .single(Call.of()
+ .bind(team.getUuid(), UUIDAdapter.AS_STRING)
+ )
+ .map(row -> new DBTeamMember(
+ row.getBoolean("isInTeam"),
+ row.getString("uuid"),
+ row.getBoolean("isTeamOperator")))
+ .all()
+ .forEach(team::addMember);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ Main.getMainLogger().warning("Could not get players from team " + team.getName());
+ }
+ }
+ return teams;
+ }
+
+ public void insertTeam(Team team) {
+ if(!Database.getInstance().isConnected) return;
+ if(team.getProtectedLocation() != null) {
+ Query.query("INSERT INTO teams (name, color, locked, uuid, world, protectedLocationX, protectedLocationY, protectedLocationZ) VALUES (?, ?, ?, ?, ?, ?, ?, ?);")
+ .single(Call.of()
+ .bind(team.getName())
+ .bind(team.getColorAsMaterial().name())
+ .bind(team.getLocked())
+ .bind(team.getUuid(), UUIDAdapter.AS_STRING)
+ .bind(team.getProtectedLocation().getWorld().getName())
+ .bind(team.getProtectedLocation().getBlockX())
+ .bind(team.getProtectedLocation().getBlockY())
+ .bind(team.getProtectedLocation().getBlockZ())
+ )
+ .insert();
+ }
+ else {
+ Query.query("INSERT INTO teams (name, color, locked, uuid) VALUES (?, ?, ?, ?);")
+ .single(Call.of()
+ .bind(team.getName())
+ .bind(team.getColorAsMaterial().name())
+ .bind(team.getLocked())
+ .bind(team.getUuid(), UUIDAdapter.AS_STRING))
+ .insert();
+ }
+ for(UUID uuid : team.getAllPlayers()) {
+ PlayerData playerData = HandlePlayers.getInstance().getPlayerData(uuid);
+ updatePlayerInDB(playerData);
+ }
+ }
+
+ public void updatePlayerInDB(PlayerData playerData) {
+ if(!Database.getInstance().isConnected) return;
+ Team team = HandleTeams.getTeam(playerData);
+ if(team == null || !playerData.isInTeam()) {
+ Main.getMainLogger().warning("Player is not in team, isInTeam = " + playerData.isInTeam());
+ Query.query("UPDATE playerData SET isInTeam = ? WHERE uuid = ?;")
+ .single(Call.of()
+ .bind(false)
+ .bind(playerData.getUniqueId(), UUIDAdapter.AS_STRING))
+ .insert();
+ }
+ else {
+ Main.getMainLogger().warning("Player is in team, isInTeam = " + playerData.isInTeam());
+ Query.query("UPDATE playerData SET uuidOfTeam = ?, isTeamOperator = ? WHERE uuid = ?;")
+ .single(Call.of()
+ .bind(team.getUuid().toString())
+ .bind(team.isTeamOperator(playerData))
+ .bind(playerData.getUniqueId(), UUIDAdapter.AS_STRING))
+ .insert();
+ }
+ }
+
+ public void updateTeamsDatabase() {
+ if(!Database.getInstance().isConnected) return;
+ List teams = HandleTeams.getInstance().getAllTeams();
+ wipeDatabase();
+ for (Team team : teams) {
+ if(team.getAllPlayers().isEmpty()) {
+ Main.getMainLogger().info("Team " + team.getName() + " has no players, removing it");
+ }
+ else {
+ insertTeam(team);
+ }
+ }
+ Main.getMainLogger().info("Updated teams database");
+ }
+
+ private void wipeDatabase() {
+ if(!Database.getInstance().isConnected) return;
+ Query.query("DELETE FROM teams;")
+ .single()
+ .delete();
+ }
+
+ public void removeTeam(Team team) {
+ if(!Database.getInstance().isConnected) return;
+ Query.query("DELETE FROM teams WHERE uuid = ?;")
+ .single(Call.of()
+ .bind(team.getUuid(), UUIDAdapter.AS_STRING))
+ .delete();
+ for(UUID uuid : team.getAllPlayers()) {
+ PlayerData playerData = HandlePlayers.getInstance().getPlayerData(uuid);
+ updatePlayerInDB(playerData);
+ }
+ }
+}
diff --git a/src/main/java/de/j/deathMinigames/listeners/AnvilListener.java b/src/main/java/de/j/deathMinigames/listeners/AnvilListener.java
index 7218257b..af5931b1 100644
--- a/src/main/java/de/j/deathMinigames/listeners/AnvilListener.java
+++ b/src/main/java/de/j/deathMinigames/listeners/AnvilListener.java
@@ -1,8 +1,13 @@
package de.j.deathMinigames.listeners;
import de.j.deathMinigames.dmUtil.DmUtil;
+import de.j.deathMinigames.main.HandlePlayers;
import de.j.deathMinigames.settings.MainMenu;
import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.HandleTeams;
+import de.j.stationofdoom.teams.Team;
+import de.j.stationofdoom.teams.TeamSettingsGUI;
+import de.j.stationofdoom.teams.chunkClaimSystem.ChunkClaimSystem;
import de.j.stationofdoom.util.Tablist;
import de.j.stationofdoom.util.translations.TranslationFactory;
import net.kyori.adventure.text.Component;
@@ -22,9 +27,13 @@
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.view.AnvilView;
+import static io.papermc.paper.registry.keys.SoundEventKeys.*;
+
public class AnvilListener implements Listener {
private String serverName;
private String hostName;
+ private String teamName;
+ private int claimingRadius;
private TranslationFactory tf = new TranslationFactory();
@EventHandler
@@ -54,6 +63,26 @@ else if(MainMenu.getSetServerName().compareLocIDTo(loc)) {
if(renameText == null) return;
serverName = renameText;
}
+ else if(TeamSettingsGUI.renameTeam.compareLocIDTo(loc)) {
+ finishAnvilInvAfterOpening(event, player);
+ if(renameText == null) return;
+ teamName = renameText;
+ }
+ else if(MainMenu.getSetClaimingRadius().compareLocIDTo(loc)) {
+ finishAnvilInvAfterOpening(event, player);
+ if(renameText == null) return;
+ try {
+ claimingRadius = Integer.parseInt(renameText);
+ }
+ catch(NumberFormatException e) {
+ player.sendMessage(Component.text(tf.getTranslation(player, "invalidAnvilInputClaimingRadius")));
+ return;
+ }
+ if(claimingRadius <= 0 || claimingRadius > 256) {
+ player.sendMessage(Component.text(tf.getTranslation(player, "invalidAnvilInputClaimingRadius")));
+ return;
+ }
+ }
}
@EventHandler
@@ -69,17 +98,43 @@ public void onAnvilClick(InventoryClickEvent event) {
if (hostName == null) return;
Tablist.setHostedBy(hostName);
event.getView().close();
- DmUtil.getInstance().playSoundAtLocation(player.getLocation(), 0.5f, Sound.BLOCK_ANVIL_USE);
+ player.playSound(net.kyori.adventure.sound.Sound.sound(BLOCK_CHISELED_BOOKSHELF_INSERT_ENCHANTED, net.kyori.adventure.sound.Sound.Source.PLAYER, 3F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
player.sendMessage(Component.text("Host name: " + hostName).color(NamedTextColor.GOLD));
} else if (MainMenu.getSetServerName().compareLocIDTo(loc)) {
event.setCancelled(true);
if (serverName == null) return;
Tablist.setServerName(serverName);
event.getView().close();
- DmUtil.getInstance().playSoundAtLocation(player.getLocation(), 0.5f, Sound.BLOCK_ANVIL_USE);
+ player.playSound(net.kyori.adventure.sound.Sound.sound(BLOCK_CHISELED_BOOKSHELF_INSERT_ENCHANTED, net.kyori.adventure.sound.Sound.Source.PLAYER, 3F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
player.sendMessage(Component.text("Server name: " + serverName).color(NamedTextColor.GOLD));
}
-
+ else if(TeamSettingsGUI.renameTeam.compareLocIDTo(loc)) {
+ event.setCancelled(true);
+ if(teamName == null) {
+ Main.getMainLogger().info("teamName is null");
+ return;
+ }
+ Team team = HandleTeams.getTeam(HandlePlayers.getInstance().getPlayerData(player.getUniqueId()));
+ if(team == null) {
+ Main.getMainLogger().warning("Team is null in onAnvilClick");
+ player.sendMessage(Component.text(tf.getTranslation(player, "noTeam")));
+ return;
+ }
+ Main.getMainLogger().info("set name of team " + team.getName() + " to: " + teamName);
+ team.setName(teamName);
+ new TeamSettingsGUI(team).showPage(1, player);
+ player.playSound(net.kyori.adventure.sound.Sound.sound(BLOCK_CHISELED_BOOKSHELF_INSERT_ENCHANTED, net.kyori.adventure.sound.Sound.Source.PLAYER, 3F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+ else if(MainMenu.getSetClaimingRadius().compareLocIDTo(loc)) {
+ event.setCancelled(true);
+ if(claimingRadius <= 0 || claimingRadius > 256) {
+ player.sendMessage(Component.text(tf.getTranslation(player, "invalidAnvilInputClaimingRadius")));
+ return;
+ }
+ ChunkClaimSystem.getInstance().setProtectedLocationSizeInBlocks(claimingRadius);
+ event.getView().close();
+ player.sendMessage(Component.text(tf.getTranslation(player, "setClaimingRadius", ChunkClaimSystem.getInstance().getProtectedLocationSizeInBlocks())).color(NamedTextColor.GOLD));
+ }
}
}
@@ -95,6 +150,12 @@ public void onAnvilClose(InventoryCloseEvent event) {
else if(MainMenu.getSetServerName().compareLocIDTo(loc)) {
anvilInventory.clear();
}
+ else if(TeamSettingsGUI.renameTeam.compareLocIDTo(loc)) {
+ anvilInventory.clear();
+ }
+ else if(MainMenu.getSetClaimingRadius().compareLocIDTo(loc)) {
+ anvilInventory.clear();
+ }
}
}
diff --git a/src/main/java/de/j/deathMinigames/listeners/InventoryListener.java b/src/main/java/de/j/deathMinigames/listeners/InventoryListener.java
index f0168023..15f58db1 100755
--- a/src/main/java/de/j/deathMinigames/listeners/InventoryListener.java
+++ b/src/main/java/de/j/deathMinigames/listeners/InventoryListener.java
@@ -256,6 +256,9 @@ private void handleMainMenuGUI(InventoryClickEvent event, Player player, MainMen
case 5:
MainMenu.getSetServerName().showInventory(player);
break;
+ case 6:
+ MainMenu.getSetClaimingRadius().showInventory(player);
+ break;
}
}
diff --git a/src/main/java/de/j/deathMinigames/listeners/JoinListener.java b/src/main/java/de/j/deathMinigames/listeners/JoinListener.java
index 5ac67ffd..a5725310 100755
--- a/src/main/java/de/j/deathMinigames/listeners/JoinListener.java
+++ b/src/main/java/de/j/deathMinigames/listeners/JoinListener.java
@@ -3,6 +3,7 @@
import de.j.deathMinigames.main.HandlePlayers;
import de.j.deathMinigames.main.PlayerData;
import de.j.deathMinigames.main.PlayerMinigameStatus;
+import de.j.stationofdoom.main.Main;
import de.j.stationofdoom.util.translations.TranslationFactory;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -32,13 +33,12 @@ public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
TranslationFactory tf = new TranslationFactory();
HandlePlayers handlePlayers = HandlePlayers.getInstance();
-
if(!handlePlayers.checkIfPlayerIsKnown(player.getUniqueId())) {
handlePlayers.addNewPlayer(player);
player.sendMessage(Component.text(tf.getTranslation(player,"addedToPlayerList")).color(NamedTextColor.GOLD)
.append(Component.text(HandlePlayers.getKnownPlayers().get(player.getUniqueId()).getDifficulty()).color(NamedTextColor.RED)));
}
- PlayerData playerData = HandlePlayers.getKnownPlayers().get(player.getUniqueId());
+ PlayerData playerData = HandlePlayers.getInstance().getPlayerData(player.getUniqueId());
if(playerData.getStatus().equals(PlayerMinigameStatus.DECIDING)) {
respawnListener.handleTimerWhilePlayerDecides(player);
}
diff --git a/src/main/java/de/j/deathMinigames/main/Config.java b/src/main/java/de/j/deathMinigames/main/Config.java
index 564cdc2d..3768d63a 100644
--- a/src/main/java/de/j/deathMinigames/main/Config.java
+++ b/src/main/java/de/j/deathMinigames/main/Config.java
@@ -1,9 +1,9 @@
package de.j.deathMinigames.main;
import de.j.stationofdoom.enchants.CustomEnchantsEnum;
+import de.j.stationofdoom.teams.chunkClaimSystem.ChunkClaimSystem;
import de.j.stationofdoom.util.Tablist;
import org.bukkit.Location;
-
import de.j.stationofdoom.main.Main;
import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration;
@@ -140,6 +140,9 @@ private void handleCloneTablist(FileConfiguration config) {
Tablist.setHostedBy(config.getString("Tablist.HostedBy"));
}
}
+ if(config.contains("ProtectedLocationRadius")) {
+ ChunkClaimSystem.getInstance().setProtectedLocationSizeInBlocks(config.getInt("ProtectedLocationRadius"));
+ }
}
private void handleCloneCustomEnchants(FileConfiguration config) {
@@ -177,7 +180,6 @@ public void cloneWaitingListLocationToPlugin(World world) {
int y = Main.getPlugin().getConfig().getInt("WaitingListPosition.y");
int z = Main.getPlugin().getConfig().getInt("WaitingListPosition.z");
configWaitingListPosition = new Location(world, x, y, z);
- Main.getMainLogger().info("set WaitingListPosition from config to: " + configWaitingListPosition.getBlockX() + ", " + configWaitingListPosition.getBlockY() + ", " + configWaitingListPosition.getBlockZ());
}
else {
Main.getMainLogger().warning("WaitingListPosition not found in config!");
@@ -259,6 +261,13 @@ public synchronized void setWaitingListPosition(Location location) {
Main.getMainLogger().info("set WaitingListPosition to: " + configWaitingListPosition);
}
+ public synchronized void setProtectedLocationSizeInBlocksInConfig(int size) {
+ if(size == 0 || size == Main.getPlugin().getConfig().getInt("ProtectedLocationRadius")) return;
+ Main.getPlugin().getConfig().set("ProtectedLocationRadius", size);
+ Main.getPlugin().saveConfig();
+ Main.getMainLogger().info("set ProtectedLocationSizeInBlocksInConfig to: " + size);
+ }
+
/**
* Checks if the plugin is set up.
*
diff --git a/src/main/java/de/j/deathMinigames/main/HandlePlayers.java b/src/main/java/de/j/deathMinigames/main/HandlePlayers.java
index 15ae6362..76e7bac3 100644
--- a/src/main/java/de/j/deathMinigames/main/HandlePlayers.java
+++ b/src/main/java/de/j/deathMinigames/main/HandlePlayers.java
@@ -1,11 +1,10 @@
package de.j.deathMinigames.main;
+import de.j.deathMinigames.database.Database;
import de.j.deathMinigames.database.PlayerDataDatabase;
import de.j.deathMinigames.minigames.Minigame;
import de.j.stationofdoom.main.Main;
-import de.j.stationofdoom.util.translations.TranslationFactory;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.*;
@@ -58,10 +57,10 @@ public static HashMap getKnownPlayers() {
*/
public static void initKnownPlayersPlayerData() {
PlayerDataDatabase playerDataDatabase = PlayerDataDatabase.getInstance();
- for(PlayerData playerData : playerDataDatabase.getAllPlayerDatas()) {
- knownPlayers.put(playerData.getUUID(), playerData);
+ for(PlayerData playerData : playerDataDatabase.getAllPlayerDataFromDB()) {
+ HandlePlayers.knownPlayers.put(playerData.getUniqueId(), playerData);
}
- Main.getMainLogger().info("Loaded " + knownPlayers.size() + " known players and their data");
+ Main.getMainLogger().info("Loaded " + HandlePlayers.knownPlayers.size() + " known players and their data");
}
/**
@@ -71,7 +70,7 @@ public static void initKnownPlayersPlayerData() {
* @return true if the player is known, false otherwise.
*/
public boolean checkIfPlayerIsKnown(UUID uuid) {
- return knownPlayers.containsKey(uuid);
+ return HandlePlayers.knownPlayers.containsKey(uuid);
}
/**
@@ -82,14 +81,14 @@ public boolean checkIfPlayerIsKnown(UUID uuid) {
* @param player The player to add.
*/
public synchronized void addNewPlayer(Player player) {
- PlayerData playerData = new PlayerData(player);
UUID playerUUID = player.getUniqueId();
if(checkIfPlayerIsKnown(playerUUID)) {
Main.getMainLogger().warning("Player " + playerUUID + " was tried to add, but is already known!");
return;
}
- knownPlayers.put(playerUUID, playerData);
- Main.getMainLogger().info("Added new player " + playerData.getName());
+ PlayerData playerData = new PlayerData(player);
+ HandlePlayers.knownPlayers.put(playerUUID, playerData);
+ PlayerDataDatabase.getInstance().addPlayerToDatabase(playerData);
}
@@ -101,7 +100,7 @@ public synchronized void addNewPlayer(Player player) {
*/
public static void copyAllPlayerDataIntoDatabase() {
PlayerDataDatabase playerDataDatabase = PlayerDataDatabase.getInstance();
- playerDataDatabase.updatePlayerDataDatabase(knownPlayers.values());
+ playerDataDatabase.updatePlayerDataDatabase(HandlePlayers.knownPlayers.values());
}
/**
@@ -114,7 +113,7 @@ public static void copyAllPlayerDataIntoDatabase() {
public List getLeaderBoard() {
float defaultTime = 1000f;
List leaderboard = new ArrayList<>();
- for (PlayerData playerData : knownPlayers.values()) {
+ for (PlayerData playerData : HandlePlayers.knownPlayers.values()) {
if(playerData.getBestParkourTime() == defaultTime) continue;
leaderboard.add(playerData);
}
@@ -124,7 +123,7 @@ public List getLeaderBoard() {
}
public void resetLeaderboardAndTimesOfPlayers() {
- for (PlayerData playerData : knownPlayers.values()) {
+ for (PlayerData playerData : HandlePlayers.knownPlayers.values()) {
playerData.setBestParkourTime(1000f);
}
}
@@ -145,4 +144,11 @@ public void handlePlayerLeftWhileProcessing(Player player) {
playerData.setLeftWhileProcessing(false);
}
}
+
+ public PlayerData getPlayerData(UUID uuidOfPlayer) {
+ if(!this.checkIfPlayerIsKnown(uuidOfPlayer)) {
+ addNewPlayer(Bukkit.getPlayer(uuidOfPlayer));
+ }
+ return HandlePlayers.knownPlayers.get(uuidOfPlayer);
+ }
}
diff --git a/src/main/java/de/j/deathMinigames/main/PlayerData.java b/src/main/java/de/j/deathMinigames/main/PlayerData.java
index 3bb062ad..bbbd1069 100644
--- a/src/main/java/de/j/deathMinigames/main/PlayerData.java
+++ b/src/main/java/de/j/deathMinigames/main/PlayerData.java
@@ -1,7 +1,9 @@
package de.j.deathMinigames.main;
import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.HandleTeams;
import org.bukkit.Bukkit;
import org.bukkit.Location;
+import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
@@ -18,16 +20,23 @@ public synchronized void setName(String name) {
this.name = name;
}
- public synchronized UUID getUUID() {
+ public synchronized UUID getUniqueId() {
return uuid;
}
- public synchronized void setUUID(UUID uuid) {
+ public synchronized void setUniqueID(UUID uuid) {
this.uuid = uuid;
}
public synchronized Player getPlayer() {
- return player;
+ if(this.player == null) {
+ this.player = Bukkit.getPlayer(this.uuid);
+ }
+ return this.player;
+ }
+
+ public synchronized OfflinePlayer getOfflinePlayer() {
+ return Bukkit.getOfflinePlayer(this.uuid);
}
public synchronized PlayerMinigameStatus getStatus() {
@@ -62,6 +71,16 @@ public synchronized void setLastDeathLocation(Location lastDeathLocation) {
this.lastDeathLocation = lastDeathLocation;
}
+ public synchronized Location getLocation() {
+ try {
+ return getPlayer().getLocation();
+ }
+ catch (NullPointerException e) {
+ Main.getMainLogger().warning("Tried accessing location of " + this.name + " but player is not online!");
+ return Bukkit.getOfflinePlayer(this.uuid).getLocation();
+ }
+ }
+
public synchronized int getDecisionTimer() {
return decisionTimer;
}
@@ -102,9 +121,18 @@ public synchronized void setUsesPlugin(boolean usesPlugin) {
this.usesPlugin = usesPlugin;
}
+ public boolean isOnline() {
+ try {
+ return getPlayer().isConnected();
+ }
+ catch (NullPointerException e) {
+ return false;
+ }
+ }
+
private volatile String name; // in database
private volatile UUID uuid; // in database
- private final Player player;
+ private volatile Player player;
private volatile PlayerMinigameStatus status;
private volatile Inventory lastDeathInventory = Bukkit.createInventory(null, 9*6);
private volatile Location lastDeathLocation;
@@ -113,6 +141,33 @@ public synchronized void setUsesPlugin(boolean usesPlugin) {
private volatile int difficulty; // in database
private volatile int decisionTimer;
private volatile float bestParkourTime; // in database
+ private volatile boolean isInTeam; // in database
+ private volatile UUID uuidOfTeam; // in database
+ private volatile boolean teamOperator; // in database
+
+ public boolean isInTeam() {
+ return this.isInTeam;
+ }
+
+ public void setInTeam(boolean isInTeam) {
+ this.isInTeam = isInTeam;
+ }
+
+ public UUID getUuidOfTeam() {
+ return this.uuidOfTeam;
+ }
+
+ public void setUuidOfTeam(UUID uuidOfTeam) {
+ this.uuidOfTeam = uuidOfTeam;
+ }
+
+ public boolean isTeamOperator() {
+ return teamOperator;
+ }
+
+ public void setTeamOperator(boolean teamOperator) {
+ this.teamOperator = teamOperator;
+ }
public boolean getLeftWhileProcessing() {
return leftWhileProcessing;
@@ -139,7 +194,7 @@ public PlayerData(Player player) {
this.leftWhileProcessing = false;
}
- public PlayerData(String name, String uuid, boolean introduction, boolean usesPlugin, int difficulty, float bestParkourTime) {
+ public PlayerData(String name, String uuid, boolean introduction, boolean usesPlugin, int difficulty, float bestParkourTime, boolean isInTeam, String uuidOfTeam, boolean teamOperator) {
Config config = Config.getInstance();
this.name = name;
this.uuid = UUID.fromString(uuid);
@@ -152,14 +207,10 @@ public PlayerData(String name, String uuid, boolean introduction, boolean usesPl
this.introduction = introduction;
this.usesPlugin = usesPlugin;
this.leftWhileProcessing = false;
- }
-
- /**
- * Updates the player's name to the current name of the player entity.
- * This method synchronizes the stored name with the live player's name.
- */
- public void updateName() {
- this.name = player.getName();
+ if(isInTeam) {
+ this.uuidOfTeam = UUID.fromString(uuidOfTeam);
+ this.teamOperator = teamOperator;
+ }
}
/**
diff --git a/src/main/java/de/j/deathMinigames/settings/AnvilUI.java b/src/main/java/de/j/deathMinigames/settings/AnvilUI.java
index a3e5ef2c..91241e72 100644
--- a/src/main/java/de/j/deathMinigames/settings/AnvilUI.java
+++ b/src/main/java/de/j/deathMinigames/settings/AnvilUI.java
@@ -1,5 +1,10 @@
package de.j.deathMinigames.settings;
+import de.j.deathMinigames.main.HandlePlayers;
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.HandleTeams;
+import de.j.stationofdoom.teams.Team;
+import de.j.stationofdoom.teams.chunkClaimSystem.ChunkClaimSystem;
import de.j.stationofdoom.util.Tablist;
import de.j.stationofdoom.util.translations.TranslationFactory;
import net.kyori.adventure.text.Component;
@@ -66,9 +71,30 @@ private void setInputMeta(Player player) {
}
else {
switch (title) {
- case SET_HOST_NAME -> inputItemName = Tablist.getHostedBy();
- case SET_SERVER_NAME -> inputItemName = Tablist.getServerName();
- default -> throw new IllegalArgumentException("Title: " + title + " is not supported");
+ case SET_HOST_NAME:
+ inputItemName = Tablist.getHostedBy();
+ break;
+ case SET_SERVER_NAME:
+ inputItemName = Tablist.getServerName();
+ break;
+ case TEAM_RENAME:
+ Team team = HandleTeams.getTeam(HandlePlayers.getInstance().getPlayerData(player.getUniqueId()));
+ if(team == null) {
+ Main.getMainLogger().warning("Team is null in setInputMeta");
+ return;
+ }
+ if(team.getName() != null) {
+ inputItemName = team.getName();
+ }
+ else {
+ inputItemName = "";
+ }
+ break;
+ case SET_CLAIMING_RADIUS:
+ inputItemName = String.valueOf(ChunkClaimSystem.getInstance().getProtectedLocationSizeInBlocks());
+ break;
+ default:
+ throw new IllegalArgumentException("Title: " + title + " is not supported!");
}
if(inputItemName == null) {
inputMeta.displayName(Component.text(new TranslationFactory().getTranslation(player, "noNameSet")));
diff --git a/src/main/java/de/j/deathMinigames/settings/GUI.java b/src/main/java/de/j/deathMinigames/settings/GUI.java
index f0a6908c..62ff55c4 100755
--- a/src/main/java/de/j/deathMinigames/settings/GUI.java
+++ b/src/main/java/de/j/deathMinigames/settings/GUI.java
@@ -7,17 +7,12 @@
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Material;
-import org.bukkit.OfflinePlayer;
-import org.bukkit.Server;
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 de.j.deathMinigames.main.Config;
-import de.j.deathMinigames.listeners.InventoryListener;
import org.bukkit.inventory.meta.SkullMeta;
-import org.bukkit.profile.PlayerProfile;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -26,8 +21,13 @@
import java.util.UUID;
public class GUI implements InventoryHolder {
- private final Inventory inventory;
- private final UUID uuid = UUID.randomUUID();
+ protected Inventory inventory;
+ protected final UUID uuid = UUID.randomUUID();
+
+ public GUI() {
+ int inventorySize = 54;
+ inventory = Bukkit.createInventory(this, inventorySize);
+ }
public GUI(String title, boolean addAllPlayers, boolean addAsPlayerHeads) {
if(title == null) {
@@ -46,6 +46,22 @@ public GUI(String title, boolean addAllPlayers, boolean addAsPlayerHeads) {
}
}
+ public GUI(String title, boolean addAllPlayers, boolean addAsPlayerHeads, int size) {
+ if(title == null) {
+ throw new NullPointerException("Title is null!");
+ }
+ inventory = Bukkit.createInventory(this, size, title);
+ if(addAllPlayers) {
+ HashMap knownPlayers = HandlePlayers.getKnownPlayers();
+ if(addAsPlayerHeads) {
+ addPlayerHeads(knownPlayers);
+ }
+ else {
+ addBooleanBased(knownPlayers, title);
+ }
+ }
+ }
+
public void addPlayerHeads(HashMap knownPlayers) {
int maxSlots = inventory.getSize() - 1;
List playerKeys = new ArrayList<>(knownPlayers.keySet());
@@ -55,10 +71,10 @@ public void addPlayerHeads(HashMap knownPlayers) {
break;
}
PlayerData playerData = knownPlayers.get(playerKeys.get(i));
- if(playerData == null || playerData.getUUID() == null) continue;
+ if(playerData == null || playerData.getUniqueId() == null) continue;
ItemStack head = new ItemStack(Material.PLAYER_HEAD, 1);
SkullMeta skullMeta = (SkullMeta) head.getItemMeta();
- skullMeta.setOwnerProfile(Bukkit.createProfile(playerData.getUUID()));
+ skullMeta.setOwnerProfile(Bukkit.createProfile(playerData.getUniqueId()));
skullMeta.displayName(Component.text(playerData.getName()));
head.setItemMeta(skullMeta);
@@ -66,6 +82,17 @@ public void addPlayerHeads(HashMap knownPlayers) {
}
}
+ public void addPlayerHead(PlayerData playerData, int slot, List lore) {
+ ItemStack head = new ItemStack(Material.PLAYER_HEAD, 1);
+ SkullMeta skullMeta = (SkullMeta) head.getItemMeta();
+ skullMeta.setOwnerProfile(Bukkit.createProfile(playerData.getUniqueId()));
+ skullMeta.displayName(Component.text(playerData.getName()));
+ skullMeta.setLore(lore);
+ head.setItemMeta(skullMeta);
+
+ inventory.setItem(slot, head);
+ }
+
private void addBooleanBased(HashMap knownPlayers, String title) {
List playerKeys = new ArrayList<>(knownPlayers.keySet());
for(int i = 0; i < knownPlayers.size(); i++) {
@@ -118,21 +145,7 @@ public void addClickableItemStack(String name, Material material, int amount, in
}
itemStack.setItemMeta(itemMeta);
- inventory.setItem(slotWhereToPutTheItem, itemStack);
- }
-
- /**
- * Adds contents to the inventory using an array of ItemStacks.
- * If the array is larger than the inventory size, an exception is thrown.
- *
- * @param itemStackList An array of ItemStacks to be added to the inventory.
- * @throws IllegalArgumentException if the itemS tackList size exceeds the inventory size.
- */
- public void addClickableContentsViaItemStackList(ItemStack[] itemStackList) {
- if(itemStackList.length > inventory.getSize()) {
- throw new IllegalArgumentException("The StackList is bigger then the size of the inventory!");
- }
- inventory.setContents(itemStackList);
+ this.inventory.setItem(slotWhereToPutTheItem, itemStack);
}
/**
diff --git a/src/main/java/de/j/deathMinigames/settings/MainMenu.java b/src/main/java/de/j/deathMinigames/settings/MainMenu.java
index 74bf6e73..da9ecff7 100755
--- a/src/main/java/de/j/deathMinigames/settings/MainMenu.java
+++ b/src/main/java/de/j/deathMinigames/settings/MainMenu.java
@@ -27,13 +27,13 @@ public enum InventoryMenus {
PARKOUR_LENGTH,
COST_TO_LOWER_THE_DIFFICULTY,
TIME_TO_DECIDE_WHEN_RESPAWNING,
- SET_HOST,
- SET_SERVER_NAME
}
public enum AnvilUIs {
SET_SERVER_NAME,
SET_HOST_NAME,
+ TEAM_RENAME,
+ SET_CLAIMING_RADIUS,
DEFAULT // usage when the input slot item should have no name
}
@@ -85,6 +85,10 @@ public synchronized static AnvilUI getSetServerName() {
return setServerName;
}
+ public static AnvilUI getSetClaimingRadius() {
+ return setClaimingRadius;
+ }
+
private static final GUI introduction = new GUI("Introduction", true, false);
private static final GUI difficulty = new GUI("Difficulty", true, true);
private static final GUI usesPlugin = new GUI("UsesPlugin", true, false);
@@ -96,6 +100,7 @@ public synchronized static AnvilUI getSetServerName() {
private static final GUI timeToDecideWhenRespawning = new GUI("TimeToDecideWhenRespawning", false, false);
private static final AnvilUI setHost = new AnvilUI(AnvilUIs.SET_HOST_NAME);
private static final AnvilUI setServerName = new AnvilUI(AnvilUIs.SET_SERVER_NAME);
+ private static final AnvilUI setClaimingRadius = new AnvilUI(AnvilUIs.SET_CLAIMING_RADIUS);
/**
* Opens the main menu for the given player, where the player can
@@ -129,6 +134,7 @@ private void addSubmenus() {
addClickableItemStack("Difficulty", Material.RED_CONCRETE, 1, 3);
addClickableItemStack("SetHost", Material.BOOK, 1, 4);
addClickableItemStack("SetServerName", Material.BOOK, 1, 5);
+ addClickableItemStack("SetClaimingRadius", Material.MAP, 1, 6);
}
/**
diff --git a/src/main/java/de/j/stationofdoom/main/Main.java b/src/main/java/de/j/stationofdoom/main/Main.java
index 29cc38c1..20f84d11 100755
--- a/src/main/java/de/j/stationofdoom/main/Main.java
+++ b/src/main/java/de/j/stationofdoom/main/Main.java
@@ -2,6 +2,11 @@
import de.j.deathMinigames.commands.GameCMD;
import de.j.deathMinigames.commands.LeaderboardCMD;
+import de.j.stationofdoom.teams.TeamCMD;
+import de.j.stationofdoom.teams.chunkClaimSystem.BlockBreakAndUseCancelListener;
+import de.j.stationofdoom.teams.enderchest.TeamEnderchestPreventEnchantedItemsInputListener;
+import de.j.deathMinigames.database.TeamEnderchestsDatabase;
+import de.j.deathMinigames.database.TeamsDatabase;
import de.j.deathMinigames.listeners.*;
import de.j.deathMinigames.main.Config;
import de.j.deathMinigames.database.Database;
@@ -12,6 +17,9 @@
import de.j.stationofdoom.enchants.FurnaceEvents;
import de.j.stationofdoom.enchants.TelepathyEvents;
import de.j.stationofdoom.listener.*;
+import de.j.stationofdoom.teams.TeamInventoryReload;
+import de.j.stationofdoom.teams.TeamsCMD;
+import de.j.stationofdoom.teams.TeamSettingsInventoryListener;
import de.j.stationofdoom.util.EntityManager;
import de.j.stationofdoom.util.translations.ChangeLanguageGUI;
import de.j.stationofdoom.util.translations.LanguageChanger;
@@ -87,6 +95,8 @@ public void onEnable() {
COMMANDS.register("sit", new PlayerSitListener());
COMMANDS.register("game", "game related commands", new GameCMD());
COMMANDS.register("leaderboard", "showing the leaderboard of the minigame", new LeaderboardCMD());
+ COMMANDS.register("teams", "showing the Main teams menu settings", new TeamsCMD());
+ COMMANDS.register("team", "showing your team's settings", new TeamCMD());
});
PluginManager pluginManager = Bukkit.getPluginManager();
@@ -112,6 +122,10 @@ public void onEnable() {
pluginManager.registerEvents(new InitWaitingListLocationOnJoin(), this);
pluginManager.registerEvents(new LeaveListener(), this);
pluginManager.registerEvents(new AnvilListener(), this);
+ pluginManager.registerEvents(new TeamSettingsInventoryListener(), this);
+ pluginManager.registerEvents(new TeamInventoryReload(), this);
+ pluginManager.registerEvents(new TeamEnderchestPreventEnchantedItemsInputListener(), this);
+ pluginManager.registerEvents(new BlockBreakAndUseCancelListener(), this);
//CustomEnchants.register(); -> see custom enchants class for more info
@@ -126,6 +140,8 @@ public void onDisable() {
EntityManager.removeOldEntities();
WhoIsOnline.shutdown();
HandlePlayers.copyAllPlayerDataIntoDatabase();
+ TeamsDatabase.getInstance().updateTeamsDatabase();
+ TeamEnderchestsDatabase.getInstance().updateTeamEnderchestsOfAllTeams();
}
public static Main getPlugin(){
diff --git a/src/main/java/de/j/stationofdoom/teams/HandleTeams.java b/src/main/java/de/j/stationofdoom/teams/HandleTeams.java
new file mode 100644
index 00000000..c0c92a99
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/HandleTeams.java
@@ -0,0 +1,90 @@
+package de.j.stationofdoom.teams;
+
+import de.j.deathMinigames.database.TeamsDatabase;
+import de.j.deathMinigames.main.PlayerData;
+
+import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class HandleTeams {
+ private static volatile HandleTeams instance;
+
+ private static List teams = new CopyOnWriteArrayList<>();
+
+ private HandleTeams() {
+ teams = TeamsDatabase.getInstance().getTeams();
+ }
+
+ public static HandleTeams getInstance() {
+ if (instance == null) {
+ synchronized (HandleTeams.class) {
+ if (instance == null) {
+ instance = new HandleTeams();
+ }
+ }
+ }
+ return instance;
+ }
+
+ /** returns null when no them is found */
+ @Nullable
+ public static Team getTeam(PlayerData playerData) {
+ for(Team team : teams) {
+ if(team.isDeleted()) continue;
+ if(team.isMember(playerData.getUniqueId())) {
+ return team;
+ }
+ }
+ return null;
+ }
+
+ public static Team getTeamFromPlayerUUID(UUID uuid) {
+ for(Team team : teams) {
+ if(team.isDeleted()) continue;
+ if(team.isMember(uuid)) {
+ return team;
+ }
+ }
+ return new Team();
+ }
+
+ public static Team getTeam(UUID uuidOfTeam) {
+ for(Team team : teams) {
+ if(team.getUuid().equals(uuidOfTeam)) return team;
+ }
+ return null;
+ }
+
+ public static boolean teamExists(UUID uuidOfTeam) {
+ for(Team team : teams) {
+ if(team.getUuid().equals(uuidOfTeam)) return true;
+ }
+ return false;
+ }
+
+ public static void removePlayerFromEveryTeam(PlayerData playerData) {
+ List teamToRemoveOrAddPlayer = new ArrayList<>();
+ for(Team team : teams) {
+ if(team == null) continue;
+ if(team.isMember(playerData.getUniqueId())) {
+ teamToRemoveOrAddPlayer.add(team);
+ }
+ }
+ for(Team team : teamToRemoveOrAddPlayer) {
+ team.removeMember(playerData);
+ }
+ }
+
+ public static void addTeam(Team team) {
+ if(!teams.contains(team) && team.getName() != null && team.getUuid() != null && !team.getAllPlayers().isEmpty()) {
+ teams.add(team);
+ }
+ }
+
+ public List getAllTeams() {
+ return teams;
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/Team.java b/src/main/java/de/j/stationofdoom/teams/Team.java
new file mode 100644
index 00000000..92e3b882
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/Team.java
@@ -0,0 +1,307 @@
+package de.j.stationofdoom.teams;
+
+import de.j.deathMinigames.database.DBTeamMember;
+import de.j.deathMinigames.database.TeamEnderchestsDatabase;
+import de.j.deathMinigames.database.TeamsDatabase;
+import de.j.deathMinigames.main.HandlePlayers;
+import de.j.deathMinigames.main.PlayerData;
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.enderchest.EnderchestInvHolder;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
+
+
+public class Team {
+ private String name;
+ private Material colorAsMaterial;
+ private String colorAsString;
+ private boolean locked;
+ public volatile Inventory inventory;
+ private final EnderchestInvHolder enderchestInvHolder = new EnderchestInvHolder();
+ private final HashMap members = new HashMap<>();
+ private UUID uuid;
+ private Location protectedLocation;
+
+ public void addToMembers(UUID uuid, boolean isOperator) {
+ Main.getMainLogger().info("Adding member: " + uuid + " " + isOperator);
+ this.members.put(uuid, isOperator);
+ }
+
+ public void removeFromMembers(UUID uuid) {
+ Main.getMainLogger().info("Removing member: " + uuid);
+ this.members.remove(uuid);
+ }
+
+ public boolean isDeleted() {
+ return deleted;
+ }
+
+ private volatile boolean deleted = false;
+
+ public Team(String name, String colorAsString, boolean locked, String uuid, Location protectedLocation) {
+ init(name, UUID.fromString(uuid), Material.valueOf(colorAsString));
+ convertMaterialToString(this.colorAsMaterial);
+ this.locked = locked;
+ this.inventory.setContents(TeamEnderchestsDatabase.getInstance().getTeamEnderchest(this.getUuid()).getContents());
+ if (protectedLocation != null && protectedLocation.getWorld() != null) {
+ this.protectedLocation = protectedLocation;
+ }
+ }
+
+ public Team(String name, String colorAsString, boolean locked, String uuid, String world, int x, int y, int z) {
+ init(name, UUID.fromString(uuid), Material.valueOf(colorAsString));
+ convertMaterialToString(this.colorAsMaterial);
+ this.locked = locked;
+ this.inventory.setContents(TeamEnderchestsDatabase.getInstance().getTeamEnderchest(this.getUuid()).getContents());
+ if(world != null) {
+ this.protectedLocation = new Location(Bukkit.getWorld(world), x, y, z);
+ }
+ }
+
+ public Team(String name, String colorAsString, boolean locked, String uuid) {
+ init(name, UUID.fromString(uuid), Material.valueOf(colorAsString));
+ convertMaterialToString(this.colorAsMaterial);
+ this.locked = locked;
+ this.inventory.setContents(TeamEnderchestsDatabase.getInstance().getTeamEnderchest(this.getUuid()).getContents());
+ }
+
+ // used to create a new team without any operators
+ public Team() {
+ uuid = UUID.randomUUID();
+ addToList();
+ }
+
+ public Team(PlayerData playerData) {
+ init(playerData.getName() + "'s Team", UUID.randomUUID(), getRandomConcreteMaterial());
+ this.inventory.setContents(TeamEnderchestsDatabase.getInstance().getTeamEnderchest(this.getUuid()).getContents());
+ handlePlayerLeaveOrJoin(playerData);
+ setTeamOperator(HandlePlayers.getInstance().getPlayerData(playerData.getUniqueId()), true);
+ }
+
+ public Team(Player player) {
+ init(player.getName() + "'s Team", UUID.randomUUID(), getRandomConcreteMaterial());
+ this.inventory.setContents(TeamEnderchestsDatabase.getInstance().getTeamEnderchest(this.getUuid()).getContents());
+ handlePlayerLeaveOrJoin(HandlePlayers.getInstance().getPlayerData(player.getUniqueId()));
+ setTeamOperator(HandlePlayers.getInstance().getPlayerData(player.getUniqueId()), true);
+ }
+
+ private void init(String name, UUID uuid, Material colorAsMaterial) {
+ this.name = name;
+ this.uuid = uuid;
+ this.colorAsMaterial = colorAsMaterial;
+ this.inventory = Bukkit.createInventory(this.enderchestInvHolder, 27, name);
+ addToList();
+ }
+
+ public List getMembers() {
+ List members = new ArrayList<>();
+ for (UUID uuid : this.members.keySet()) {
+ PlayerData playerData = HandlePlayers.getInstance().getPlayerData(uuid);
+ if(isTeamOperator(playerData)) continue;
+ members.add(playerData);
+ }
+ return members;
+ }
+
+ public void addMember(DBTeamMember member) {
+ if(member.isInTeam) this.members.put(member.uuid, member.isTeamOperator);
+ }
+
+ public List getTeamOperators() {
+ List teamOperators = new ArrayList<>();
+ for (UUID uuid : this.members.keySet()) {
+ PlayerData playerData = HandlePlayers.getInstance().getPlayerData(uuid);
+ if(this.members.get(uuid)) teamOperators.add(playerData);
+ }
+ return teamOperators;
+ }
+
+ public List getAllPlayers() {
+ return members.keySet().stream().toList();
+ }
+
+ public boolean getLocked() {
+ return locked;
+ }
+
+ public void setLocked(boolean locked) {
+ if(getTeamOperators().isEmpty()) {
+ Main.getMainLogger().info("Team is not locked because there are no operators");
+ return;
+ }
+ this.locked = locked;
+ }
+
+ public Material getColorAsMaterial() {
+ return colorAsMaterial;
+ }
+
+ public void setColorAsMaterial(Material colorAsMaterial) {
+ this.colorAsMaterial = colorAsMaterial;
+ convertMaterialToString(colorAsMaterial);
+ }
+
+ private void convertMaterialToString(Material material) {
+ String color = material.toString();
+ color = color.replace("_CONCRETE", "");
+ this.colorAsString = color;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ private Material getRandomConcreteMaterial() {
+ List materials = new ArrayList<>();
+ for (Material material : Material.values()) {
+ if (material.name().contains("CONCRETE") && !material.name().contains("POWDER")) {
+ materials.add(material);
+ }
+ }
+ return materials.get(ThreadLocalRandom.current().nextInt(0, materials.size()));
+ }
+
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ public void handlePlayerLeaveOrJoin(PlayerData playerData) {
+ if(this.members.containsKey(playerData.getUniqueId())) {
+ if(getAllPlayers().size() <= 1) {
+ this.remove();
+ }
+ else {
+ removeMember(playerData);
+ }
+ }
+ else {
+ HandleTeams.removePlayerFromEveryTeam(playerData);
+ this.members.put(playerData.getUniqueId(), false);
+ playerData.setUuidOfTeam(this.getUuid());
+ playerData.setInTeam(true);
+ }
+ }
+
+ public void removeMember(PlayerData playerData) {
+ if(this.members.containsKey(playerData.getUniqueId())) {
+ if(getTeamOperators().contains(playerData) && getTeamOperators().size() == 1) {
+ setLocked(false);
+ }
+ this.members.remove(playerData.getUniqueId());
+ playerData.setUuidOfTeam(null);
+ playerData.setInTeam(false);
+ Main.getMainLogger().warning("Removed player " + playerData.getName());
+ if(this.members.isEmpty()) {
+ TeamsMainMenuGUI.teams.remove(this);
+ }
+ }
+ }
+
+ public void remove() {
+ Main.getMainLogger().info("Removing team " + this.name);
+ TeamsDatabase.getInstance().removeTeam(this);
+ this.deleted = true;
+ if (this.inventory != null && !this.inventory.isEmpty()) {
+ Location loc;
+ Main.getMainLogger().warning("Team " + this.name + " is being removed but has items in its ender chest, dropping items to first operator");
+ if (!getTeamOperators().isEmpty()) {
+ loc = getTeamOperators().getFirst().getLocation();
+ try {
+ for (ItemStack itemStack : this.inventory.getContents()) {
+ if (itemStack == null) continue;
+ loc.getWorld().dropItem(loc, itemStack);
+ }
+ }
+ catch (Exception e) {
+ Main.getMainLogger().severe("Could not drop enderchest items for team " + this.name);
+ e.printStackTrace();
+ }
+ } else {
+ Main.getMainLogger().warning("Team has no operators, dropping items to first member");
+ if (!getAllPlayers().isEmpty()) {
+ loc = HandlePlayers.getInstance().getPlayerData(getAllPlayers().getFirst()).getLocation();
+ try {
+ for (ItemStack itemStack : this.inventory.getContents()) {
+ if (itemStack == null) continue;
+ loc.getWorld().dropItem(loc, itemStack);
+ }
+ }
+ catch (Exception e) {
+ Main.getMainLogger().severe("Could not drop enderchest items for team " + this.name);
+ e.printStackTrace();
+ }
+ }
+ else Main.getMainLogger().warning("Team has no members, can not drop items");
+ }
+ }
+ this.members.clear();
+ TeamsMainMenuGUI.teams.remove(this);
+ if(this.inventory != null && !this.inventory.isEmpty()) {
+ this.inventory.clear();
+ }
+
+ Main.getMainLogger().info("Removed team " + this.name);
+ }
+
+ public void setTeamOperator(PlayerData playerData, boolean value) {
+ if(this.members.containsKey(playerData.getUniqueId())) {
+ this.members.put(playerData.getUniqueId(), value);
+ }
+ if(getTeamOperators().isEmpty()) this.locked = false;
+ }
+
+ public boolean isTeamOperator(PlayerData playerData) {
+ if(!this.members.containsKey(playerData.getUniqueId())) return false;
+ return this.members.containsKey(playerData.getUniqueId()) && this.members.get(playerData.getUniqueId());
+ }
+
+ public void accessEnderChest(Player player) {
+ if(!this.members.containsKey(player.getUniqueId())) return;
+ player.openInventory(this.inventory);
+ }
+
+ public boolean isMember(UUID uuidOfPlayerToCheck) {
+ if (uuidOfPlayerToCheck == null) {
+ return false;
+ }
+ for (UUID uuid : this.members.keySet()) {
+ if(uuid.equals(uuidOfPlayerToCheck)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setProtectedLocation(Location location) {
+ this.protectedLocation = location;
+ }
+
+ public Location getProtectedLocation() {
+ return this.protectedLocation;
+ }
+
+ private void addToList() {
+ HandleTeams.addTeam(this);
+ }
+
+ public String getColorAsString() {
+ if(colorAsString == null) {
+ convertMaterialToString(this.colorAsMaterial);
+ }
+ return colorAsString;
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/TeamCMD.java b/src/main/java/de/j/stationofdoom/teams/TeamCMD.java
new file mode 100644
index 00000000..30dd668d
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/TeamCMD.java
@@ -0,0 +1,25 @@
+package de.j.stationofdoom.teams;
+
+import de.j.stationofdoom.util.translations.TranslationFactory;
+import io.papermc.paper.command.brigadier.BasicCommand;
+import io.papermc.paper.command.brigadier.CommandSourceStack;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.entity.Player;
+
+
+public class TeamCMD implements BasicCommand {
+ @Override
+ public void execute(CommandSourceStack stack, String[] args) {
+ if (!(stack.getSender() instanceof Player player)) {
+ return;
+ }
+ Team team = HandleTeams.getTeamFromPlayerUUID(player.getUniqueId());
+ if (!team.isMember(player.getUniqueId())) {
+ player.sendMessage(Component.text(new TranslationFactory().getTranslation(player, "TeamCMDNoTeam"))
+ .color(NamedTextColor.RED));
+ return;
+ }
+ new TeamSettingsGUI(team).showPage(1, player);
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/TeamInventoryReload.java b/src/main/java/de/j/stationofdoom/teams/TeamInventoryReload.java
new file mode 100644
index 00000000..37c2349b
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/TeamInventoryReload.java
@@ -0,0 +1,45 @@
+package de.j.stationofdoom.teams;
+
+import de.j.deathMinigames.settings.GUI;
+import de.j.stationofdoom.main.Main;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryOpenEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.scheduler.BukkitRunnable;
+
+public class TeamInventoryReload implements Listener {
+ private static final int secondsBetweenReloads = 3;
+
+ @EventHandler
+ public void onInventoryOpen(InventoryOpenEvent event) {
+ if(event.getInventory().getHolder() instanceof TeamsMainMenuGUI || event.getInventory().getHolder() instanceof TeamSettingsGUI) {
+ GUI gui = (GUI) event.getInventory().getHolder();
+ Player viewer = (Player) event.getPlayer();
+ Inventory inv = event.getInventory();
+ startTimer(inv, gui, viewer);
+ }
+ }
+
+ private void startTimer(Inventory inv, GUI gui, Player viewer) {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if(!inv.getViewers().contains(viewer)) {
+ cancel();
+ }
+ else {
+ int currentPage = inv.getItem(53).getAmount() - 1;
+ if(gui instanceof TeamsMainMenuGUI teamsMainMenuGUI) {
+ teamsMainMenuGUI.showPage(currentPage, viewer);
+ }
+ else if(gui instanceof TeamSettingsGUI teamSettingsGUI) {
+ teamSettingsGUI.showPage(currentPage, viewer);
+ }
+ cancel();
+ }
+ }
+ }.runTaskTimer(Main.getPlugin(), 10, secondsBetweenReloads * 20);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/j/stationofdoom/teams/TeamPlayerSettingsGUI.java b/src/main/java/de/j/stationofdoom/teams/TeamPlayerSettingsGUI.java
new file mode 100644
index 00000000..bc57e568
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/TeamPlayerSettingsGUI.java
@@ -0,0 +1,65 @@
+package de.j.stationofdoom.teams;
+
+import de.j.deathMinigames.main.PlayerData;
+import de.j.deathMinigames.settings.GUI;
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.util.translations.TranslationFactory;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.InventoryHolder;
+
+import java.util.ArrayList;
+
+public class TeamPlayerSettingsGUI extends GUI {
+ private TranslationFactory tf = new TranslationFactory();
+ private volatile PlayerData playerData;
+ private volatile Team team;
+
+ public TeamPlayerSettingsGUI() {
+
+ }
+
+ public void showInventory(Player playerToShowTheInvTo, PlayerData playerDataBasedOnSlot) {
+ this.playerData = playerDataBasedOnSlot;
+ fillInv(playerToShowTheInvTo, playerDataBasedOnSlot);
+ playerToShowTheInvTo.openInventory(inventory);
+ }
+
+ private void fillInv(Player playerToShowTheInvTo,PlayerData playerDataBasedOnSlot) {
+ this.inventory = Bukkit.createInventory(this, 18, playerDataBasedOnSlot.getName());
+ Team team = HandleTeams.getTeam(playerDataBasedOnSlot);
+ if(team == null) {
+ Main.getMainLogger().warning("Team is null in fillInv");
+ return;
+ }
+ this.team = team;
+ boolean isOperator = team.isTeamOperator(playerDataBasedOnSlot);
+ this.inventory.clear();
+ for (int i = 0; i < 9; i++) {
+ if (i == 4) continue;
+ if (isOperator) {
+ addClickableItemStack("", Material.GREEN_STAINED_GLASS_PANE, 1, i);
+ } else {
+ addClickableItemStack("", Material.WHITE_STAINED_GLASS_PANE, 1, i);
+ }
+ }
+ addPlayerHead(playerDataBasedOnSlot, 4, new ArrayList<>());
+ if(isOperator) {
+ addClickableItemStack(tf.getTranslation(playerToShowTheInvTo, "teamPlayerSettingsDemoteToMember"), Material.ENDER_EYE, 1, 9);
+ }
+ else {
+ addClickableItemStack(tf.getTranslation(playerToShowTheInvTo, "teamPlayerSettingsPromoteToOperator"), Material.ENDER_PEARL, 1, 9);
+ }
+ addClickableItemStack(tf.getTranslation(playerToShowTheInvTo, "teamPlayerSettingsKickPlayer"), Material.BARRIER, 1, 10);
+ addClickableItemStack(tf.getTranslation(playerToShowTheInvTo, "backButton"), Material.RED_CONCRETE, 1, 17);
+ }
+
+ public PlayerData getPlayerData() {
+ return playerData;
+ }
+
+ public Team getTeam() {
+ return team;
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/TeamSettingsGUI.java b/src/main/java/de/j/stationofdoom/teams/TeamSettingsGUI.java
new file mode 100644
index 00000000..44ba603d
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/TeamSettingsGUI.java
@@ -0,0 +1,141 @@
+package de.j.stationofdoom.teams;
+
+import de.j.deathMinigames.main.HandlePlayers;
+import de.j.deathMinigames.main.PlayerData;
+import de.j.deathMinigames.settings.AnvilUI;
+import de.j.deathMinigames.settings.GUI;
+import de.j.deathMinigames.settings.MainMenu;
+import de.j.stationofdoom.util.translations.TranslationFactory;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class TeamSettingsGUI extends GUI {
+ private final TranslationFactory tf = new TranslationFactory();
+ private final Team team;
+ private final int inventorySize = 54;
+ private final int maxSlotsPerPage = 27;
+ private volatile ConcurrentHashMap invSlots = new ConcurrentHashMap<>();
+ private int pagesBasedOnMemberQuantity;
+ private volatile List members;
+ private volatile float memberQuantity;
+ private final int startSlotToFill = 18;
+ public static AnvilUI renameTeam = new AnvilUI(MainMenu.AnvilUIs.TEAM_RENAME);
+ public static GUI colorChanger = new GUI("Color changer", false, false, 2 * 9);
+
+ public TeamSettingsGUI(Team team) {
+ this.team = team;
+ }
+
+ public void showPage(int page, Player playerToShowTheInvTo) {
+ this.inventory = null;
+ this.inventory = Bukkit.createInventory(this, inventorySize, team.getName() +" - " + tf.getTranslation(playerToShowTheInvTo, "page") + " " + page );
+ if(this.team.isDeleted()) {
+ playerToShowTheInvTo.sendMessage(Component.text(tf.getTranslation(playerToShowTheInvTo, "teamDeleted", team.getName())).color(NamedTextColor.RED));
+ new TeamsMainMenuGUI().showPage(1, playerToShowTheInvTo);
+ return;
+ }
+ members = team.getAllPlayers();
+ if(!members.isEmpty()) {
+ memberQuantity = team.getAllPlayers().size();
+ pagesBasedOnMemberQuantity = (int) Math.ceil(memberQuantity / maxSlotsPerPage);
+ fillPage(page);
+ }
+ if(members.contains(playerToShowTheInvTo.getUniqueId())) {
+ addClickableItemStack(tf.getTranslation(playerToShowTheInvTo, "leaveTeam"), Material.BARRIER, 1, 45);
+ }
+ else {
+ addClickableItemStack(tf.getTranslation(playerToShowTheInvTo, "joinTeam"), Material.END_CRYSTAL, 1, 45);
+ }
+ if(page == 1) {
+ addClickableItemStack(tf.getTranslation(playerToShowTheInvTo, "alreadyFirstPage"), Material.BARRIER, 1, 52);
+ }
+ else {
+ addClickableItemStack(tf.getTranslation(playerToShowTheInvTo, "lastPage"), Material.COPPER_BULB, page - 1, 52);
+ }
+ addClickableItemStack(tf.getTranslation(playerToShowTheInvTo, "nextPage"), Material.OXIDIZED_COPPER_BULB, page + 1, 53);
+ addTopBarToInventory();
+ addFunctionsToInventory(playerToShowTheInvTo);
+ playerToShowTheInvTo.openInventory(this.inventory);
+ }
+
+ private void fillPage(int page) {
+ float intToStartFrom = (page * maxSlotsPerPage) - maxSlotsPerPage;
+ addPlayersToInventory((int) intToStartFrom);
+ }
+
+ private void addPlayersToInventory(int intToStartFrom) {
+ invSlots.clear();
+ for(int playersAdded = 0; playersAdded < maxSlotsPerPage; playersAdded++) {
+ if(playersAdded >= memberQuantity || playersAdded >= maxSlotsPerPage || intToStartFrom + playersAdded >= memberQuantity) return;
+ PlayerData currentPlayerData = HandlePlayers.getInstance().getPlayerData(members.get(intToStartFrom + playersAdded));
+ ArrayList lore = new ArrayList<>();
+ lore.add("Operator: " + team.isTeamOperator(currentPlayerData));
+ if(!currentPlayerData.isOnline()) {
+ lore.add("Offline");
+ }
+ else {
+ lore.add("Online");
+ }
+ addPlayerHead(currentPlayerData, playersAdded + startSlotToFill, lore);
+ invSlots.put(playersAdded + startSlotToFill, currentPlayerData);
+ }
+ }
+
+ public int getPagesQuantity() {
+ return pagesBasedOnMemberQuantity;
+ }
+
+ public Team getTeam() {
+ return team;
+ }
+
+ public PlayerData getMemberBasedOnSlot(int slot) {
+ PlayerData playerBasedOnSlot = invSlots.get(slot);
+ if(playerBasedOnSlot == null) {
+ return null;
+ }
+ return playerBasedOnSlot;
+ }
+
+ private void addTopBarToInventory() {
+ String colorAsGlassPane = team.getColorAsMaterial().toString().replace("_CONCRETE", "_STAINED_GLASS_PANE");
+ Material material = Material.getMaterial(colorAsGlassPane);
+ if(material == null) material = Material.WHITE_STAINED_GLASS_PANE;
+ for (int i = 0; i < 9; i++) {
+ addClickableItemStack(team.getName(), material, 1, i);
+ }
+ addClickableItemStack(team.getName(), team.getColorAsMaterial(), 1, 4);
+ }
+
+ private void addFunctionsToInventory(Player player) {
+ addClickableItemStack(tf.getTranslation(player, "renameTeam"), Material.NAME_TAG, 1, 9);
+ addClickableItemStack(tf.getTranslation(player, "changeColor"), Material.ORANGE_GLAZED_TERRACOTTA, 1, 10);
+ ArrayList lockedTeamSettingsLore = new ArrayList<>();
+ lockedTeamSettingsLore.add(tf.getTranslation(player, "lockedTeamSettingsLore"));
+ if(team.getLocked()) {
+ addClickableItemStack(tf.getTranslation(player, "lockTeamSettings"), Material.OMINOUS_TRIAL_KEY, 1, 11, lockedTeamSettingsLore);
+ }
+ else {
+ addClickableItemStack(tf.getTranslation(player, "lockTeamSettings"), Material.TRIAL_KEY, 1, 11, lockedTeamSettingsLore);
+ }
+ ArrayList teamEnderChestLore = new ArrayList<>();
+ teamEnderChestLore.add(tf.getTranslation(player, "teamEnderChestLore"));
+ addClickableItemStack(tf.getTranslation(player, "teamEnderChest"), Material.ENDER_CHEST, 1, 12, teamEnderChestLore);
+ ArrayList teamClaimChunksLore = new ArrayList<>();
+ teamClaimChunksLore.add(tf.getTranslation(player, "teamClaimChunksLore"));
+ if(team.getProtectedLocation() != null) {
+ addClickableItemStack(tf.getTranslation(player, "teamClaimChunksProtectedLocation", team.getProtectedLocation().getBlockX(), team.getProtectedLocation().getBlockY(), team.getProtectedLocation().getBlockZ()), Material.FILLED_MAP, 1, 13, teamClaimChunksLore);
+ }
+ else {
+ addClickableItemStack(tf.getTranslation(player, "teamClaimChunks"), Material.MAP, 1, 13, teamClaimChunksLore);
+ }
+ addClickableItemStack(tf.getTranslation(player, "deleteTeam"), Material.COMPOSTER, 1, 17);
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/TeamSettingsInventoryListener.java b/src/main/java/de/j/stationofdoom/teams/TeamSettingsInventoryListener.java
new file mode 100644
index 00000000..c3245e25
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/TeamSettingsInventoryListener.java
@@ -0,0 +1,308 @@
+package de.j.stationofdoom.teams;
+
+import de.j.deathMinigames.main.HandlePlayers;
+import de.j.deathMinigames.main.PlayerData;
+import de.j.deathMinigames.settings.GUI;
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.chunkClaimSystem.ChunkClaimSystem;
+import de.j.stationofdoom.util.translations.TranslationFactory;
+import net.kyori.adventure.sound.Sound;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.Bukkit;
+import org.bukkit.Effect;
+import org.bukkit.EntityEffect;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+
+import static io.papermc.paper.registry.keys.SoundEventKeys.*;
+
+public class TeamSettingsInventoryListener implements Listener {
+ TranslationFactory tf = new TranslationFactory();
+
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ if (event.getClickedInventory() == null) return;
+ InventoryHolder invHolder = event.getClickedInventory().getHolder();
+ if (invHolder instanceof TeamSettingsGUI || invHolder instanceof TeamsMainMenuGUI) {
+ event.setCancelled(true);
+ int slot = event.getSlot();
+ Inventory inv = event.getClickedInventory();
+ Player player = (Player) event.getWhoClicked();
+ if (player == null) return;
+ PlayerData playerData = HandlePlayers.getInstance().getPlayerData(player.getUniqueId());
+ if (event.getClickedInventory().getItem(53) == null) return;
+ int currentPage = event.getClickedInventory().getItem(53).getAmount() - 1;
+ int lastPage = currentPage - 1;
+ int nextPage = currentPage + 1;
+ if (invHolder instanceof TeamsMainMenuGUI) {
+ handleTeamsMainMenuGUI(slot, inv, invHolder, player, currentPage, lastPage, nextPage);
+ }
+ else {
+ handleTeamSettingsGUI(slot, inv, invHolder, player, playerData, currentPage, lastPage, nextPage);
+ }
+ }
+ else if (invHolder instanceof GUI) {
+ GUI colorChanger = (GUI) invHolder;
+ event.setCancelled(true);
+ int slot = event.getSlot();
+ Inventory inv = event.getClickedInventory();
+ Player player = (Player) event.getWhoClicked();
+ if (player == null) return;
+ if(colorChanger.getUUID() == TeamSettingsGUI.colorChanger.getUUID()) {
+ if(slot < 0 || slot > 15) return;
+ handleColorChanger(slot, inv, player);
+ }
+ if(invHolder instanceof TeamPlayerSettingsGUI) {
+ handleTeamPlayerSettingsGUI(slot, invHolder, player);
+ }
+ }
+ }
+
+ private void handleTeamsMainMenuGUI(int slot, Inventory inv, InventoryHolder invHolder, Player player, int currentPage, int lastPage, int nextPage) {
+ TeamsMainMenuGUI teamsMainMenuGUI = (TeamsMainMenuGUI) invHolder;
+ switch (slot) {
+ case -999:
+ return;
+ case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44:
+ if (inv.getItem(slot) == null) {
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_PLACE, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ return;
+ }
+ Team currentTeam = teamsMainMenuGUI.getTeamBasedOnSlot(slot);
+ if (currentTeam == null) return;
+ TeamSettingsGUI teamSettingsGUI = new TeamSettingsGUI(currentTeam);
+ teamSettingsGUI.showPage(1, player);
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_PLACE, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ break;
+ case 45:
+ teamsMainMenuGUI.addTeam(player);
+ teamsMainMenuGUI.showPage(teamsMainMenuGUI.getPagesQuantity(), player);
+ player.playSound(Sound.sound(BLOCK_AMETHYST_BLOCK_PLACE, Sound.Source.PLAYER, 1F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ break;
+ case 52:
+ if (currentPage == 1) {
+ return;
+ } else {
+ teamsMainMenuGUI.showPage(lastPage, player);
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_TURN_ON, Sound.Source.PLAYER, 2F, 1), net.kyori.adventure.sound.Sound.Emitter.self()); }
+ break;
+ case 53:
+ if (currentPage == teamsMainMenuGUI.getPagesQuantity() || teamsMainMenuGUI.getPagesQuantity() == 1 || teamsMainMenuGUI.getPagesQuantity() == 0) {
+ return;
+ }
+ else {
+ teamsMainMenuGUI.showPage(nextPage, player);
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_TURN_ON, Sound.Source.PLAYER, 2F, 1), net.kyori.adventure.sound.Sound.Emitter.self()); }
+ break;
+ default:
+ if (inv.getItem(slot) == null) player.playSound(Sound.sound(BLOCK_COPPER_BULB_PLACE, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+ }
+
+ private void handleTeamSettingsGUI(int slot, Inventory inv, InventoryHolder invHolder, Player player, PlayerData playerData, int currentPage, int lastPage, int nextPage) {
+ TeamSettingsGUI teamSettingsGUI = (TeamSettingsGUI) invHolder;
+ Team team = teamSettingsGUI.getTeam();
+ handleTeamSettingsGUIChecking(slot, player, team, teamSettingsGUI, currentPage, inv);
+ switch (slot) {
+ case -999:
+ return;
+ case 0, 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 16, 46, 47, 48, 49, 50, 51:
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_PLACE, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ break;
+ case 9:
+ TeamSettingsGUI.renameTeam.showInventory(player);
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_TURN_ON, Sound.Source.PLAYER, 2F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ break;
+ case 10:
+ addColorsToColorChanger(TeamSettingsGUI.colorChanger.getInventory());
+ TeamSettingsGUI.colorChanger.showInventory(player);
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_TURN_ON, Sound.Source.PLAYER, 2F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ break;
+ case 11:
+ handleTeamSettingsGUICase11(team, player, teamSettingsGUI, currentPage);
+ break;
+ case 12:
+ team.accessEnderChest(player);
+ player.playSound(Sound.sound(BLOCK_CHEST_OPEN, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ break;
+ case 13:
+ ChunkClaimSystem.getInstance().playerClaim(player, team, player.getLocation());
+ player.playSound(Sound.sound(BLOCK_AMETHYST_BLOCK_RESONATE, Sound.Source.PLAYER, 1F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ break;
+ case 17:
+ team.remove();
+ new TeamsMainMenuGUI().showPage(1, player);
+ player.playSound(Sound.sound(BLOCK_AMETHYST_BLOCK_BREAK, Sound.Source.PLAYER, 1F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ break;
+ case 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44:
+ handleTeamSettingsGUICase18To44(inv, slot, player, teamSettingsGUI);
+ break;
+ case 45:
+ handleTeamSettingsGUICase45(team, player, teamSettingsGUI, currentPage, playerData);
+ break;
+ case 52:
+ handleTeamSettingsGUICase52(currentPage, player, teamSettingsGUI, lastPage);
+ break;
+ case 53:
+ if (currentPage == teamSettingsGUI.getPagesQuantity() || teamSettingsGUI.getPagesQuantity() == 1 || teamSettingsGUI.getPagesQuantity() == 0) {
+ return;
+ } else {
+ teamSettingsGUI.showPage(nextPage, player);
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_TURN_ON, Sound.Source.PLAYER, 2F, 1), net.kyori.adventure.sound.Sound.Emitter.self()); }
+ break;
+ default:
+ }
+ }
+
+ private void handleTeamSettingsGUIChecking(int slot, Player player, Team team, TeamSettingsGUI teamSettingsGUI, int currentPage, Inventory inv) {
+ if(slot != 45) {
+ if(player.getUniqueId() == null) {
+ Main.getMainLogger().info("Player is null in TeamSettingsInventoryListener");
+ return;
+ }
+ if(!team.isMember(player.getUniqueId())) {
+ player.sendMessage(Component.text(tf.getTranslation(player, "teamNotAMember")).color(NamedTextColor.RED));
+ player.playSound(Sound.sound(BLOCK_AMETHYST_CLUSTER_BREAK, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ return;
+ }
+ }
+ if(slot >= 9 && slot <=13 || slot == 17 || slot >= 18 && slot <= 44 && inv.getItem(slot) != null) {
+ if(team.getLocked() && !team.isTeamOperator(HandlePlayers.getInstance().getPlayerData(player.getUniqueId()))) {
+ player.sendMessage(Component.text(tf.getTranslation(player, "teamLockedAndNotOperator")).color(NamedTextColor.RED));
+ player.playSound(Sound.sound(BLOCK_AMETHYST_CLUSTER_BREAK, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ teamSettingsGUI.showPage(currentPage, player);
+ }
+ }
+ }
+
+ private void handleTeamSettingsGUICase11(Team team, Player player, TeamSettingsGUI teamSettingsGUI, int currentPage) {
+ team.setLocked(!team.getLocked());
+ teamSettingsGUI.showPage(currentPage, player);
+ if(team.getLocked()) {
+ player.playSound(Sound.sound(BLOCK_IRON_DOOR_CLOSE, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+ else {
+ player.playSound(Sound.sound(BLOCK_IRON_DOOR_OPEN, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+ }
+
+ private void handleTeamSettingsGUICase18To44(Inventory inv, int slot, Player player, TeamSettingsGUI teamSettingsGUI) {
+ if (inv.getItem(slot) == null) {
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_PLACE, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ return;
+ }
+ PlayerData playerBasedOnSlot = teamSettingsGUI.getMemberBasedOnSlot(slot);
+ if(playerBasedOnSlot == null) return;
+ new TeamPlayerSettingsGUI().showInventory(player, playerBasedOnSlot);
+ player.playSound(Sound.sound(BLOCK_ENDER_CHEST_OPEN, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+
+ private void handleTeamSettingsGUICase45(Team team, Player player, TeamSettingsGUI teamSettingsGUI, int currentPage, PlayerData playerData) {
+ if(team.getLocked() && !team.isMember(player.getUniqueId())) {
+ player.sendMessage(Component.text(tf.getTranslation(player, "teamLocked")).color(NamedTextColor.RED));
+ return;
+ }
+ if(team.isMember(player.getUniqueId())) player.playSound(Sound.sound(BLOCK_AMETHYST_BLOCK_BREAK, Sound.Source.PLAYER, 1F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ else player.playSound(net.kyori.adventure.sound.Sound.sound(BLOCK_CHISELED_BOOKSHELF_INSERT_ENCHANTED, net.kyori.adventure.sound.Sound.Source.PLAYER, 3F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ team.handlePlayerLeaveOrJoin(playerData);
+ if(!team.getAllPlayers().isEmpty()) {
+ teamSettingsGUI.showPage(currentPage, player);
+ }
+ else {
+ new TeamsMainMenuGUI().showPage(1, player);
+ }
+ }
+
+ private void handleTeamSettingsGUICase52(int currentPage, Player player, TeamSettingsGUI teamSettingsGUI, int lastPage) {
+ if (currentPage != 1) {
+ teamSettingsGUI.showPage(lastPage, player);
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_TURN_ON, Sound.Source.PLAYER, 2F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+ }
+
+ private void handleColorChanger(int slot, Inventory inv, Player player) {
+ Material clickedColor = inv.getItem(slot).getType();
+ Team teamToChangeColor = HandleTeams.getTeam(HandlePlayers.getInstance().getPlayerData(player.getUniqueId()));
+ if(teamToChangeColor == null) return;
+ teamToChangeColor.setColorAsMaterial(clickedColor);
+ new TeamSettingsGUI(teamToChangeColor).showPage(1, player);
+ player.playSound(net.kyori.adventure.sound.Sound.sound(BLOCK_CHISELED_BOOKSHELF_INSERT_ENCHANTED, net.kyori.adventure.sound.Sound.Source.PLAYER, 3F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ player.playSound(Sound.sound(ITEM_BOOK_PAGE_TURN, Sound.Source.PLAYER, 1F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+
+ private void addColorsToColorChanger(Inventory colorChanger) {
+ int count = 0;
+ for (Material material : Material.values()) {
+ if (material.name().contains("CONCRETE") && !material.name().contains("POWDER")) {
+ ItemStack color = new ItemStack(material);
+ colorChanger.setItem(count, color);
+ count++;
+ }
+ }
+ }
+
+ private void handleTeamPlayerSettingsGUI(int slot, InventoryHolder invHolder, Player player) {
+ if(slot != 9 && slot != 10 && slot != 17) {
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_PLACE, Sound.Source.PLAYER, 0.5F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ return;
+ }
+ TeamPlayerSettingsGUI teamPlayerSettingsGUI = (TeamPlayerSettingsGUI) invHolder;
+ Team team = teamPlayerSettingsGUI.getTeam();
+ PlayerData playerData = HandlePlayers.getInstance().getPlayerData(player.getUniqueId());
+ PlayerData clickedOnPlayerData = teamPlayerSettingsGUI.getPlayerData();
+ if(team == null) return;
+ if(slot == 9 || slot == 10) {
+ if(!team.isTeamOperator(playerData) && team.getLocked()) {
+ player.sendMessage(Component.text(tf.getTranslation(player, "teamLockedAndNotOperator")).color(NamedTextColor.RED));
+ return;
+ }
+ }
+ switch (slot) {
+ case 9:
+ handleTeamPlayerSettingsGUICase9(team, player, clickedOnPlayerData);
+ break;
+ case 10:
+ handleTeamPlayerSettingsGUICase10(team, player, clickedOnPlayerData);
+ break;
+ case 17:
+ handleTeamPlayerSettingsGUICase17(team, player);
+ return;
+ }
+ if(!team.getAllPlayers().isEmpty()) {
+ teamPlayerSettingsGUI.showInventory(player, clickedOnPlayerData);
+ }
+ }
+
+ private void handleTeamPlayerSettingsGUICase9(Team team, Player player, PlayerData clickedOnPlayerData) {
+ player.playSound(Sound.sound(BLOCK_PISTON_CONTRACT, Sound.Source.PLAYER, 0.5F, 1), Sound.Emitter.self());
+ team.setTeamOperator(clickedOnPlayerData, !team.isTeamOperator(clickedOnPlayerData));
+ }
+
+ private void handleTeamPlayerSettingsGUICase10(Team team, Player player, PlayerData clickedOnPlayerData) {
+ team.removeMember(clickedOnPlayerData);
+ if(clickedOnPlayerData.isOnline()) {
+ clickedOnPlayerData.getPlayer().sendMessage(Component.text(tf.getTranslation(clickedOnPlayerData.getPlayer(), "kickedFromTeam", player.getName())).color(NamedTextColor.RED));
+ Bukkit.getPlayer(clickedOnPlayerData.getUniqueId()).playSound(Sound.sound(BLOCK_AMETHYST_BLOCK_RESONATE, Sound.Source.PLAYER, 1F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+ player.playSound(Sound.sound(BLOCK_COPPER_BULB_TURN_ON, Sound.Source.PLAYER, 2F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+
+ private void handleTeamPlayerSettingsGUICase17(Team team, Player player) {
+ if(!team.getAllPlayers().isEmpty()) {
+ new TeamSettingsGUI(team).showPage(1, player);
+ }
+ else {
+ new TeamsMainMenuGUI().showPage(1, player);
+ }
+ player.playSound(Sound.sound(ITEM_BOOK_PAGE_TURN, Sound.Source.PLAYER, 1F, 1), net.kyori.adventure.sound.Sound.Emitter.self());
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/TeamsCMD.java b/src/main/java/de/j/stationofdoom/teams/TeamsCMD.java
new file mode 100644
index 00000000..d12550f9
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/TeamsCMD.java
@@ -0,0 +1,30 @@
+package de.j.stationofdoom.teams;
+
+import de.j.deathMinigames.main.HandlePlayers;
+import io.papermc.paper.command.brigadier.BasicCommand;
+import io.papermc.paper.command.brigadier.CommandSourceStack;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public class TeamsCMD implements BasicCommand {
+ public TeamsMainMenuGUI teamsMainMenuGUI = new TeamsMainMenuGUI();
+
+ @Override
+ public boolean canUse(@NotNull CommandSender sender) {
+ return sender instanceof Player;
+ }
+
+ @Override
+ public void execute(CommandSourceStack stack, String[] args) {
+ Player player = (Player) stack.getSender();
+ if(args.length == 0) {
+ teamsMainMenuGUI.showPage(1, player);
+ }
+ else if(args.length == 1 && (args[0].equalsIgnoreCase("e") || args[0].equalsIgnoreCase("enderchest"))) {
+ Team team = HandleTeams.getTeam(HandlePlayers.getInstance().getPlayerData(player.getUniqueId()));
+ if(team == null || !team.isMember(player.getUniqueId())) return;
+ team.accessEnderChest(player);
+ }
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/TeamsMainMenuGUI.java b/src/main/java/de/j/stationofdoom/teams/TeamsMainMenuGUI.java
new file mode 100644
index 00000000..3ef1068e
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/TeamsMainMenuGUI.java
@@ -0,0 +1,111 @@
+package de.j.stationofdoom.teams;
+
+import de.j.deathMinigames.database.Database;
+import de.j.deathMinigames.main.PlayerData;
+import de.j.deathMinigames.settings.GUI;
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.util.translations.TranslationFactory;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class TeamsMainMenuGUI extends GUI {
+ public static volatile List teams = new ArrayList<>();
+ private final HashMap invSlots = new HashMap<>(); // for checking which team settings to open based on clicked slot
+ private float teamQuantity;
+ private final float maxSlotsPerPage = 45;
+ private int pagesBasedOnTeamsQuantity; // has to be greater than 0
+ private final int inventorySize = 54;
+ private final TranslationFactory tf = new TranslationFactory();
+
+ public TeamsMainMenuGUI() {
+ if(Database.getInstance().isConnected) {
+ teams = HandleTeams.getInstance().getAllTeams();
+ }
+ }
+
+ public List getTeams() {
+ return teams;
+ }
+
+ public void showPage(int page, Player player) {
+ this.inventory = null;
+ this.inventory = Bukkit.createInventory(this, inventorySize, "Teams - " + tf.getTranslation(player, "page") + " " + page );
+ if(!TeamsMainMenuGUI.teams.isEmpty()) {
+ teamQuantity = TeamsMainMenuGUI.teams.size();
+ pagesBasedOnTeamsQuantity = (int) Math.ceil(teamQuantity / maxSlotsPerPage);
+ fillPage(page);
+ }
+ addClickableItemStack(tf.getTranslation(player, "createTeam"), Material.CRAFTING_TABLE, 1, 45);
+ if(page == 1) {
+ addClickableItemStack(tf.getTranslation(player, "alreadyFirstPage"), Material.BARRIER, 1, 52);
+ }
+ else {
+ addClickableItemStack(tf.getTranslation(player, "lastPage"), Material.COPPER_BULB, page - 1, 52);
+ }
+ addClickableItemStack(tf.getTranslation(player, "nextPage"), Material.OXIDIZED_COPPER_BULB, page + 1, 53);
+ player.openInventory(this.inventory);
+ }
+
+ private void fillPage(int page) {
+ float intToStartFrom = (page * maxSlotsPerPage) - maxSlotsPerPage;
+ addTeamsToInventory((int) intToStartFrom);
+ }
+
+ private void addTeamsToInventory(int intToStartFrom) {
+ invSlots.clear();
+ for(int teamsAdded = 0; teamsAdded < maxSlotsPerPage; teamsAdded++) {
+ if(teamsAdded >= teamQuantity || teamsAdded >= maxSlotsPerPage || intToStartFrom + teamsAdded >= teamQuantity) return;
+ Team currentTeam = TeamsMainMenuGUI.teams.get(intToStartFrom + teamsAdded);
+ ArrayList lore = getTeamInformation(currentTeam);
+ addClickableItemStack(currentTeam.getName(), currentTeam.getColorAsMaterial(), 1, teamsAdded, lore);
+ invSlots.put(teamsAdded, currentTeam);
+ }
+ }
+
+ private ArrayList getTeamInformation(Team currentTeam) {
+ ArrayList lore = new ArrayList<>();
+ if(!currentTeam.getTeamOperators().isEmpty()) {
+ lore.add("Team Operators:");
+ for (PlayerData playerData : currentTeam.getTeamOperators()) {
+ lore.add(" " + playerData.getName());
+ }
+ }
+ if(!currentTeam.getMembers().isEmpty()) {
+ lore.add("Team Members:");
+ for (PlayerData playerData : currentTeam.getMembers()) {
+ lore.add(" " + playerData.getName());
+ }
+ }
+ if(currentTeam.getProtectedLocation() == null) {
+ lore.add("No Claimed Location");
+ }
+ else {
+ lore.add("Claimed Location:");
+ lore.add(" X: " + currentTeam.getProtectedLocation().getBlockX() + " Z: " + currentTeam.getProtectedLocation().getBlockZ());
+ }
+ return lore;
+ }
+
+ public void addTeam(Player creatorOfTeam) {
+ new Team(creatorOfTeam);
+ }
+
+ public int getPagesQuantity() {
+ if(pagesBasedOnTeamsQuantity == 0) return 1;
+ else return pagesBasedOnTeamsQuantity;
+ }
+
+ public Team getTeamBasedOnSlot(int slot) {
+ Team teamBasedOnSlot = invSlots.get(slot);
+ if(teamBasedOnSlot == null) {
+ return null;
+ }
+ return teamBasedOnSlot;
+ }
+
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/chunkClaimSystem/BlockBreakAndUseCancelListener.java b/src/main/java/de/j/stationofdoom/teams/chunkClaimSystem/BlockBreakAndUseCancelListener.java
new file mode 100644
index 00000000..58e6319f
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/chunkClaimSystem/BlockBreakAndUseCancelListener.java
@@ -0,0 +1,30 @@
+package de.j.stationofdoom.teams.chunkClaimSystem;
+
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.Team;
+import de.j.stationofdoom.util.translations.TranslationFactory;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerInteractEvent;
+
+public class BlockBreakAndUseCancelListener implements Listener {
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ Player player = event.getPlayer();
+ if(player == null || event.getClickedBlock() == null) return;
+ ChunkClaimSystem chunkClaimSystem = ChunkClaimSystem.getInstance();
+ if(chunkClaimSystem.checkIfLocationProtectedFromPlayer(event.getClickedBlock().getX(), event.getClickedBlock().getZ(), player)) {
+ Team team = ChunkClaimSystem.getInstance().getTeam(event.getClickedBlock().getLocation());
+ if(team == null) {
+ Main.getMainLogger().warning("Team is null when checking if location is protected");
+ return;
+ }
+ player.sendMessage(Component.text(new TranslationFactory().getTranslation(player, "chunkClaimedByDifferentTeam", team.getName())).color(NamedTextColor.RED));
+ event.setCancelled(true);
+ ChunkClaimSystem.getInstance().showPlayerProtectedLocationViaParticles(player, team.getProtectedLocation());
+ }
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/chunkClaimSystem/ChunkClaimSystem.java b/src/main/java/de/j/stationofdoom/teams/chunkClaimSystem/ChunkClaimSystem.java
new file mode 100644
index 00000000..069167e8
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/chunkClaimSystem/ChunkClaimSystem.java
@@ -0,0 +1,194 @@
+package de.j.stationofdoom.teams.chunkClaimSystem;
+
+import de.j.deathMinigames.main.Config;
+import de.j.deathMinigames.main.HandlePlayers;
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.HandleTeams;
+import de.j.stationofdoom.teams.Team;
+import de.j.stationofdoom.util.translations.TranslationFactory;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.*;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.bukkit.util.Vector;
+
+import java.util.*;
+
+public class ChunkClaimSystem {
+ private final TranslationFactory tf = new TranslationFactory();
+ private int protectedLocationSizeInBlocks = 32;
+ private final int heightOfCube = 20;
+ private final int period = 1;
+ private final Material material = Material.BARRIER;
+ private static volatile ChunkClaimSystem instance;
+
+ private ChunkClaimSystem(){}
+
+ public static ChunkClaimSystem getInstance() {
+ if (instance == null) {
+ synchronized (ChunkClaimSystem.class) {
+ if (instance == null) {
+ instance = new ChunkClaimSystem();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public int getProtectedLocationSizeInBlocks() {
+ return protectedLocationSizeInBlocks;
+ }
+
+ public void setProtectedLocationSizeInBlocks(int protectedLocationSizeInBlocks) {
+ this.protectedLocationSizeInBlocks = protectedLocationSizeInBlocks;
+ Config.getInstance().setProtectedLocationSizeInBlocksInConfig(protectedLocationSizeInBlocks);
+ }
+
+ public boolean checkIfLocationProtectedFromPlayer(int locationX, int locationZ, Player player) {
+ HashMap locationsOfTeamsMap = getAllProtectedLocations();
+ for (Location loc : locationsOfTeamsMap.keySet()) {
+ if(loc == null) continue;
+ int minX = loc.getBlockX() - protectedLocationSizeInBlocks;
+ int maxX = loc.getBlockX() + protectedLocationSizeInBlocks;
+ int minZ = loc.getBlockZ() - protectedLocationSizeInBlocks;
+ int maxZ = loc.getBlockZ() + protectedLocationSizeInBlocks;
+ if((locationX >= minX && locationX <= maxX) && (locationZ >= minZ && locationZ <= maxZ)){
+ if(!locationsOfTeamsMap.get(loc).isMember(player.getUniqueId())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean checkIfAreaLocationIsProtectedFromPlayer(int locationX, int locationZ, Player player) {
+ return checkIfLocationProtectedFromPlayer(locationX + protectedLocationSizeInBlocks, locationZ + protectedLocationSizeInBlocks, player) ||
+ checkIfLocationProtectedFromPlayer(locationX - protectedLocationSizeInBlocks, locationZ - protectedLocationSizeInBlocks, player) ||
+ checkIfLocationProtectedFromPlayer(locationX + protectedLocationSizeInBlocks, locationZ - protectedLocationSizeInBlocks, player) ||
+ checkIfLocationProtectedFromPlayer(locationX - protectedLocationSizeInBlocks, locationZ + protectedLocationSizeInBlocks, player);
+ }
+
+ public Team getTeam(Location location) {
+ return getTeamFromLocation(location.getBlockX(), location.getBlockZ());
+ }
+
+ private Team getTeamFromLocation(int locationX, int locationZ) {
+ HashMap locationsOfTeamsMap = getAllProtectedLocations();
+ for (Location loc : locationsOfTeamsMap.keySet()) {
+ int minX = loc.getBlockX() - protectedLocationSizeInBlocks;
+ int maxX = loc.getBlockX() + protectedLocationSizeInBlocks;
+ int minZ = loc.getBlockZ() - protectedLocationSizeInBlocks;
+ int maxZ = loc.getBlockZ() + protectedLocationSizeInBlocks;
+ if((locationX >= minX && locationX <= maxX) && (locationZ >= minZ && locationZ <= maxZ)){
+ return locationsOfTeamsMap.get(loc);
+ }
+ }
+ return null;
+ }
+
+ private HashMap getAllProtectedLocations() {
+ HashMap locationsOfTeamsMap = new HashMap<>();
+ int i = 0;
+ for (Team team : HandleTeams.getInstance().getAllTeams()){
+ Location location = team.getProtectedLocation();
+ if(location != null) {
+ locationsOfTeamsMap.put(team.getProtectedLocation(), team);
+ i++;
+ }
+ }
+ return locationsOfTeamsMap;
+ }
+
+ public void playerClaim(Player player, Team team, Location location) {
+ if(!checkIfAreaLocationIsProtectedFromPlayer(location.getBlockX(), location.getBlockZ(), player)) {
+ team.setProtectedLocation(location);
+ messageTeamMembersAboutNewProtectedLocation(team, player);
+ showPlayerProtectedLocationViaParticles(player, team.getProtectedLocation());
+ }
+ else {
+ player.sendMessage(Component.text(tf.getTranslation(player, "teamLocationAlreadyProtected")).color(NamedTextColor.RED));
+ }
+ }
+
+ private void messageTeamMembersAboutNewProtectedLocation(Team team, Player claimingPlayer) {
+ for (UUID uuid : team.getAllPlayers()) {
+ if(HandlePlayers.getInstance().getPlayerData(uuid).isOnline()) {
+ Player player = Bukkit.getPlayer(uuid);
+ if(player == null) continue;
+ Location location = team.getProtectedLocation();
+ if(uuid.equals(claimingPlayer.getUniqueId())) {
+ player.sendMessage(Component.text(tf.getTranslation(player, "teamSetProtectedLocation", location.getBlockX(), location.getBlockZ())).color(NamedTextColor.GREEN));
+ }
+ else {
+ player.sendMessage(Component.text(tf.getTranslation(player, "teamMembersNewProtectedLocation", location.getBlockX(), location.getBlockZ())).color(NamedTextColor.GREEN));
+ }
+ }
+ }
+ }
+
+ public void showPlayerProtectedLocationViaParticles(Player player, Location location1) {
+ List corners = new ArrayList<>();
+ Location playerLocation = player.getLocation();
+ Location location = location1.clone();
+ location.setY(playerLocation.getY());
+ location = location.getBlock().getLocation();
+ corners.add(location.clone().add(protectedLocationSizeInBlocks, heightOfCube, protectedLocationSizeInBlocks));
+ corners.add(location.clone().add(-protectedLocationSizeInBlocks, heightOfCube, -protectedLocationSizeInBlocks));
+ corners.add(location.clone().add(protectedLocationSizeInBlocks, heightOfCube, -protectedLocationSizeInBlocks));
+ corners.add(location.clone().add(-protectedLocationSizeInBlocks, heightOfCube, protectedLocationSizeInBlocks));
+ spawnEdgeParticles(location.getBlockX() + protectedLocationSizeInBlocks, location.getBlockZ() + protectedLocationSizeInBlocks, player, playerLocation, corners);
+ spawnEdgeParticles(location.getBlockX() - protectedLocationSizeInBlocks, location.getBlockZ() - protectedLocationSizeInBlocks, player, playerLocation, corners);
+ spawnEdgeParticles(location.getBlockX() + protectedLocationSizeInBlocks, location.getBlockZ() - protectedLocationSizeInBlocks, player, playerLocation, corners);
+ spawnEdgeParticles(location.getBlockX() - protectedLocationSizeInBlocks, location.getBlockZ() + protectedLocationSizeInBlocks, player, playerLocation, corners);
+ }
+
+ private void spawnEdgeParticles(int locationX, int locationZ, Player player, Location playerLocation, List corners) {
+ BlockData blockData = Bukkit.createBlockData(material);
+ final int[] y = {playerLocation.getBlockY() - 30};
+ Location thisCorner = new Location(player.getWorld(), locationX, playerLocation.getBlockY() + heightOfCube, locationZ);
+
+ BukkitRunnable runnable = new BukkitRunnable() {
+ public void run() {
+ int i = 1;
+ if(y[0] >= playerLocation.getBlockY() + heightOfCube) {
+ for(Location corner : corners) {
+ Vector connectionVector = corner.clone().toVector().subtract(thisCorner.toVector());
+ if(Math.round(connectionVector.length()) == (long) protectedLocationSizeInBlocks * 2) {
+ spawnBlockMarkerFromPointToAnother(thisCorner.clone(), thisCorner.clone().add(connectionVector.clone().multiply(0.5)), player);
+ }
+ i++;
+ }
+ this.cancel();
+ }
+ player.spawnParticle(Particle.BLOCK_MARKER, locationX, y[0], locationZ, 1, 0, 0, 0, blockData);
+ y[0]++;
+ }
+ };
+ runnable.runTaskTimer(Main.getPlugin(), 0, period);
+ }
+
+ private void spawnBlockMarkerFromPointToAnother(Location locationFromWhereToDraw, Location locationToWhereToDraw, Player player) {
+ Vector vector = locationToWhereToDraw.toVector().subtract(locationFromWhereToDraw.toVector());
+ Vector changeVector = vector.clone().multiply(1 / vector.length());
+ Location location = locationFromWhereToDraw.clone();
+ BlockData blockData = Bukkit.createBlockData(material);
+ final int[] y = {0};
+
+ BukkitRunnable runnable = new BukkitRunnable() {
+ public void run() {
+ if (y[0] >= vector.length()) {
+ this.cancel();
+ }
+ player.spawnParticle(Particle.BLOCK_MARKER, location.add(changeVector), 1, 0, 0, 0, blockData);
+ y[0]++;
+ if(vector.length() > 16) {
+ player.spawnParticle(Particle.BLOCK_MARKER, location.add(changeVector), 1, 0, 0, 0, blockData);
+ y[0]++;
+ }
+ }
+ };
+ runnable.runTaskTimerAsynchronously(Main.getPlugin(), 0, period);
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/enderchest/EnderchestInvHolder.java b/src/main/java/de/j/stationofdoom/teams/enderchest/EnderchestInvHolder.java
new file mode 100644
index 00000000..45e93869
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/enderchest/EnderchestInvHolder.java
@@ -0,0 +1,13 @@
+package de.j.stationofdoom.teams.enderchest;
+
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+
+public class EnderchestInvHolder implements InventoryHolder {
+
+ /** returns null, don't use*/
+ @Override
+ public Inventory getInventory() {
+ return null;
+ }
+}
diff --git a/src/main/java/de/j/stationofdoom/teams/enderchest/TeamEnderchestPreventEnchantedItemsInputListener.java b/src/main/java/de/j/stationofdoom/teams/enderchest/TeamEnderchestPreventEnchantedItemsInputListener.java
new file mode 100644
index 00000000..1f8f9343
--- /dev/null
+++ b/src/main/java/de/j/stationofdoom/teams/enderchest/TeamEnderchestPreventEnchantedItemsInputListener.java
@@ -0,0 +1,32 @@
+package de.j.stationofdoom.teams.enderchest;
+
+import de.j.deathMinigames.dmUtil.DmUtil;
+import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.util.translations.TranslationFactory;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.Sound;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+
+public class TeamEnderchestPreventEnchantedItemsInputListener implements Listener {
+ @EventHandler
+ public void onEnderchestInput(InventoryClickEvent event) {
+ try {
+ if(event.getView().getTopInventory().getHolder() instanceof EnderchestInvHolder && !event.getCurrentItem().getEnchantments().isEmpty()) {
+ event.setCancelled(true);
+ Player player = (Player) event.getView().getPlayer();
+ if(player == null) return;
+ player.sendMessage(Component.text(new TranslationFactory().getTranslation(player, "teamEnderchestPreventEnchantedItemsInput")).color(NamedTextColor.RED));
+ DmUtil.getInstance().playSoundAtLocation(player.getLocation(), 1F, Sound.BLOCK_ANVIL_PLACE);
+ }
+ }
+ catch (NullPointerException e) {
+ Main.getMainLogger().warning(e.getMessage());
+ return;
+ }
+ }
+
+}
diff --git a/src/main/java/de/j/stationofdoom/util/Tablist.java b/src/main/java/de/j/stationofdoom/util/Tablist.java
index b6ff7e11..9093317e 100644
--- a/src/main/java/de/j/stationofdoom/util/Tablist.java
+++ b/src/main/java/de/j/stationofdoom/util/Tablist.java
@@ -2,133 +2,292 @@
import de.j.deathMinigames.main.Config;
import de.j.stationofdoom.main.Main;
+import de.j.stationofdoom.teams.HandleTeams;
+import de.j.stationofdoom.teams.Team;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
-import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
+import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Scoreboard;
-import java.util.HashMap;
+import java.util.*;
import java.util.stream.Stream;
public class Tablist {
private volatile static String serverName = Bukkit.getServer().getName();
private volatile static String hostedBy = null;
+ private static final HashMap playerRanks = new HashMap<>();
+ private static final List afkPlayers = new ArrayList<>();
private static Scoreboard scoreboard;
- public static HashMap rank;
//Map that contains the player as key and the header and footer as array
private final HashMap playerListMap = new HashMap<>();
+ private static final Map colors = new HashMap<>();
+
+ private static final int secondsBetweenReloads = 10;
+ private static int n = 0;
+ private static boolean autoReloadRunning = false;
+ private static int autoReloadTaskId;
+
+ private enum Ranks {
+ HOST,
+ ADMIN,
+ DEVELOPER
+ }
+
public void setScoreboard() {
assert !Main.isFolia();
+ putColorsInMap();
+
scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
- rank = new HashMap<>();
- scoreboard.registerNewTeam("0Host");
- scoreboard.registerNewTeam("1Admin");
- scoreboard.registerNewTeam("2Developer");
- scoreboard.registerNewTeam("4Spieler");
- scoreboard.registerNewTeam("5AFK");
+ createScoreboardTeamsWithoutTeamName();
+ for (Team team : HandleTeams.getInstance().getAllTeams()) {
+ createScoreboardTeamsFromTeam(team);
+ }
- MiniMessage mm = MiniMessage.miniMessage();
+ setAllPlayerRanks();
+ for (Player on : Bukkit.getOnlinePlayers()){
+ setTeam(on);
+ reloadScoreboard(on);
+ }
+ if(!autoReloadRunning) {
+ startAutoReload();
+ }
+ }
+
+ private void putColorsInMap() {
+ colors.put("WHITE", "#FFFFFF");
+ colors.put("ORANGE", "#FFA500");
+ colors.put("MAGENTA", "#ff00ff");
+ colors.put("LIGHT_BLUE", "#ADD8E6");
+ colors.put("YELLOW", "#FFFF00");
+ colors.put("LIME", "#00FF00");
+ colors.put("PINK", "#FFC0CB");
+ colors.put("GRAY", "#808080");
+ colors.put("LIGHT_GRAY", "#D3D3D3");
+ colors.put("CYAN", "#E0FFFF");
+ colors.put("PURPLE", "#800080");
+ colors.put("BLUE", "#0000FF");
+ colors.put("BROWN", "#964B00");
+ colors.put("GREEN", "#008000");
+ colors.put("RED", "#FF0000");
+ colors.put("BLACK", "#000000");
+ }
+
+ // teams without any team name in it only once
+ private void createScoreboardTeamsWithoutTeamName() {
+ scoreboard.registerNewTeam("0Host");
scoreboard.getTeam("0Host").prefix(Component.text("Host ")
.color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
- .append(Component.text("| ").color(NamedTextColor.DARK_GRAY)));
- //scoreboard.getTeam("0Host")
- // .prefix(mm.deserialize("Host | "));
+ .append(Component.text("| ").color(NamedTextColor.WHITE)));
+
+ scoreboard.registerNewTeam("0AFK_Host");
+ scoreboard.getTeam("0AFK_Host").prefix(Component.text("AFK ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("Host ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("| ").color(NamedTextColor.WHITE))));
+
+ scoreboard.registerNewTeam("1Admin");
scoreboard.getTeam("1Admin").prefix(Component.text("Admin ")
.color(NamedTextColor.RED)
- .append(Component.text("| ").color(NamedTextColor.DARK_GRAY)));
+ .append(Component.text("| ").color(NamedTextColor.WHITE)));
+
+ scoreboard.registerNewTeam("1AFK_Admin");
+ scoreboard.getTeam("1AFK_Admin").prefix(Component.text("AFK ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("Admin ")
+ .color(NamedTextColor.RED)
+ .append(Component.text("| ").color(NamedTextColor.WHITE))));
+
+ scoreboard.registerNewTeam("2Developer");
scoreboard.getTeam("2Developer").prefix(Component.text("Dev ")
.color(NamedTextColor.GOLD)
- .append(Component.text("| ").color(NamedTextColor.DARK_GRAY)));
- scoreboard.getTeam("4Spieler").prefix(Component.text(""));
- scoreboard.getTeam("5AFK").prefix(Component.text("[")
- .color(NamedTextColor.DARK_BLUE)
- .append(Component.text("AFK")
- .color(NamedTextColor.DARK_AQUA)
- .append(Component.text("] ")
- .color(NamedTextColor.DARK_BLUE)
- .append(Component.text("| ").color(NamedTextColor.DARK_GRAY)))));
+ .append(Component.text("| ").color(NamedTextColor.WHITE)));
+ scoreboard.registerNewTeam("2AFK_Developer");
+ scoreboard.getTeam("2AFK_Developer").prefix(Component.text("AFK ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("Dev ")
+ .color(NamedTextColor.GOLD)
+ .append(Component.text("| ").color(NamedTextColor.WHITE))));
+
+ scoreboard.registerNewTeam("3AFK_");
+ scoreboard.getTeam("3AFK_").prefix(Component.text("AFK ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)));
- for (Player on : Bukkit.getOnlinePlayers()){
- setTeam(on);
- }
}
- public void setScoreboard(Player player, boolean afk) {
- assert !Main.isFolia();
- scoreboard.getTeam("0Host").prefix(Component.text("Host ")
+ private void createScoreboardTeamsFromTeam(Team team) {
+ TextColor teamColor;
+ if(team.getColorAsString() == null || colors.get(team.getColorAsString()) == null) {
+ Main.getMainLogger().warning("Could not find color for " + team.getName());
+ teamColor = NamedTextColor.WHITE;
+ }
+ else {
+ teamColor = TextColor.fromHexString(colors.get(team.getColorAsString()));
+ }
+
+ scoreboard.registerNewTeam("0Host_" + team.getUuid());
+ scoreboard.getTeam("0Host_" + team.getUuid()).prefix(Component.text("Host ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)
+ .append(Component.text(team.getName() + " ").color(teamColor)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)))));
+ scoreboard.registerNewTeam("0AFK_Host_" + team.getUuid());
+ scoreboard.getTeam("0AFK_Host_" + team.getUuid()).prefix(Component.text("AFK ")
.color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
- .append(Component.text("| ").color(NamedTextColor.DARK_GRAY)));
- scoreboard.getTeam("1Admin").prefix(Component.text("Admin ")
+ .append(Component.text("Host ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)
+ .append(Component.text(team.getName() + " ").color(teamColor)
+ .append(Component.text("| ").color(NamedTextColor.WHITE))))));
+
+ scoreboard.registerNewTeam("1Admin_" + team.getUuid());
+ scoreboard.getTeam("1Admin_" + team.getUuid()).prefix(Component.text("Admin ")
.color(NamedTextColor.RED)
- .append(Component.text("| ").color(NamedTextColor.DARK_GRAY)));
- scoreboard.getTeam("2Developer").prefix(Component.text("Dev ")
+ .append(Component.text("| ").color(NamedTextColor.WHITE)
+ .append(Component.text(team.getName() + " ").color(teamColor)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)))));
+ scoreboard.registerNewTeam("1AFK_Admin_" + team.getUuid());
+ scoreboard.getTeam("1AFK_Admin_" + team.getUuid()).prefix(Component.text("AFK ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("Admin ")
+ .color(NamedTextColor.RED)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)
+ .append(Component.text(team.getName() + " ").color(teamColor)
+ .append(Component.text("| ").color(NamedTextColor.WHITE))))));
+
+ scoreboard.registerNewTeam("2Developer_" + team.getUuid());
+ scoreboard.getTeam("2Developer_" + team.getUuid()).prefix(Component.text("Dev ")
.color(NamedTextColor.GOLD)
- .append(Component.text("| ").color(NamedTextColor.DARK_GRAY)));
- scoreboard.getTeam("4Spieler").prefix(Component.text(""));
- scoreboard.getTeam("5AFK").prefix(Component.text("[")
- .color(NamedTextColor.DARK_BLUE)
- .append(Component.text("AFK")
- .color(NamedTextColor.DARK_AQUA)
- .append(Component.text("] ")
- .color(NamedTextColor.DARK_BLUE)
- .append(Component.text("| ").color(NamedTextColor.DARK_GRAY)))));
+ .append(Component.text("| ").color(NamedTextColor.WHITE)
+ .append(Component.text(team.getName() + " ").color(teamColor)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)))));
+ scoreboard.registerNewTeam("2AFK_Developer_" + team.getUuid());
+ scoreboard.getTeam("2AFK_Developer_" + team.getUuid()).prefix(Component.text("AFK ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("Dev ")
+ .color(NamedTextColor.GOLD)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)
+ .append(Component.text(team.getName() + " ").color(teamColor)
+ .append(Component.text("| ").color(NamedTextColor.WHITE))))));
- setTeam(player, afk);
+ scoreboard.registerNewTeam("3AFK_" + team.getUuid());
+ scoreboard.getTeam("3AFK_" + team.getUuid()).prefix(Component.text("AFK ")
+ .color(NamedTextColor.DARK_RED).decoration(TextDecoration.BOLD, true)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)
+ .append(Component.text(team.getName() + " ").color(teamColor)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)))));
+ scoreboard.registerNewTeam("3_" + team.getUuid());
+ scoreboard.getTeam("3_" + team.getUuid()).prefix(Component.text(team.getName() + " ").color(teamColor)
+ .append(Component.text("| ").color(NamedTextColor.WHITE)));
+ }
+ private void setAllPlayerRanks() {
+ playerRanks.put(UUID.fromString("46cd27ba-df0c-49ef-9f33-6cfa884e339b"), Ranks.DEVELOPER);
+ playerRanks.put(UUID.fromString("050fee27-a1cc-4e78-953a-7cefaf0849a1"), Ranks.DEVELOPER);
}
private void setTeam(Player player) {
assert !Main.isFolia();
- String team = null;
- switch (player.getUniqueId().toString()) {
- case "050fee27-a1cc-4e78-953a-7cefaf0849a1" -> {//LP
- team = "0Host";
- rank.put(player, ChatColor.RED + "" + ChatColor.BOLD + "[Host]" + ChatColor.RESET + " ");
+ UUID playerUUID = player.getUniqueId();
+ if(playerRanks.containsKey(player.getUniqueId())) {
+ switch (playerRanks.get(player.getUniqueId())) {
+ case Ranks.HOST:
+ if(afkPlayers.contains(player.getUniqueId())) {
+ if(HandleTeams.getTeamFromPlayerUUID(playerUUID).isMember(player.getUniqueId())) {
+ scoreboard.getTeam("0AFK_Host_" + HandleTeams.getTeamFromPlayerUUID(playerUUID).getUuid()).addPlayer(player);
+ }
+ else {
+ scoreboard.getTeam("0AFK_Host").addPlayer(player);
+ }
+ }
+ else {
+ if(HandleTeams.getTeamFromPlayerUUID(playerUUID).isMember(player.getUniqueId())) {
+ scoreboard.getTeam("0Host_" + HandleTeams.getTeamFromPlayerUUID(playerUUID).getUuid()).addPlayer(player);
+ }
+ else {
+ scoreboard.getTeam("0Host").addPlayer(player);
+ }
+ }
+ break;
+ case Ranks.ADMIN:
+ if(afkPlayers.contains(player.getUniqueId())) {
+ if(HandleTeams.getTeamFromPlayerUUID(playerUUID).isMember(player.getUniqueId())) {
+ scoreboard.getTeam("1AFK_Admin_" + HandleTeams.getTeamFromPlayerUUID(playerUUID).getUuid()).addPlayer(player);
+ }
+ else {
+ scoreboard.getTeam("1AFK_Admin").addPlayer(player);
+ }
+ }
+ else {
+ if(HandleTeams.getTeamFromPlayerUUID(playerUUID).isMember(player.getUniqueId())) {
+ scoreboard.getTeam("1Admin_" + HandleTeams.getTeamFromPlayerUUID(playerUUID).getUuid()).addPlayer(player);
+ }
+ else {
+ scoreboard.getTeam("1Admin").addPlayer(player);
+ }
+ }
+ break;
+ case Ranks.DEVELOPER:
+ if(afkPlayers.contains(player.getUniqueId())) {
+ if(HandleTeams.getTeamFromPlayerUUID(playerUUID).isMember(player.getUniqueId())) {
+ scoreboard.getTeam("2AFK_Developer_" + HandleTeams.getTeamFromPlayerUUID(playerUUID).getUuid()).addPlayer(player);
+ }
+ else {
+ scoreboard.getTeam("2AFK_Developer").addPlayer(player);
+ }
+ }
+ else {
+ if(HandleTeams.getTeamFromPlayerUUID(playerUUID).isMember(player.getUniqueId())) {
+ scoreboard.getTeam("2Developer_" + HandleTeams.getTeamFromPlayerUUID(playerUUID).getUuid()).addPlayer(player);
+ }
+ else {
+ scoreboard.getTeam("2Developer").addPlayer(player);
+ }
+ }
+ break;
}
- case "0565369c-ec68-4e7e-a90f-3492eb7002d8" -> {//MDHD
- team = "1Admin";
- rank.put(player, ChatColor.BLUE + "" + ChatColor.BOLD + "[Admin]" + ChatColor.RESET + " ");
- }
- //case "" -> {
- // team = "2Developer";
- // rank.put(player, ChatColor.GRAY + "[Dev]" + ChatColor.RESET + " ");
- //}
}
-
- if (team == null) {
- team = "4Spieler";
- rank.put(player, "");
+ else {
+ if(afkPlayers.contains(player.getUniqueId())) {
+ if(HandleTeams.getTeamFromPlayerUUID(playerUUID).isMember(player.getUniqueId())) {
+ scoreboard.getTeam("3AFK_" + HandleTeams.getTeamFromPlayerUUID(playerUUID).getUuid()).addPlayer(player);
+ }
+ else {
+ scoreboard.getTeam("3AFK_").addPlayer(player);
+ }
+ }
+ else {
+ if(HandleTeams.getTeamFromPlayerUUID(playerUUID).isMember(player.getUniqueId())) {
+ scoreboard.getTeam("3_" + HandleTeams.getTeamFromPlayerUUID(playerUUID).getUuid()).addPlayer(player);
+ }
+ }
}
+ }
- scoreboard.getTeam(team).addPlayer(player);
+ private void reloadScoreboard(Player player) {
player.setScoreboard(scoreboard);
}
- private void setTeam(Player player, boolean afk) {
+ public void setAFK(Player player, boolean afk) {
assert !Main.isFolia();
- String team;
- if (afk) {
- team = "5AFK";
- rank.put(player, ChatColor.DARK_BLUE + "[" + ChatColor.DARK_AQUA + "AFK" + ChatColor.DARK_BLUE + "]");
-
- scoreboard.getTeam(team).addPlayer(player);
- player.setScoreboard(scoreboard);
- } else
- setTeam(player);
- }
- public void tab(Audience player, Component header, Component footer) {
- player.sendPlayerListHeaderAndFooter(header, footer);
+ if(afk && !afkPlayers.contains(player.getUniqueId())) {
+ afkPlayers.add(player.getUniqueId());
+ }
+ else if(!afk && afkPlayers.contains(player.getUniqueId())) {
+ afkPlayers.remove(player.getUniqueId());
+ }
+ setScoreboard();
}
public void tabTPS(Audience player, Component header, Component footer) {
@@ -147,15 +306,6 @@ public void tabTPS(Audience player, Component header, Component footer) {
playerListMap.put(player, Stream.of(header, footer).toArray(Component[]::new));
}
- public void setAFK(Player player, boolean afk) {
- assert !Main.isFolia();
- if (afk) {
- setScoreboard(player, afk);
- } else
- setScoreboard(player, false);
-
- }
-
public Component getTimeComponent(Player player) {
double time = (player.getWorld().getFullTime() / 1000.0 + 6) % 24;
String formattedTime = String.format("%02d:%02d", (int) time, (int) ((time % 1) * 60));
@@ -188,4 +338,26 @@ public static void setHostedBy(String hostedBy) {
public static String getHostedBy() {
return hostedBy;
}
+
+ private static void startAutoReload() {
+ autoReloadRunning = true;
+ autoReloadTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getPlugin(), new Runnable() {
+ public void run() {
+ if(Bukkit.getOnlinePlayers().isEmpty()) {
+ stopAutoReload();
+ }
+ if (n >= secondsBetweenReloads){
+ Tablist tablist = new Tablist();
+ tablist.setScoreboard();
+ n = 0;
+ }
+ n++;
+ }
+ }, 20, 20);
+ }
+
+ private static void stopAutoReload() {
+ autoReloadRunning = false;
+ Bukkit.getScheduler().cancelTask(autoReloadTaskId);
+ }
}
diff --git a/src/main/resources/translations.json b/src/main/resources/translations.json
index 2448d3f2..59b0315f 100755
--- a/src/main/resources/translations.json
+++ b/src/main/resources/translations.json
@@ -65,7 +65,7 @@
"ignoreMinigame": "nicht um deine Items spielen",
"maxDiffAlreadyReached": "Du hast schon die maximale Schwierigkeit erreicht. Hast du super gemacht",
"introParkour": "Du musst diesen Parkour bestehen, um deine Items wieder zu bekommen",
- "loseMessage": "Du hast verloren. Dein Inventar wird an deinem Todesort gedroppt\n Todesort: %s\n Wenn du deine Schwierigkeit verringern möchtest musst du etwas opfern. Clicke dafür hier oder gib /game lowerDifficulty ein",
+ "loseMessage": "Du hast verloren. Dein Inventar wird an deinem Todesort gedroppt\n Todesort: %s\n Wenn du deine Schwierigkeit verringern möchtest musst du etwas opfern. Clicke dafür hier oder gib /game lowerDifficulty ein",
"winMessage": "Du hast gewonnen, du bekommst jetzt deine Items",
"winInv": "Deine Items",
"backButton": "Zurück",
@@ -84,7 +84,42 @@
"invalidDifficulty": "Die Schwierigkeit muss zwischen 0 und 10 sein",
"anvilOutput": "Klicke hier um zu bestätigen",
"noNameSet": "Kein Name gesetzt",
- "enchantNotEnabled": "Diese Verzauberung ist auf diesem Server nicht aktiviert."
+ "createTeam": "Erstelle eine Team",
+ "alreadyFirstPage": "Du bist bereits auf der ersten Seite",
+ "lastPage": "Zurück",
+ "nextPage": "Weiter",
+ "page": "Seite",
+ "leaveTeam": "Team verlassen",
+ "joinTeam": "Team beitreten",
+ "renameTeam": "Team umbenennen",
+ "deleteTeam": "Team löschen",
+ "changeColor": "Farbe ändern",
+ "lockTeamSettings": "Team Einstellungen sperren",
+ "lockedTeamSettingsLore": "Wenn die Einstellungen gesperrt sind, können diese nur die Team Operatoren bearbeiten",
+ "teamEnderChest": "Team Enderchest",
+ "teamEnderChestLore": "Klicke hier um die Team-Enderchest zu öffnen",
+ "teamLockedAndNotOperator": "Die Team Einstellung sind gesperrt und du bis kein Operator von diesem Team",
+ "teamNotAMember": "Du bist kein Mitglied dieses Teams",
+ "teamPlayerSettingsDemoteToMember": "Zu Mitglied herunterstufen",
+ "teamPlayerSettingsPromoteToOperator": "Zu Operator hochstufen",
+ "teamPlayerSettingsKickPlayer": "Spieler kicken",
+ "kickedFromTeam": "Du wurdest von %s vom Team gekickt",
+ "teamDeleted": "Das Team, %s, ist gelöscht und du kannst es nicht mehr öffnen",
+ "playerIsOffline": "Der Spieler ist offline",
+ "teamClaimChunks": "Chunks beanspruchen",
+ "teamClaimChunksProtectedLocation": "Chunks beanspruchen (gerade: x: %s y: %s z: %S)",
+ "teamClaimChunksLore": "Klicke hier, um Anspruch auf die drei umgebenden Chunks zu erheben",
+ "chunkClaimedByDifferentTeam": "Dieser Chunk ist von dem Team: %s beansprucht",
+ "teamEnderchestPreventEnchantedItemsInput": "Du kannst keine verzauberten Items in die Enderchest legen",
+ "teamSetProtectedLocation": "Du hast den Bereich um die Location x: %s z: %S geschützt",
+ "teamLocationAlreadyProtected": "Dieser Bereich ist bereits beschützt",
+ "teamMembersNewProtectedLocation": "Dein Team hat einen neuen Bereich geschützt: x: %s z: %s",
+ "setClaimingRadius": "Du hast den Radius des beschützen Bereichs jedes Team auf: %s gesetzt",
+ "TeamCMDNoTeam": "Du bist in keinem Team",
+ "teamLocked": "Das Team ist gesperrt",
+ "enchantNotEnabled": "Diese Verzauberung ist auf diesem Server nicht aktiviert",
+ "noTeam": "Es wurde für dich kein Team gefunden",
+ "invalidAnvilInputClaimingRadius": "Deine Eingabe war invalide, bitte gebe nur positive Zahlen bis 256 ein"
}
],
"en-US": [
@@ -153,7 +188,7 @@
"ignoreMinigame": "not play for your items",
"maxDiffAlreadyReached": "You already reached the maximum difficulty.",
"introParkour": "You have to get to the end of this parkour to get your items back",
- "loseMessage": "You lost. Your inventory will be dropped at your point of death \n Deathpoint: %s \n If this difficulty is to hard for you, you can lower it by sacrificing something. Click here or type /game lowerDifficulty in chat.",
+ "loseMessage": "You lost. Your inventory will be dropped at your point of death \n Deathpoint: %s \n If this difficulty is to hard for you, you can lower it by sacrificing something. Click here or type /game lowerDifficulty in chat.",
"winMessage": "You won, you will get your items back",
"winInv": "Your items",
"backButton": "Back",
@@ -172,7 +207,42 @@
"invalidDifficulty": "The difficulty has to be between 0 and 10",
"anvilOutput": "Click here to accept",
"noNameSet": "No name set",
- "enchantNotEnabled": "This enchantment is currently not activated."
+ "createTeam": "Create a team",
+ "alreadyFirstPage": "You are already on the first page",
+ "lastPage": "Back",
+ "nextPage": "Next",
+ "page": "Page",
+ "leaveTeam": "Leave team",
+ "joinTeam": "Join team",
+ "renameTeam": "Rename team",
+ "deleteTeam": "Delete team",
+ "changeColor": "Change color",
+ "lockTeamSettings": "Lock team settings",
+ "lockedTeamSettingsLore": "When locked, only team operators can change team settings",
+ "teamEnderChest": "Team enderchest",
+ "teamEnderChestLore": "Click here to open the team enderchest",
+ "teamLockedAndNotOperator": "The team settings are locked and you are not an operator of this team",
+ "teamNotAMember": "You are not a member of this team",
+ "teamPlayerSettingsDemoteToMember": "Demote to member",
+ "teamPlayerSettingsPromoteToOperator": "Promote to operator",
+ "teamPlayerSettingsKickPlayer": "Kick player",
+ "kickedFromTeam": "You got kicked from the team by %s",
+ "teamDeleted": "The team, %s, is deleted and you can not open it anymore",
+ "playerIsOffline": "This player is offline",
+ "teamClaimChunks": "Claim chunks",
+ "teamClaimChunksProtectedLocation": "Claim chunks (at the moment: x: %s y: %s z: %S)",
+ "teamClaimChunksLore": "Click here to claim the three surrounding chunks for your team",
+ "chunkClaimedByDifferentTeam": "This chunk is claimed by the team: %s",
+ "teamEnderchestPreventEnchantedItemsInput": "You can not put enchanted items into the team enderchest",
+ "teamSetProtectedLocation": "You claimed the location around x: %s z: %s",
+ "teamLocationAlreadyProtected": "This location is already claimed",
+ "teamMembersNewProtectedLocation": "Your team has claimed a new location: x: %s z: %s",
+ "setClaimingRadius": "You set the claiming radius to: %s",
+ "TeamCMDNoTeam": "You are not in any team",
+ "teamLocked": "This team is locked",
+ "enchantNotEnabled": "This enchantment is currently not activated.",
+ "noTeam": "There was no team found for you",
+ "invalidAnvilInputClaimingRadius": "Your input is invalid, please only use positive numbers which are smaller than 256"
}
]
}
\ No newline at end of file