9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-23 08:59:27 +00:00

持久化存储冷却

This commit is contained in:
XiaoMoMi
2025-05-24 03:34:22 +08:00
parent 85ab8505d8
commit d3ae85f9cb
10 changed files with 74 additions and 29 deletions

View File

@@ -175,6 +175,13 @@ debug_is_section_injected:
- /craftengine debug is-section-injected
- /ce debug is-section-injected
debug_clear_cooldown:
enable: true
permission: ce.command.debug.clear_cooldown
usage:
- /craftengine debug clear-cooldown
- /ce debug clear-cooldown
debug_test:
enable: true
permission: ce.command.debug.test

View File

@@ -101,7 +101,7 @@ warning.config.condition.expression.missing_expression: "<yellow>Issue found in
warning.config.condition.is_null.missing_argument: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'argument' argument for 'is_null' condition.</yellow>"
warning.config.condition.hand.missing_hand: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'hand' argument for 'hand' condition.</yellow>"
warning.config.condition.hand.invalid_hand: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid 'hand' argument '<arg:2>' for 'hand' condition. Allowed hand types: [<arg:3>]</yellow>"
warning.config.condition.cooldown.missing_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'id' argument for 'cooldown' condition.</yellow>"
warning.config.condition.on_cooldown.missing_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'id' argument for 'on_cooldown' condition.</yellow>"
warning.config.structure.not_section: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is expected to be a config section while it's actually a(n) '<arg:2>'.</yellow>"
warning.config.image.duplicate: "<yellow>Issue found in file <arg:0> - Duplicated image '<arg:1>'. Please check if there is the same configuration in other files.</yellow>"
warning.config.image.missing_height: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' is missing the required 'height' argument.</yellow>"

View File

@@ -102,7 +102,7 @@ warning.config.condition.is_null.missing_argument: "<yellow>在文件 <arg:0>
warning.config.structure.not_section: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 应为配置段落 但实际类型为 '<arg:2>'</yellow>"
warning.config.condition.hand.missing_hand: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'hand' 条件必需的 'hand' 参数</yellow>"
warning.config.condition.hand.invalid_hand: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 使用了无效的 'hand' 参数 '<arg:2>''hand' 条件)。允许的手部类型: [<arg:3>]</yellow>"
warning.config.condition.cooldown.missing_id: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'cooldown' 条件必需的 'id' 参数</yellow>"
warning.config.condition.on_cooldown.missing_id: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'on_cooldown' 条件必需的 'id' 参数</yellow>"
warning.config.image.duplicate: "<yellow>在文件 <arg:0> 发现问题 - 重复的图片配置 '<arg:1>' 请检查其他文件中是否存在相同配置</yellow>"
warning.config.image.missing_height: "<yellow>在文件 <arg:0> 发现问题 - 图片 '<arg:1>' 缺少必需的 'height' 参数</yellow>"
warning.config.image.height_ascent_conflict: "<yellow>在文件 <arg:0> 发现问题 - 图片 '<arg:1>' 违反位图规则: 'height' 参数 '<arg:2>' 必须不小于 'ascent' 参数 '<arg:3>'</yellow>"

View File

@@ -41,6 +41,7 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
new DebugGetBlockStateRegistryIdCommand(this, plugin),
new DebugGetBlockInternalIdCommand(this, plugin),
new DebugAppearanceStateUsageCommand(this, plugin),
new DebugClearCooldownCommand(this, plugin),
new DebugRealStateUsageCommand(this, plugin),
new DebugItemDataCommand(this, plugin),
new DebugSetBlockCommand(this, plugin),

View File

@@ -0,0 +1,33 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
import org.bukkit.command.CommandSender;
import org.incendo.cloud.Command;
import org.incendo.cloud.bukkit.parser.PlayerParser;
public class DebugClearCooldownCommand extends BukkitCommandFeature<CommandSender> {
public DebugClearCooldownCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
super(commandManager, plugin);
}
@Override
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder
.required("player", PlayerParser.playerParser())
.handler(context -> {
BukkitServerPlayer serverPlayer = plugin().adapt(context.get("player"));
serverPlayer.cooldown().clearCooldowns();
plugin().senderFactory().wrap(context.sender()).sendMessage(Component.text("Done clearing cooldowns!"));
});
}
@Override
public String getFeatureID() {
return "debug_clear_cooldown";
}
}

View File

@@ -198,26 +198,21 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
Channel channel = getChannel(player);
NetWorkUser user = removeUser(channel);
if (user == null) return;
saveCooldown(player, user);
handleDisconnection(channel);
this.onlineUsers.remove(player.getUniqueId());
this.resetUserArray();
BukkitServerPlayer serverPlayer = this.onlineUsers.remove(player.getUniqueId());
if (serverPlayer != null) {
this.resetUserArray();
this.saveCooldown(player, serverPlayer.cooldown());
}
}
private void saveCooldown(Player player, NetWorkUser user) {
if (user instanceof BukkitServerPlayer serverPlayer) {
CooldownData cd = serverPlayer.cooldown();
if (cd != null) {
try {
byte[] data = CooldownData.toBytes(cd);
player.getPersistentDataContainer().set(KeyUtils.toNamespacedKey(CooldownData.COOLDOWN_KEY), PersistentDataType.BYTE_ARRAY, data);
} catch (IOException e) {
player.getPersistentDataContainer().remove(KeyUtils.toNamespacedKey(CooldownData.COOLDOWN_KEY));
this.plugin.logger().warn("Failed to save cooldown for player " + player.getName(), e);
}
private void saveCooldown(Player player, CooldownData cd) {
if (cd != null && player != null) {
try {
byte[] data = CooldownData.toBytes(cd);
player.getPersistentDataContainer().set(KeyUtils.toNamespacedKey(CooldownData.COOLDOWN_KEY), PersistentDataType.BYTE_ARRAY, data);
} catch (IOException e) {
player.getPersistentDataContainer().remove(KeyUtils.toNamespacedKey(CooldownData.COOLDOWN_KEY));
this.plugin.logger().warn("Failed to save cooldown for player " + player.getName(), e);
}
}
}
@@ -465,7 +460,9 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
String encoderName = pipeline.names().contains("outbound_config") ? "outbound_config" : "encoder";
pipeline.addBefore(encoderName, PACKET_ENCODER, new PluginChannelEncoder(user));
channel.closeFuture().addListener((ChannelFutureListener) future -> handleDisconnection(user.nettyChannel()));
channel.closeFuture().addListener((ChannelFutureListener) future -> {
handleDisconnection(user.nettyChannel());
});
setUser(channel, user);
}

View File

@@ -65,11 +65,18 @@ public class CooldownData {
if (entry.getValue() instanceof LongTag longTag) {
long expire = longTag.getAsLong();
if (currentTime < expire) {
cd.setCooldown(entry.getKey(), expire);
cd.cooldownMap.put(entry.getKey(), expire);
}
}
}
}
return cd;
}
@Override
public String toString() {
return "CooldownData{" +
"cooldownMap=" + cooldownMap +
'}';
}
}

View File

@@ -18,7 +18,7 @@ public final class CommonConditions {
public static final Key FALLING_BLOCK = Key.from("craftengine:falling_block");
public static final Key DISTANCE = Key.from("craftengine:distance");
public static final Key PERMISSION = Key.from("craftengine:permission");
public static final Key COOLDOWN = Key.from("craftengine:cooldown");
public static final Key ON_COOLDOWN = Key.from("craftengine:on_cooldown");
public static final Key EQUALS = Key.from("craftengine:equals");
public static final Key STRING_EQUALS = Key.from("craftengine:string_equals");
public static final Key STRING_CONTAINS = Key.from("craftengine:string_contains");

View File

@@ -10,16 +10,16 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
import java.util.Optional;
public class CooldownCondition<CTX extends Context> implements Condition<CTX> {
public class OnCooldownCondition<CTX extends Context> implements Condition<CTX> {
private final String key;
public CooldownCondition(String key) {
public OnCooldownCondition(String key) {
this.key = key;
}
@Override
public Key type() {
return CommonConditions.COOLDOWN;
return CommonConditions.ON_COOLDOWN;
}
@Override
@@ -36,8 +36,8 @@ public class CooldownCondition<CTX extends Context> implements Condition<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {
String id = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("id"), "warning.config.condition.cooldown.missing_id");
return new CooldownCondition<>(id);
String id = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("id"), "warning.config.condition.on_cooldown.missing_id");
return new OnCooldownCondition<>(id);
}
}
}

View File

@@ -36,7 +36,7 @@ public class EventConditions {
register(CommonConditions.EXPRESSION, new ExpressionCondition.FactoryImpl<>());
register(CommonConditions.IS_NULL, new IsNullCondition.FactoryImpl<>());
register(CommonConditions.HAND, new HandCondition.FactoryImpl<>());
register(CommonConditions.COOLDOWN, new CooldownCondition.FactoryImpl<>());
register(CommonConditions.ON_COOLDOWN, new OnCooldownCondition.FactoryImpl<>());
}
public static void register(Key key, ConditionFactory<PlayerOptionalContext> factory) {