This commit is contained in:
DaTTV 2025-02-16 20:03:01 +01:00
commit a1a6f21624
14 changed files with 663 additions and 7 deletions

Binary file not shown.

9
.idea/compiler.xml generated
View file

@ -1,6 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Gradle Imported" enabled="true">
<outputRelativeToContentRoot value="true" />
<processorPath useClasspath="false">
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.18.36/5a30490a6e14977d97d9c73c924c1f1b5311ea95/lombok-1.18.36.jar" />
</processorPath>
<module name="BlazeSMP.main" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel target="21" />
</component>
</project>

1
.idea/gradle.xml generated
View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>

3
.idea/misc.xml generated
View file

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="temurin-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>

View file

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$/../../build/generated/sources/annotationProcessor/java/main">
<sourceFolder url="file://$MODULE_DIR$/../../build/generated/sources/annotationProcessor/java/main" isTestSource="false" generated="true" />
</content>
</component>
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>

View file

@ -1,12 +1,50 @@
package me.freezy.plugins.papermc.blazesmp;
import lombok.Getter;
import me.freezy.plugins.papermc.blazesmp.module.manager.Clans;
import me.freezy.plugins.papermc.blazesmp.module.manager.Homes;
import me.freezy.plugins.papermc.blazesmp.module.manager.ProtectedBlocks;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.slf4j.Logger;
public final class BlazeSMP extends JavaPlugin {
@Getter private static BlazeSMP instance;
@Getter private Homes homes;
@Getter private ProtectedBlocks protectedBlocks;
@Getter private Clans clans;
@Getter private FileConfiguration configuration;
@Getter private Logger log;
@Override
public void onLoad() {
this.log=getSLF4JLogger();
this.log.info("Loading Homes...");
this.homes=new Homes();
this.homes.load();
this.log.info("Loaded Homes!");
this.log.info("Loading ProtectedBlocks...");
this.protectedBlocks=new ProtectedBlocks();
this.protectedBlocks.load();
this.log.info("Loaded ProtectedBlocks!");
this.log.info("Loading Clans...");
this.clans=new Clans();
this.clans.loadAllClans();
this.log.info("Loaded Clans!");
this.log.info("Loading config...");
saveDefaultConfig();
this.configuration= getConfig();
saveConfig();
this.log.info("Loaded config!");
}
@Override
public void onEnable() {
// Plugin startup logic
BlazeSMP.instance=this;
}

View file

@ -1,5 +1,212 @@
package me.freezy.plugins.papermc.blazesmp.module;
public class Clan {
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.Getter;
import lombok.Setter;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;
@Getter
public class Clan {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final String STORAGE_PATH = "plugins/BlazeSMP/storage/clans/";
private static final Logger LOGGER = Logger.getLogger("Clan");
private final UUID uuid;
@Setter private String name;
@Setter private Component tag;
@Setter private UUID leaderUUID;
@Setter private UUID viceUUID;
private final LinkedList<UUID> members;
private final LinkedList<Chunk> chunks;
private final LinkedHashMap<Chunk, UUID> chunkOwnerMap;
private int chunkAmount;
public Clan(String name, Component tag, UUID leaderUUID) {
this.uuid = UUID.randomUUID();
this.name = name;
this.tag = tag;
this.leaderUUID = leaderUUID;
this.viceUUID = null;
this.members = new LinkedList<>();
this.chunks = new LinkedList<>();
this.chunkOwnerMap = new LinkedHashMap<>();
this.chunkAmount = 0;
}
public Clan(UUID clanUUID, String name, Component tag, UUID leaderUUID, UUID viceUUID,
LinkedList<UUID> members, LinkedList<Chunk> chunks, LinkedHashMap<Chunk, UUID> chunkOwnerMap) {
this.uuid = clanUUID;
this.name = name;
this.tag = tag;
this.leaderUUID = leaderUUID;
this.viceUUID = viceUUID;
this.members = members;
this.chunks = chunks;
this.chunkOwnerMap = chunkOwnerMap;
this.chunkAmount = chunks.size();
}
/**
* Loads a Clan from the JSON file corresponding to the given UUID.
*
* @param uuid The UUID of the clan.
* @return The loaded Clan or null if the file does not exist.
*/
public static Clan load(UUID uuid) {
File file = new File(STORAGE_PATH + uuid + ".json");
if (!file.exists()) {
LOGGER.warning("Clan file " + file.getAbsolutePath() + " does not exist.");
return null;
}
try (FileReader reader = new FileReader(file)) {
ClanJson jsonClan = GSON.fromJson(reader, ClanJson.class);
if (jsonClan == null) {
LOGGER.warning("Failed to parse clan JSON for UUID " + uuid);
return null;
}
Component tagComponent = MiniMessage.miniMessage().deserialize(jsonClan.tag);
UUID leader = (jsonClan.leader == null || jsonClan.leader.isEmpty()) ? null : UUID.fromString(jsonClan.leader);
UUID vice = (jsonClan.vize == null || jsonClan.vize.isEmpty()) ? null : UUID.fromString(jsonClan.vize);
// Convert members
LinkedList<UUID> memberUUIDs = new LinkedList<>();
if (jsonClan.members != null) {
for (String s : jsonClan.members) {
if (s != null && !s.isEmpty()) {
memberUUIDs.add(UUID.fromString(s));
}
}
}
// Process chunks with world information
LinkedList<Chunk> chunkList = new LinkedList<>();
LinkedHashMap<Chunk, UUID> chunkOwnerMap = new LinkedHashMap<>();
if (jsonClan.chunks != null && jsonClan.chunks.locations != null) {
for (LocationJson loc : jsonClan.chunks.locations) {
World world = Bukkit.getWorld(loc.world);
if (world == null) {
LOGGER.warning("World '" + loc.world + "' not found. Skipping chunk at " + loc.x + ", " + loc.z);
continue;
}
int x = Integer.parseInt(loc.x);
int z = Integer.parseInt(loc.z);
Chunk chunk = world.getChunkAt(x, z);
chunkList.add(chunk);
UUID ownerUUID = (loc.owner == null || loc.owner.isEmpty()) ? null : UUID.fromString(loc.owner);
chunkOwnerMap.put(chunk, ownerUUID);
}
}
Clan clan = new Clan(uuid, jsonClan.name, tagComponent, leader, vice, memberUUIDs, chunkList, chunkOwnerMap);
clan.chunkAmount = (jsonClan.chunks != null) ? jsonClan.chunks.amount : chunkList.size();
return clan;
} catch (IOException e) {
LOGGER.severe("Error loading clan: " + e.getMessage());
return null;
}
}
/**
* Reloads the clan from its corresponding JSON file.
*/
public void reload() {
Clan loaded = load(this.uuid);
if (loaded == null) {
LOGGER.warning("Failed to reload clan with UUID: " + this.uuid);
return;
}
this.name = loaded.name;
this.tag = loaded.tag;
this.leaderUUID = loaded.leaderUUID;
this.viceUUID = loaded.viceUUID;
this.members.clear();
this.members.addAll(loaded.members);
this.chunks.clear();
this.chunks.addAll(loaded.chunks);
this.chunkOwnerMap.clear();
this.chunkOwnerMap.putAll(loaded.chunkOwnerMap);
this.chunkAmount = loaded.chunkAmount;
}
/**
* Saves the clan data to its corresponding JSON file.
*/
public void save() {
ClanJson jsonClan = new ClanJson();
jsonClan.name = this.name;
jsonClan.tag = MiniMessage.miniMessage().serialize(this.tag);
jsonClan.leader = (this.leaderUUID == null) ? "" : this.leaderUUID.toString();
jsonClan.vize = (this.viceUUID == null) ? "" : this.viceUUID.toString();
jsonClan.members = this.members.stream().map(UUID::toString).toList();
// Prepare chunks JSON
jsonClan.chunks = new ChunksJson();
jsonClan.chunks.amount = this.chunkAmount;
jsonClan.chunks.locations = new LinkedList<>();
for (Chunk chunk : this.chunks) {
LocationJson loc = new LocationJson();
// Assuming the owner mapping may be null
UUID owner = this.chunkOwnerMap.getOrDefault(chunk, null);
loc.owner = (owner == null) ? "" : owner.toString();
// Store world name along with chunk coordinates
loc.world = chunk.getWorld().getName();
loc.x = String.valueOf(chunk.getX());
loc.z = String.valueOf(chunk.getZ());
jsonClan.chunks.locations.add(loc);
}
// Ensure directory exists
File dir = new File(STORAGE_PATH);
if (!dir.exists()) {
if (dir.mkdirs()) {
LOGGER.info("Successfully created folder structure!");
} else {
LOGGER.severe("Failed to create folder structure!");
}
}
File file = new File(dir, this.uuid + ".json");
try (FileWriter writer = new FileWriter(file)) {
GSON.toJson(jsonClan, writer);
} catch (IOException e) {
LOGGER.severe("Error saving clan: " + e.getMessage());
}
}
// Helper classes to represent the JSON structure
private static class ClanJson {
String name;
String tag;
String leader;
String vize;
List<String> members;
ChunksJson chunks;
}
private static class ChunksJson {
int amount;
List<LocationJson> locations;
}
private static class LocationJson {
String owner;
String world;
String x;
String z;
}
}

View file

@ -0,0 +1,11 @@
package me.freezy.plugins.papermc.blazesmp.module;
import lombok.Getter;
import org.bukkit.Location;
import java.util.UUID;
/**
* Represents a protected block with an owner, a key, and a location.
*/
public record ProtectedBlock(UUID owner, UUID key, Location location) {}

View file

@ -0,0 +1,127 @@
package me.freezy.plugins.papermc.blazesmp.module.manager;
import me.freezy.plugins.papermc.blazesmp.module.Clan;
import java.io.File;
import java.util.LinkedList;
import java.util.UUID;
import java.util.logging.Logger;
public class Clans {
private static final Logger LOGGER = Logger.getLogger("ClanManager");
private static final String CLAN_STORAGE_PATH = "plugins/BlazeSMP/storage/clans/";
private final LinkedList<Clan> clans;
public Clans() {
this.clans = new LinkedList<>();
}
/**
* Returns the list of loaded clans.
*
* @return LinkedList of Clan objects.
*/
public LinkedList<Clan> getClans() {
return clans;
}
/**
* Loads all clan files from the storage folder.
*/
public void loadAllClans() {
File dir = new File(CLAN_STORAGE_PATH);
if (!dir.exists()) {
LOGGER.info("Clan storage directory does not exist. Creating directory...");
dir.mkdirs();
return;
}
File[] files = dir.listFiles((file, name) -> name.endsWith(".json"));
if (files == null || files.length == 0) {
LOGGER.info("No clan files found in " + CLAN_STORAGE_PATH);
return;
}
for (File file : files) {
try {
// Assume file name is <uuid>.json
String filename = file.getName();
String uuidString = filename.substring(0, filename.lastIndexOf('.'));
UUID clanUUID = UUID.fromString(uuidString);
Clan clan = Clan.load(clanUUID);
if (clan != null) {
clans.add(clan);
LOGGER.info("Loaded clan: " + clan.getName() + " (" + clan.getUuid() + ")");
} else {
LOGGER.warning("Failed to load clan with UUID: " + clanUUID);
}
} catch (Exception e) {
LOGGER.warning("Error loading clan file " + file.getName() + ": " + e.getMessage());
}
}
}
/**
* Saves all loaded clans to their respective JSON files.
*/
public void saveAllClans() {
for (Clan clan : clans) {
clan.save();
}
}
/**
* Retrieves a clan by its name (case-insensitive).
*
* @param name The name of the clan.
* @return The matching Clan or null if not found.
*/
public Clan getClanByName(String name) {
for (Clan clan : clans) {
if (clan.getName().equalsIgnoreCase(name)) {
return clan;
}
}
return null;
}
/**
* Retrieves a clan by its UUID.
*
* @param uuid The UUID of the clan.
* @return The matching Clan or null if not found.
*/
public Clan getClanByUUID(UUID uuid) {
for (Clan clan : clans) {
if (clan.getUuid().equals(uuid)) {
return clan;
}
}
return null;
}
/**
* Adds a clan to the manager.
*
* @param clan The Clan to add.
*/
public void addClan(Clan clan) {
if (!clans.contains(clan)) {
clans.add(clan);
}
}
/**
* Removes a clan from the manager and deletes its JSON file.
*
* @param clan The Clan to remove.
*/
public void removeClan(Clan clan) {
clans.remove(clan);
File file = new File(CLAN_STORAGE_PATH + clan.getUuid() + ".json");
if (file.exists()) {
if (!file.delete()) {
LOGGER.warning("Failed to delete clan file: " + file.getAbsolutePath());
}
}
}
}

View file

@ -0,0 +1,124 @@
package me.freezy.plugins.papermc.blazesmp.module.manager;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;
public class Homes {
private static final String FILE_PATH = "plugins/BlazeSMP/storage/homes.json";
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Logger LOGGER = Logger.getLogger("Homes");
// Mapping of player UUID to their home location
@Getter private final LinkedHashMap<UUID, Location> homes;
public Homes() {
this.homes = new LinkedHashMap<>();
}
/**
* Loads homes from the JSON file.
*/
public void load() {
File file = new File(FILE_PATH);
if (!file.exists()) {
LOGGER.info("Homes file does not exist, a new one will be created upon saving.");
return;
}
try (FileReader reader = new FileReader(file)) {
// Use a TypeToken to handle the Map<String, LocationJson> structure
Type type = new TypeToken<Map<String, LocationJson>>() {}.getType();
Map<String, LocationJson> jsonMap = GSON.fromJson(reader, type);
if (jsonMap == null) {
return;
}
for (Map.Entry<String, LocationJson> entry : jsonMap.entrySet()) {
UUID uuid;
try {
uuid = UUID.fromString(entry.getKey());
} catch (IllegalArgumentException ex) {
LOGGER.warning("Invalid UUID key in homes file: " + entry.getKey());
continue;
}
LocationJson locJson = entry.getValue();
// Assume the default world "world" for homes
World world = Bukkit.getWorld("world");
if (world == null) {
LOGGER.warning("Default world 'world' not found. Skipping home for " + uuid);
continue;
}
try {
double x = Double.parseDouble(locJson.x);
double y = Double.parseDouble(locJson.y);
double z = Double.parseDouble(locJson.z);
float yaw = Float.parseFloat(locJson.yaw);
float pitch = Float.parseFloat(locJson.pitch);
Location location = new Location(world, x, y, z, yaw, pitch);
homes.put(uuid, location);
} catch (NumberFormatException ex) {
LOGGER.warning("Invalid number format for home of " + uuid + ": " + ex.getMessage());
}
}
} catch (IOException e) {
LOGGER.severe("Error loading homes: " + e.getMessage());
}
}
/**
* Saves the homes mapping to the JSON file.
*/
public void save() {
// Convert the homes map to a map of String keys (UUIDs) to LocationJson objects.
Map<String, LocationJson> jsonMap = new LinkedHashMap<>();
for (Map.Entry<UUID, Location> entry : homes.entrySet()) {
Location location = entry.getValue();
LocationJson locJson = new LocationJson();
locJson.x = String.valueOf(location.getX());
locJson.y = String.valueOf(location.getY());
locJson.z = String.valueOf(location.getZ());
locJson.yaw = String.valueOf(location.getYaw());
locJson.pitch = String.valueOf(location.getPitch());
jsonMap.put(entry.getKey().toString(), locJson);
}
File file = new File(FILE_PATH);
// Ensure the parent directory exists
File parent = file.getParentFile();
if (parent != null && !parent.exists()) {
if (parent.mkdirs()) {
LOGGER.info("Successfully created folder structure!");
} else {
LOGGER.severe("Failed to create folder structure!");
}
}
try (FileWriter writer = new FileWriter(file)) {
GSON.toJson(jsonMap, writer);
} catch (IOException e) {
LOGGER.severe("Error saving homes: " + e.getMessage());
}
}
/**
* Inner class representing the JSON structure for a location.
*/
private static class LocationJson {
String x;
String y;
String z;
String yaw;
String pitch;
}
}

View file

@ -0,0 +1,129 @@
package me.freezy.plugins.papermc.blazesmp.module.manager;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import me.freezy.plugins.papermc.blazesmp.module.ProtectedBlock;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;
/**
* Manager class for loading and saving protected blocks.
*/
public class ProtectedBlocks {
private static final String FILE_PATH = "plugins/BlazeSMP/storage/protected_blocks.json";
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Logger LOGGER = Logger.getLogger("ProtectedBlocks");
// List of protected blocks
private final List<ProtectedBlock> blocks;
public ProtectedBlocks() {
this.blocks = new ArrayList<>();
}
public List<ProtectedBlock> getBlocks() {
return blocks;
}
/**
* Loads protected blocks from the JSON file.
*/
public void load() {
File file = new File(FILE_PATH);
if (!file.exists()) {
LOGGER.info("Protected blocks file does not exist, a new one will be created upon saving.");
return;
}
try (FileReader reader = new FileReader(file)) {
// Deserialize the JSON into a ProtectedBlocksJson object
ProtectedBlocksJson jsonData = GSON.fromJson(reader, ProtectedBlocksJson.class);
if (jsonData == null || jsonData.blocks == null) {
return;
}
blocks.clear();
for (BlockJson blockJson : jsonData.blocks) {
try {
UUID owner = (blockJson.owner == null || blockJson.owner.isEmpty())
? null : UUID.fromString(blockJson.owner);
UUID key = (blockJson.key == null || blockJson.key.isEmpty())
? null : UUID.fromString(blockJson.key);
// Use default world "world" since no world field is provided
World world = Bukkit.getWorld("world");
if (world == null) {
LOGGER.warning("Default world 'world' not found. Skipping block for owner: " + blockJson.owner);
continue;
}
double x = Double.parseDouble(blockJson.location.x);
double y = Double.parseDouble(blockJson.location.y);
double z = Double.parseDouble(blockJson.location.z);
Location location = new Location(world, x, y, z);
blocks.add(new ProtectedBlock(owner, key, location));
} catch (Exception e) {
LOGGER.warning("Error loading a protected block: " + e.getMessage());
}
}
} catch (IOException e) {
LOGGER.severe("Error loading protected blocks: " + e.getMessage());
}
}
/**
* Saves the protected blocks to the JSON file.
*/
public void save() {
ProtectedBlocksJson jsonData = new ProtectedBlocksJson();
jsonData.blocks = new ArrayList<>();
for (ProtectedBlock block : blocks) {
BlockJson blockJson = new BlockJson();
blockJson.owner = (block.owner() == null) ? "" : block.owner().toString();
blockJson.key = (block.key() == null) ? "" : block.key().toString();
blockJson.location = new LocationJson();
blockJson.location.x = String.valueOf(block.location().getX());
blockJson.location.y = String.valueOf(block.location().getY());
blockJson.location.z = String.valueOf(block.location().getZ());
jsonData.blocks.add(blockJson);
}
File file = new File(FILE_PATH);
File parent = file.getParentFile();
if (parent != null && !parent.exists()) {
if (parent.mkdirs()) {
LOGGER.info("Successfully created folder structure!");
} else {
LOGGER.severe("Failed to create folder structure!");
} }
try (FileWriter writer = new FileWriter(file)) {
GSON.toJson(jsonData, writer);
} catch (IOException e) {
LOGGER.severe("Error saving protected blocks: " + e.getMessage());
}
}
// Inner classes to match the JSON structure
private static class ProtectedBlocksJson {
List<BlockJson> blocks;
}
private static class BlockJson {
String owner;
String key;
LocationJson location;
}
private static class LocationJson {
String x;
String y;
String z;
}
}

View file

@ -9,11 +9,13 @@
"locations": [
{
"owner": "",
"world": "",
"x": "12",
"z": "4"
},
{
"owner": "",
"world": "",
"x": "13",
"z": "4"
}

View file

@ -1,12 +1,12 @@
{
"blocks": [
{
"owner": "",
"key": "",
"owner": "uuid",
"key": "uuid",
"location": {
"x": "",
"y": "",
"z": ""
"x": "blockx",
"y": "blocky",
"z": "blockz"
}
}
]