9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-31 12:56:28 +00:00

Merge pull request #518 from jhqwqmc/dev

dev
This commit is contained in:
XiaoMoMi
2025-12-28 22:07:03 +08:00
committed by GitHub
11 changed files with 229 additions and 17 deletions

View File

@@ -0,0 +1,84 @@
package net.momirealms.craftengine.bukkit.compatibility.papi;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.context.CooldownData;
import net.momirealms.craftengine.core.util.CountdownFormatter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CraftEngineExpansion extends PlaceholderExpansion {
private final CraftEngine plugin;
public CraftEngineExpansion(CraftEngine plugin) {
this.plugin = plugin;
}
@NotNull
@Override
public String getIdentifier() {
return "ce";
}
@NotNull
@Override
public String getAuthor() {
return "jhqwqmc";
}
@NotNull
@Override
public String getVersion() {
return "1.0";
}
/**
* 用法:(小括号括起来的为必填,中括号括起来的为选填)
* <p>
* %ce_cd_(key)|[format]%
*/
@Override
public @Nullable String onPlaceholderRequest(Player bukkitPlayer, @NotNull String params) {
BukkitServerPlayer player = bukkitPlayer != null ? BukkitAdaptors.adapt(bukkitPlayer) : null;
int index = params.indexOf('_');
String action = index > 0 ? params.substring(0, index) : params;
String[] param;
if (index > 0) {
String substring = params.substring(index + 1);
int i = substring.indexOf('|');
if (i > 0) {
param = new String[]{substring.substring(0, i), substring.substring(i + 1)};
} else {
param = new String[]{substring};
}
} else {
param = new String[0];
}
return switch (action) {
case "cd", "cooldown" -> handleCooldown(player, param);
default -> null;
};
}
@Nullable
private static String handleCooldown(@Nullable BukkitServerPlayer player, String[] param) {
if (player == null || param.length < 1) {
return null;
}
CooldownData cooldown = player.cooldown();
if (cooldown == null) {
return null;
}
Long ms = cooldown.getCooldown(param[0]);
if (ms == null) {
return null;
}
if (param.length >= 2) {
return CountdownFormatter.of(param[1]).format(ms);
}
return String.valueOf(ms);
}
}

View File

@@ -21,5 +21,6 @@ public class PlaceholderAPIUtils {
new ImageExpansion(plugin).register();
new ShiftExpansion(plugin).register();
new CheckItemExpansion(plugin).register();
new CraftEngineExpansion(plugin).register();
}
}

View File

@@ -603,7 +603,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
// 如果不是原版物品那么加入ce的标识符
if (!isVanillaItem)
itemBuilder.dataModifier(new IdProcessor(id));
itemBuilder.dataModifier(new IdProcessor<>(id));
// 事件
Map<EventTrigger, List<net.momirealms.craftengine.core.plugin.context.function.Function<Context>>> eventTriggerListMap;

View File

@@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.item;
import net.momirealms.craftengine.core.item.processor.ItemProcessor;
public interface ItemProcessorFactory<T extends ItemProcessor> {
public interface ItemProcessorFactory<I> {
T create(Object arg);
ItemProcessor<I> create(Object arg);
}

View File

@@ -5,9 +5,9 @@ import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.item.ItemProcessorFactory;
import net.momirealms.craftengine.core.util.Key;
public class IdProcessor implements ItemProcessor {
public class IdProcessor<I> implements ItemProcessor<I> {
public static final String CRAFT_ENGINE_ID = "craftengine:id";
public static final ItemProcessorFactory<IdProcessor> FACTORY = new Factory();
public static final ItemProcessorFactory<?> FACTORY = new Factory<>();
private final Key argument;
public IdProcessor(Key argument) {
@@ -19,17 +19,17 @@ public class IdProcessor implements ItemProcessor {
}
@Override
public Item<?> apply(Item<?> item, ItemBuildContext context) {
public Item<I> apply(Item<I> item, ItemBuildContext context) {
item.customId(this.argument);
return item;
}
private static class Factory implements ItemProcessorFactory<IdProcessor> {
private static class Factory<I> implements ItemProcessorFactory<I> {
@Override
public IdProcessor create(Object arg) {
public ItemProcessor<I> create(Object arg) {
String id = arg.toString();
return new IdProcessor(Key.of(id));
return new IdProcessor<>(Key.of(id));
}
}
}

View File

@@ -4,11 +4,11 @@ import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.sparrow.nbt.CompoundTag;
public interface ItemProcessor {
public interface ItemProcessor<I> {
Item<?> apply(Item<?> item, ItemBuildContext context);
Item<I> apply(Item<I> item, ItemBuildContext context);
default Item<?> prepareNetworkItem(Item<?> item, ItemBuildContext context, CompoundTag networkData) {
default Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
return item;
}
}

View File

@@ -3,5 +3,5 @@ package net.momirealms.craftengine.core.item.processor;
import net.momirealms.craftengine.core.item.ItemProcessorFactory;
import net.momirealms.craftengine.core.util.Key;
public record ItemProcessorType<T extends ItemProcessor>(Key id, ItemProcessorFactory<T> factory) {
public record ItemProcessorType<T>(Key id, ItemProcessorFactory<T> factory) {
}

View File

@@ -44,6 +44,10 @@ public class CooldownData {
this.cooldownMap.clear();
}
public Long getCooldown(String key) {
return this.cooldownMap.get(key);
}
public static byte[] toBytes(CooldownData data) throws IOException {
CompoundTag tag = new CompoundTag();
long currentTime = System.currentTimeMillis();

View File

@@ -18,7 +18,6 @@ import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorType;
import net.momirealms.craftengine.core.item.equipment.Equipment;
import net.momirealms.craftengine.core.item.equipment.EquipmentType;
import net.momirealms.craftengine.core.item.processor.ItemProcessor;
import net.momirealms.craftengine.core.item.processor.ItemProcessorType;
import net.momirealms.craftengine.core.item.recipe.CustomSmithingTransformRecipe;
import net.momirealms.craftengine.core.item.recipe.Recipe;
@@ -66,7 +65,7 @@ import net.momirealms.craftengine.core.util.ResourceKey;
public final class BuiltInRegistries {
public static final Registry<CustomBlock> BLOCK = createDynamicBoundRegistry(Registries.BLOCK, 512);
public static final Registry<BlockBehaviorType<? extends BlockBehavior>> BLOCK_BEHAVIOR_TYPE = createConstantBoundRegistry(Registries.BLOCK_BEHAVIOR_TYPE, 64);
public static final Registry<ItemProcessorType<? extends ItemProcessor>> ITEM_PROCESSOR_TYPE = createConstantBoundRegistry(Registries.ITEM_PROCESSOR_TYPE, 64);
public static final Registry<ItemProcessorType<?>> ITEM_PROCESSOR_TYPE = createConstantBoundRegistry(Registries.ITEM_PROCESSOR_TYPE, 64);
public static final Registry<ItemBehaviorType<? extends ItemBehavior>> ITEM_BEHAVIOR_TYPE = createConstantBoundRegistry(Registries.ITEM_BEHAVIOR_TYPE, 64);
public static final Registry<PropertyType<? extends Comparable<?>>> PROPERTY_TYPE = createConstantBoundRegistry(Registries.PROPERTY_TYPE, 16);
public static final Registry<LootFunctionType<?>> LOOT_FUNCTION_TYPE = createConstantBoundRegistry(Registries.LOOT_FUNCTION_TYPE, 32);

View File

@@ -18,7 +18,6 @@ import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorType;
import net.momirealms.craftengine.core.item.equipment.Equipment;
import net.momirealms.craftengine.core.item.equipment.EquipmentType;
import net.momirealms.craftengine.core.item.processor.ItemProcessor;
import net.momirealms.craftengine.core.item.processor.ItemProcessorType;
import net.momirealms.craftengine.core.item.recipe.CustomSmithingTransformRecipe;
import net.momirealms.craftengine.core.item.recipe.Recipe;
@@ -69,7 +68,7 @@ public final class Registries {
public static final Key ROOT_REGISTRY = Key.withDefaultNamespace("root");
public static final ResourceKey<Registry<CustomBlock>> BLOCK = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("block"));
public static final ResourceKey<Registry<ItemProcessorType<? extends ItemProcessor>>> ITEM_PROCESSOR_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("item_processor_type"));
public static final ResourceKey<Registry<ItemProcessorType<?>>> ITEM_PROCESSOR_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("item_processor_type"));
public static final ResourceKey<Registry<PropertyType<? extends Comparable<?>>>> PROPERTY_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("property_type"));
public static final ResourceKey<Registry<BlockBehaviorType<? extends BlockBehavior>>> BLOCK_BEHAVIOR_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("block_behavior_type"));
public static final ResourceKey<Registry<ItemBehaviorType<? extends ItemBehavior>>> ITEM_BEHAVIOR_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("item_behavior_type"));

View File

@@ -0,0 +1,125 @@
package net.momirealms.craftengine.core.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class CountdownFormatter {
private static final Pattern YEAR_PATTERN = Pattern.compile("[Yy]+");
private static final Pattern MONTH_PATTERN = Pattern.compile("M+");
private static final Pattern DAY_PATTERN = Pattern.compile("[Dd]+");
private static final Pattern HOUR_PATTERN = Pattern.compile("[Hh]+");
private static final Pattern MINUTE_PATTERN = Pattern.compile("m+");
private static final Pattern SECOND_PATTERN = Pattern.compile("s+");
private static final Pattern MILLIS_PATTERN = Pattern.compile("S+");
private final String pattern;
private final Matcher yearMatcher;
private final Matcher monthMatcher;
private final Matcher dayMatcher;
private final Matcher hourMatcher;
private final Matcher minuteMatcher;
private final Matcher secondMatcher;
private final Matcher millisMatcher;
private final boolean hasYear;
private final boolean hasMonth;
private final boolean hasDay;
private final boolean hasHour;
private final boolean hasMinute;
private final boolean hasSecond;
private final boolean hasMillis;
private CountdownFormatter(String pattern) {
this.pattern = pattern;
this.yearMatcher = YEAR_PATTERN.matcher(pattern);
this.monthMatcher = MONTH_PATTERN.matcher(pattern);
this.dayMatcher = DAY_PATTERN.matcher(pattern);
this.hourMatcher = HOUR_PATTERN.matcher(pattern);
this.minuteMatcher = MINUTE_PATTERN.matcher(pattern);
this.secondMatcher = SECOND_PATTERN.matcher(pattern);
this.millisMatcher = MILLIS_PATTERN.matcher(pattern);
this.hasYear = yearMatcher.find();
this.hasMonth = monthMatcher.find();
this.hasDay = dayMatcher.find();
this.hasHour = hourMatcher.find();
this.hasMinute = minuteMatcher.find();
this.hasSecond = secondMatcher.find();
this.hasMillis = millisMatcher.find();
}
public static CountdownFormatter of(String pattern) {
return new CountdownFormatter(pattern);
}
public String format(long millis) {
long years = 0, months = 0, days = 0, hours = 0, minutes = 0, seconds = 0;
if (!hasMillis) {
seconds = millis / 1000;
millis = 0;
}
if (!hasSecond) {
minutes = seconds / 60;
seconds = 0;
}
if (!hasMinute) {
hours = minutes / 60;
minutes = 0;
}
if (!hasHour) {
days = hours / 24;
hours = 0;
}
if (!hasDay) {
months = days / 30;
days = 0;
}
if (!hasMonth) {
years = months / 12;
months = 0;
}
if (hasMillis && hasSecond) {
seconds = millis / 1000;
millis %= 1000;
}
if (hasSecond && hasMinute) {
minutes = seconds / 60;
seconds %= 60;
}
if (hasMinute && hasHour) {
hours = minutes / 60;
minutes %= 60;
}
if (hasHour && hasDay) {
days = hours / 24;
hours %= 24;
}
if (hasDay && hasMonth) {
months = days / 30;
days %= 30;
}
if (hasMonth && hasYear) {
years = months / 12;
months %= 12;
}
StringBuilder result = new StringBuilder(pattern);
replaceUnit(result, yearMatcher, years);
replaceUnit(result, monthMatcher, months);
replaceUnit(result, dayMatcher, days);
replaceUnit(result, hourMatcher, hours);
replaceUnit(result, minuteMatcher, minutes);
replaceUnit(result, secondMatcher, seconds);
replaceUnit(result, millisMatcher, millis);
return result.toString();
}
private void replaceUnit(StringBuilder text, Matcher matcher, long value) {
matcher.reset(text);
if (matcher.find()) {
int length = matcher.group().length();
String formatted = String.format("%0" + length + "d", value);
text.replace(matcher.start(), matcher.end(), formatted);
}
}
}