9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-27 19:09:09 +00:00

Added unsafe commands

This commit is contained in:
XiaoMoMi
2024-09-15 17:18:33 +08:00
parent ce4c12da11
commit 389fa9e3c6
27 changed files with 412 additions and 107 deletions

View File

@@ -92,29 +92,6 @@ public interface ActionManager<T> extends Reloadable {
*/
Action<T> parseAction(@NotNull String type, @NotNull Object args);
/**
* Generates a map of actions triggered by specific events from a configuration section.
*
* @param section The configuration section containing event-action mappings.
* @return A map where the keys are action triggers and the values are arrays of actions associated with those triggers.
*/
default Map<ActionTrigger, Action<T>[]> parseEventActions(Section section) {
HashMap<ActionTrigger, Action<T>[]> actionMap = new HashMap<>();
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
if (entry.getValue() instanceof Section innerSection) {
try {
actionMap.put(
ActionTrigger.valueOf(entry.getKey().toUpperCase(Locale.ENGLISH)),
parseActions(innerSection)
);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
}
}
return actionMap;
}
/**
* Parses a configuration section to generate a map of timed actions.
*

View File

@@ -1,24 +0,0 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.action;
public enum ActionTrigger {
PLACE,
BREAK,
WORK, INTERACT
}

View File

@@ -117,6 +117,10 @@ public class SynchronizedCompoundMap {
return compoundMapToString("BlockData", compoundMap);
}
public String asString() {
return compoundMapToString("", compoundMap);
}
/**
* Recursively converts a CompoundMap to a string representation.
*
@@ -126,12 +130,15 @@ public class SynchronizedCompoundMap {
*/
@SuppressWarnings("unchecked")
private String compoundMapToString(String key, CompoundMap compoundMap) {
StringJoiner joiner = new StringJoiner(", ");
StringJoiner joiner = new StringJoiner(",");
for (Map.Entry<String, Tag<?>> entry : compoundMap.entrySet()) {
Tag<?> tag = entry.getValue();
String tagValue;
switch (tag.getType()) {
case TAG_STRING, TAG_BYTE, TAG_DOUBLE, TAG_FLOAT, TAG_INT, TAG_INT_ARRAY,
case TAG_STRING -> {
tagValue = "\"" + tag.getValue().toString() + "\"";
}
case TAG_BYTE, TAG_DOUBLE, TAG_FLOAT, TAG_INT, TAG_INT_ARRAY,
TAG_LONG, TAG_SHORT, TAG_SHORT_ARRAY, TAG_LONG_ARRAY, TAG_BYTE_ARRAY ->
tagValue = tag.getValue().toString();
case TAG_LIST -> {
@@ -151,8 +158,12 @@ public class SynchronizedCompoundMap {
continue; // skip unsupported tag types
}
}
joiner.add("\"" + entry.getKey() + "\":\"" + tagValue + "\"");
joiner.add(entry.getKey() + "=" + tagValue);
}
if (key.isEmpty()) {
return joiner.toString();
} else {
return key + "=[" + joiner + "]";
}
return key + "{" + joiner + "}";
}
}

View File

@@ -168,10 +168,21 @@ public class CropBlock extends AbstractCustomCropsBlock {
}
@Override
public boolean isBlockInstance(String id) {
public boolean isInstance(String id) {
return Registries.STAGE_TO_CROP_UNSAFE.containsKey(id);
}
@Override
public void restore(Location location, CustomCropsBlockState state) {
CropConfig config = config(state);
if (config == null) return;
int point = point(state);
CropStageConfig stageConfig = config.stageWithModelByPoint(point);
if (stageConfig != null) {
BukkitCustomCropsPlugin.getInstance().getItemManager().place(location, stageConfig.existenceForm(), Objects.requireNonNull(stageConfig.stageID()), config.rotation() ? FurnitureRotation.random() : FurnitureRotation.NONE);
}
}
@Override
public void onInteract(WrappedInteractEvent event) {
final Player player = event.player();

View File

@@ -26,26 +26,76 @@ import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent;
import net.momirealms.customcrops.api.core.wrapper.WrappedPlaceEvent;
import net.momirealms.customcrops.api.misc.NamedTextColor;
import net.momirealms.customcrops.common.util.Key;
import org.bukkit.Location;
public interface CustomCropsBlock {
/**
* Get the key
*
* @return key
*/
Key type();
/**
* Create a CustomCropsBlockState based on this type
*
* @return CustomCropsBlockState
*/
CustomCropsBlockState createBlockState();
/**
* Create a CustomCropsBlockState based on this type and provided data
*
* @return CustomCropsBlockState
*/
CustomCropsBlockState createBlockState(CompoundMap data);
/**
* Runs scheduled tick tasks
*/
void scheduledTick(CustomCropsBlockState state, CustomCropsWorld<?> world, Pos3 location, boolean offlineTick);
/**
* Runs random tick tasks
*/
void randomTick(CustomCropsBlockState state, CustomCropsWorld<?> world, Pos3 location, boolean offlineTick);
/**
* Handles interactions
*/
void onInteract(WrappedInteractEvent event);
/**
* Handles breaks
*/
void onBreak(WrappedBreakEvent event);
/**
* Handles placement
*/
void onPlace(WrappedPlaceEvent event);
boolean isBlockInstance(String id);
/**
* Checks if the id is an instance of this block type
*
* @param id id
* @return is instance or not
*/
boolean isInstance(String id);
/**
* Restores the bukkit block state or furniture based on the given block state
*
* @param location the location of the block
* @param state the provided state
*/
void restore(Location location, CustomCropsBlockState state);
/**
* Get the color on insight mode
*
* @return the color
*/
NamedTextColor insightColor();
}

View File

@@ -38,10 +38,15 @@ public class DeadCrop extends AbstractCustomCropsBlock {
}
@Override
public boolean isBlockInstance(String id) {
public boolean isInstance(String id) {
return Registries.ITEM_TO_DEAD_CROP.containsKey(id);
}
@Override
public void restore(Location location, CustomCropsBlockState state) {
// do not restore
}
@Override
public void onInteract(WrappedInteractEvent event) {
final Player player = event.player();

View File

@@ -20,6 +20,7 @@ package net.momirealms.customcrops.api.core.block;
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
import net.momirealms.customcrops.api.core.BuiltInBlockMechanics;
import net.momirealms.customcrops.api.core.ConfigManager;
import net.momirealms.customcrops.api.core.FurnitureRotation;
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
import net.momirealms.customcrops.api.core.world.Pos3;
@@ -102,10 +103,17 @@ public class GreenhouseBlock extends AbstractCustomCropsBlock {
}
@Override
public boolean isBlockInstance(String id) {
public boolean isInstance(String id) {
return ConfigManager.greenhouse().contains(id);
}
@Override
public void restore(Location location, CustomCropsBlockState state) {
String id = ConfigManager.greenhouse().stream().findAny().orElse(null);
if (id == null) return;
BukkitCustomCropsPlugin.getInstance().getItemManager().place(location, ConfigManager.greenhouseExistenceForm(), id, FurnitureRotation.NONE);
}
public CustomCropsBlockState getOrFixState(CustomCropsWorld<?> world, Pos3 pos3) {
Optional<CustomCropsBlockState> optional = world.getBlockState(pos3);
if (optional.isPresent() && optional.get().type() instanceof GreenhouseBlock) {

View File

@@ -228,10 +228,15 @@ public class PotBlock extends AbstractCustomCropsBlock {
}
@Override
public boolean isBlockInstance(String id) {
public boolean isInstance(String id) {
return Registries.ITEM_TO_POT.containsKey(id);
}
@Override
public void restore(Location location, CustomCropsBlockState state) {
updateBlockAppearance(location, state);
}
@Override
public void onInteract(WrappedInteractEvent event) {
PotConfig potConfig = Registries.ITEM_TO_POT.get(event.relatedID());
@@ -614,9 +619,13 @@ public class PotBlock extends AbstractCustomCropsBlock {
}
public void updateBlockAppearance(Location location, PotConfig config, boolean hasWater, @Nullable Fertilizer fertilizer) {
if (config.disablePluginMechanism()) return;
String appearance = config.getPotAppearance(hasWater, fertilizer == null ? null : fertilizer.type());
BukkitCustomCropsPlugin.getInstance().getItemManager().placeBlock(location, appearance);
if (config.disablePluginMechanism()) {
String appearance = config.blocks().stream().findAny().get();
BukkitCustomCropsPlugin.getInstance().getItemManager().placeBlock(location, appearance);
} else {
String appearance = config.getPotAppearance(hasWater, fertilizer == null ? null : fertilizer.type());
BukkitCustomCropsPlugin.getInstance().getItemManager().placeBlock(location, appearance);
}
}
private Fertilizer tagToFertilizer(CompoundMap tag) {

View File

@@ -20,6 +20,7 @@ package net.momirealms.customcrops.api.core.block;
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
import net.momirealms.customcrops.api.core.BuiltInBlockMechanics;
import net.momirealms.customcrops.api.core.ConfigManager;
import net.momirealms.customcrops.api.core.FurnitureRotation;
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
import net.momirealms.customcrops.api.core.world.Pos3;
@@ -102,10 +103,17 @@ public class ScarecrowBlock extends AbstractCustomCropsBlock {
}
@Override
public boolean isBlockInstance(String id) {
public boolean isInstance(String id) {
return ConfigManager.scarecrow().contains(id);
}
@Override
public void restore(Location location, CustomCropsBlockState state) {
String id = ConfigManager.scarecrow().stream().findAny().orElse(null);
if (id == null) return;
BukkitCustomCropsPlugin.getInstance().getItemManager().place(location, ConfigManager.scarecrowExistenceForm(), id, FurnitureRotation.NONE);
}
public CustomCropsBlockState getOrFixState(CustomCropsWorld<?> world, Pos3 pos3) {
Optional<CustomCropsBlockState> optional = world.getBlockState(pos3);
if (optional.isPresent() && optional.get().type() instanceof ScarecrowBlock) {

View File

@@ -148,10 +148,17 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
}
@Override
public boolean isBlockInstance(String id) {
public boolean isInstance(String id) {
return Registries.ITEM_TO_SPRINKLER.containsKey(id);
}
@Override
public void restore(Location location, CustomCropsBlockState state) {
SprinklerConfig config = config(state);
if (config == null) return;
updateBlockAppearance(location, config, water(state) != 0);
}
@Override
public void onInteract(WrappedInteractEvent event) {
SprinklerConfig config = Registries.ITEM_TO_SPRINKLER.get(event.relatedID());

View File

@@ -55,4 +55,6 @@ public interface CustomCropsBlockState extends DataBlock {
@ApiStatus.Internal
byte[] getNBTDataAsBytes();
String asString();
}

View File

@@ -46,6 +46,13 @@ public class CustomCropsBlockStateImpl implements CustomCropsBlockState {
return TagUtils.toBytes(new CompoundTag("data", compoundMap.originalMap()));
}
@Override
public String asString() {
return owner.type().asString() +
"[" + compoundMap.asString() +
']';
}
@Override
public Tag<?> set(String key, Tag<?> tag) {
return compoundMap.put(key, tag);
@@ -68,10 +75,9 @@ public class CustomCropsBlockStateImpl implements CustomCropsBlockState {
@Override
public String toString() {
return "CustomCropsBlock{" +
"Type{" + owner.type().asString() +
"}, " + compoundMap +
'}';
return owner.type().asString() +
"[" + compoundMap +
']';
}
@Override

View File

@@ -333,6 +333,12 @@ public class CustomCropsWorldImpl<W> implements CustomCropsWorld<W> {
return this.lazyChunks.remove(chunkPos);
}
public void deleteChunk(ChunkPos chunkPos) {
this.lazyChunks.remove(chunkPos);
this.loadedChunks.remove(chunkPos);
getRegion(RegionPos.getByChunkPos(chunkPos)).ifPresent(region -> region.removeCachedChunk(chunkPos));
}
@Nullable
public CustomCropsChunk getLazyChunk(ChunkPos chunkPos) {
return this.lazyChunks.get(chunkPos);