Skip to content

Commit

Permalink
Work on separating block/entity classes from world profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
cjburkey01 committed Aug 16, 2024
1 parent 418a8f6 commit f74cf47
Show file tree
Hide file tree
Showing 11 changed files with 332 additions and 111 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Spigot plugin for 1.20+ allowing the claiming of chunks.
Usage and more information can be found [on the wiki](https://github.com/cjburkey01/ClaimChunk/wiki).

* **1.20-1.21+** | The latest version works seamlessly (excluding bugs, of course).
* **Note for 0.0.23**: When updating the server from 1.20 to 1.21, ClaimChunk will throw errors that it can't find entities by whatever names due to the enum API change.
* **Note for 0.0.23+**! When updating the server from 1.20 to 1.21, ClaimChunk will throw errors that it can't find entities by whatever names due to the enum API change.
* If you keep getting those errors on server start, stop the server, open your old profiles at `/plugins/ClaimChunk/worlds/<PROFILE>.txt`, then copy these lines and replace the old (similar looking) ones in each world profile file:
```
_._@B_:
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/com/cjburkey/claimchunk/ClaimChunk.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.cjburkey.claimchunk;

import com.cjburkey.claimchunk.access.CCInteractClasses;
import com.cjburkey.claimchunk.api.IClaimChunkPlugin;
import com.cjburkey.claimchunk.api.layer.ClaimChunkLayerHandler;
import com.cjburkey.claimchunk.chunk.*;
Expand Down Expand Up @@ -111,6 +112,8 @@ public final class ClaimChunk extends JavaPlugin implements IClaimChunkPlugin {
@Getter private MainHandler mainHandler;
@Getter private ChunkOutlineHandler chunkOutlineHandler;

@Getter private CCInteractClasses interactClasses;

// Config conversion storage
private FromPre0023 fromPre0023;

Expand Down Expand Up @@ -204,6 +207,21 @@ public void onLoad() {
} else {
Utils.log("Skipped registering WorldGuard flag, it's already initialized");
}

// Initialize block/entity classes and write the file that lists them for admin reference
interactClasses = new CCInteractClasses(true);
File interactClassesFile = new File(getDataFolder(), "classes.yml");
try {
boolean existed = interactClassesFile.exists();
interactClasses.toYaml().save(interactClassesFile);
if (!existed) {
Utils.log("Created classes reference file at classes.yml :)");
}
} catch (Exception e) {
Utils.warn(
"Failed to write classes.yml file. This doesn't really matter, but something"
+ " else is probably wrong!");
}
}

boolean checkBStats(Metrics metrics) {
Expand Down
5 changes: 1 addition & 4 deletions src/main/java/com/cjburkey/claimchunk/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,7 @@ public static boolean hasAdmin(@Nullable CommandSender sender) {

private static String prepMsg(String msg, Object... data) {
// Prepare a safe console message
String out = (msg == null) ? "null" : msg;

// Output with the ClaimChunk prefix
return "[ClaimChunk] " + color(String.format(out, data));
return color(String.format((msg == null) ? "null" : msg, data));
}

public static Map<String, Boolean> getDefaultPermissionsMap() {
Expand Down
125 changes: 125 additions & 0 deletions src/main/java/com/cjburkey/claimchunk/access/CCInteractClasses.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package com.cjburkey.claimchunk.access;

import com.cjburkey.claimchunk.config.ClaimChunkWorldProfileHandler;

import org.bukkit.Material;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull;

import java.util.*;
import java.util.stream.Collectors;

public final class CCInteractClasses {

private final HashMap<String, HashSet<Material>> classBlocks = new HashMap<>();
private final HashMap<String, HashSet<EntityType>> classEntities = new HashMap<>();

private final HashMap<Material, HashSet<String>> blockClasses = new HashMap<>();
private final HashMap<EntityType, HashSet<String>> entityClasses = new HashMap<>();

public CCInteractClasses(boolean includeDefault) {
if (includeDefault) {
for (Map.Entry<String, HashSet<Material>> classes :
ClaimChunkWorldProfileHandler.getDefaultBlockAccessClasses().entrySet()) {
addBlockClass(classes.getKey(), classes.getValue());
}
for (Map.Entry<String, HashSet<EntityType>> classes :
ClaimChunkWorldProfileHandler.getDefaultEntityAccessClasses().entrySet()) {
addEntityClass(classes.getKey(), classes.getValue());
}
}
}

public void addBlockClass(String className, Collection<Material> materials) {
classBlocks(className).addAll(materials);
materials.forEach(block -> blockClasses(block).add(className));
}

public void addBlockClass(String className, Material... materials) {
Collections.addAll(classBlocks(className), materials);
Arrays.stream(materials).forEach(block -> blockClasses(block).add(className));
}

public void addEntityClass(String className, Collection<EntityType> entities) {
classEntities(className).addAll(entities);
entities.forEach(entity -> entityClasses(entity).add(className));
}

public void addEntityClass(String className, EntityType... entities) {
Collections.addAll(classEntities(className), entities);
Arrays.stream(entities).forEach(entity -> entityClasses(entity).add(className));
}

// RETURNED SET IS UNMODIFIABLE!
public @NotNull Set<Material> getClassBlocks(String className) {
return classBlocks.containsKey(className)
? Collections.unmodifiableSet(classBlocks(className))
: Collections.emptySet();
}

// RETURNED SET IS UNMODIFIABLE!
public @NotNull Set<EntityType> getClassEntities(String className) {
return classEntities.containsKey(className)
? Collections.unmodifiableSet(classEntities(className))
: Collections.emptySet();
}

// RETURNED SET IS UNMODIFIABLE!
public @NotNull Set<String> getBlockClasses(Material block) {
return blockClasses.containsKey(block)
? Collections.unmodifiableSet(blockClasses(block))
: Collections.emptySet();
}

// RETURNED SET IS UNMODIFIABLE!
public @NotNull Set<String> getEntityClasses(EntityType entity) {
return entityClasses.containsKey(entity)
? Collections.unmodifiableSet(entityClasses(entity))
: Collections.emptySet();
}

public YamlConfiguration toYaml() {
YamlConfiguration config = new YamlConfiguration();
config.options()
.setHeader(
Arrays.asList(
"Do not modify!",
"This file lists classes that may be used in the flag config file"
+ " and world profiles",
"This file is reset every server launch! Changes will not be"
+ " reflected in-game!"));

// Write block classes
for (Map.Entry<String, HashSet<Material>> entry : classBlocks.entrySet()) {
config.set(
"blockClasses." + entry.getKey(),
entry.getValue().stream().map(Material::name).collect(Collectors.toList()));
}

// Write entity classes
for (Map.Entry<String, HashSet<EntityType>> entry : classEntities.entrySet()) {
config.set(
"entityClasses." + entry.getKey(),
entry.getValue().stream().map(EntityType::name).collect(Collectors.toList()));
}

return config;
}

private @NotNull HashSet<Material> classBlocks(String className) {
return classBlocks.computeIfAbsent(className, ignoredKey -> new HashSet<>());
}

private @NotNull HashSet<EntityType> classEntities(String className) {
return classEntities.computeIfAbsent(className, ignoredKey -> new HashSet<>());
}

private @NotNull HashSet<String> blockClasses(Material block) {
return blockClasses.computeIfAbsent(block, ignoredKey -> new HashSet<>());
}

private @NotNull HashSet<String> entityClasses(EntityType entity) {
return entityClasses.computeIfAbsent(entity, ignoredKey -> new HashSet<>());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.cjburkey.claimchunk.flags;
package com.cjburkey.claimchunk.access;

import com.cjburkey.claimchunk.Utils;
import com.google.common.base.Charsets;
Expand All @@ -21,12 +21,22 @@
*
* @since 0.0.26
*/
public class PermFlags {
public class CCPermFlags {

public final HashMap<String, BlockFlagData> blockControls = new HashMap<>();
public final HashMap<String, EntityFlagData> entityControls = new HashMap<>();

/** Read the flags defined in the flag definitions file. */
/**
* Read the flags defined in the flag definitions file.
*
* @param flagsFile The file within the /plugins/ClaimChunk directory that stores the flag
* configurations.
* @param plugin An instance of the plugin whose jar contains the default flags resource
* (probably an instance of ClaimChunk, used to call {@link
* JavaPlugin#getResource(String)}).
* @param defaultFlagsResource The path to/name of the default flags resource in the plugin jar
* file.
*/
public void load(File flagsFile, JavaPlugin plugin, String defaultFlagsResource) {
// Load the flags.yml file while ensuring the default exists
YamlConfiguration config = readFlagFile(flagsFile, plugin, defaultFlagsResource);
Expand All @@ -37,6 +47,12 @@ public void load(File flagsFile, JavaPlugin plugin, String defaultFlagsResource)
loadFromConfig(config);
}

/**
* Load from the provided configuration data. The config should contain a section named
* `permissionFlags` containing the flags.
*
* @param config The config file from which to load the user-defined flags.
*/
public void loadFromConfig(YamlConfiguration config) {
// Read the flag section
ConfigurationSection flagSection = config.getConfigurationSection("permissionFlags");
Expand All @@ -60,7 +76,7 @@ public void loadFromConfig(YamlConfiguration config) {
if (interactType == null) {
Utils.err(
"Missing interaction type in one of the flag protection maps in flag"
+ " \"%s\"",
+ " \"%s\"",
flagName);
}

Expand Down Expand Up @@ -89,7 +105,7 @@ public void loadFromConfig(YamlConfiguration config) {
if (flagData == null) {
Utils.err(
"Failed to load flag includes/excludes from flag \"%s\" for"
+ " block protections",
+ " block protections",
flagName);
}

Expand Down Expand Up @@ -120,17 +136,18 @@ public void loadFromConfig(YamlConfiguration config) {
if (flagData == null) {
Utils.err(
"Failed to load flag includes/excludes from flag \"%s\" for"
+ " entity protections",
+ " entity protections",
flagName);
}

// Add the protections
EntityFlagData entityFlagData = new EntityFlagData(flagType, flagData);
entityControls.put(flagName, entityFlagData);
}
default -> Utils.err(
"Invalid flag protection target \"%s\" for flag \"%s\"",
forType, flagName);
default ->
Utils.err(
"Invalid flag protection target \"%s\" for flag \"%s\"",
forType, flagName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,19 @@ public void unloadAllProfiles() {
entityType.getEntityClass())))
.forEach(vehicles::add);

// Containers (Keep up to date? Need to work on this)
HashSet<EntityType> containers = new HashSet<>();
Collections.addAll(
containers,
EntityType.CHEST_BOAT,
EntityType.CHEST_MINECART,
EntityType.HOPPER_MINECART);

entityAccessMapping.put("MONSTERS", monsters);
entityAccessMapping.put("HANGING_ENTITIES", hangingEntities);
entityAccessMapping.put("ANIMALS", animals);
entityAccessMapping.put("VEHICLES", vehicles);
entityAccessMapping.put("CONTAINER_ENTITIES", containers);

return entityAccessMapping;
}
Expand Down
60 changes: 0 additions & 60 deletions src/main/resources/defaultFlags.yml

This file was deleted.

Loading

0 comments on commit f74cf47

Please sign in to comment.