mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
@@ -14,6 +14,7 @@ import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
import io.papermc.paper.event.player.AsyncPlayerSpawnLocationEvent;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
@@ -129,6 +130,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -1767,6 +1769,15 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
|
||||
public static class FinishConfigurationListener implements NMSPacketListener {
|
||||
|
||||
private void returnToWorld(NetWorkUser user, Queue<Object> configurationTasks, Object packetListener) {
|
||||
configurationTasks.add(CoreReflections.instance$JoinWorldTask);
|
||||
try {
|
||||
CoreReflections.methodHandle$ServerConfigurationPacketListenerImpl$startNextTask.invokeExact(packetListener);
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Cannot return to world for " + user.name(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
@@ -1817,15 +1828,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
// 请求资源包
|
||||
ResourcePackHost host = CraftEngine.instance().packManager().resourcePackHost();
|
||||
host.requestResourcePackDownloadLink(user.uuid()).whenComplete((dataList, t) -> {
|
||||
if (t != null) {
|
||||
CraftEngine.instance().logger().warn("Failed to get pack data for player " + user.name(), t);
|
||||
FastNMS.INSTANCE.method$ServerConfigurationPacketListenerImpl$returnToWorld(packetListener);
|
||||
return;
|
||||
}
|
||||
if (dataList.isEmpty()) {
|
||||
FastNMS.INSTANCE.method$ServerConfigurationPacketListenerImpl$returnToWorld(packetListener);
|
||||
return;
|
||||
}
|
||||
Queue<Object> configurationTasks;
|
||||
try {
|
||||
configurationTasks = (Queue<Object>) CoreReflections.methodHandle$ServerConfigurationPacketListenerImpl$configurationTasksGetter.invokeExact(packetListener);
|
||||
@@ -1834,13 +1836,22 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
FastNMS.INSTANCE.method$ServerConfigurationPacketListenerImpl$returnToWorld(packetListener);
|
||||
return;
|
||||
}
|
||||
if (t != null) {
|
||||
CraftEngine.instance().logger().warn("Failed to get pack data for player " + user.name(), t);
|
||||
returnToWorld(user, configurationTasks, packetListener);
|
||||
return;
|
||||
}
|
||||
if (dataList.isEmpty()) {
|
||||
returnToWorld(user, configurationTasks, packetListener);
|
||||
return;
|
||||
}
|
||||
// 向配置阶段连接的任务重加入资源包的任务
|
||||
for (ResourcePackDownloadData data : dataList) {
|
||||
configurationTasks.add(FastNMS.INSTANCE.constructor$ServerResourcePackConfigurationTask(ResourcePackUtils.createServerResourcePackInfo(data.uuid(), data.url(), data.sha1())));
|
||||
user.addResourcePackUUID(data.uuid());
|
||||
}
|
||||
// 最后再加入一个 JoinWorldTask 并开始资源包任务
|
||||
FastNMS.INSTANCE.method$ServerConfigurationPacketListenerImpl$returnToWorld(packetListener);
|
||||
returnToWorld(user, configurationTasks, packetListener);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3958,6 +3958,27 @@ public final class CoreReflections {
|
||||
}
|
||||
}
|
||||
|
||||
// 1.20.2+
|
||||
public static final Method method$ServerConfigurationPacketListenerImpl$startNextTask = Optional.ofNullable(clazz$ServerConfigurationPacketListenerImpl)
|
||||
.map(it -> ReflectionUtils.getDeclaredMethod(it, void.class, VersionHelper.isOrAbove1_20_5() ? new String[]{"startNextTask", "o"} : new String[]{"startNextTask", "p"}))
|
||||
.orElse(null);
|
||||
|
||||
public static final MethodHandle methodHandle$ServerConfigurationPacketListenerImpl$startNextTask;
|
||||
|
||||
static {
|
||||
try {
|
||||
if (VersionHelper.isOrAbove1_20_2()) {
|
||||
methodHandle$ServerConfigurationPacketListenerImpl$startNextTask =
|
||||
ReflectionUtils.unreflectMethod(method$ServerConfigurationPacketListenerImpl$startNextTask)
|
||||
.asType(MethodType.methodType(void.class, Object.class));
|
||||
} else {
|
||||
methodHandle$ServerConfigurationPacketListenerImpl$startNextTask = null;
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ReflectionInitException("Failed to initialize reflection", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Class<?> clazz$JoinWorldTask = MiscUtils.requireNonNullIf(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("server.network.config.JoinWorldTask")
|
||||
|
||||
@@ -220,7 +220,7 @@ warning.config.template.argument.self_increase_int.invalid_range: "<yellow>Issue
|
||||
warning.config.template.argument.to_upper_case.invalid_locale: "<yellow>Issue found in file <arg:0> - The template '<arg:1>' is using an invalid locale '<arg:2>' in 'to_upper_case' argument.</yellow>"
|
||||
warning.config.template.argument.to_upper_case.missing_value: "<yellow>Issue found in file <arg:0> - The template '<arg:1>' is missing the required 'value' argument for 'to_upper_case' argument.</yellow>"
|
||||
warning.config.template.argument.to_lower_case.invalid_locale: "<yellow>Issue found in file <arg:0> - The template '<arg:1>' is using an invalid locale '<arg:2>' in 'to_lower_case' argument.</yellow>"
|
||||
warning.config.template.argument.to_lower_case.missing_value: "<yellow>Issue found in file <arg:0> - The template '<arg:1>' is missing the required 'value' argument for 'to_upper_case' argument.</yellow>"
|
||||
warning.config.template.argument.to_lower_case.missing_value: "<yellow>Issue found in file <arg:0> - The template '<arg:1>' is missing the required 'value' argument for 'to_lower_case' argument.</yellow>"
|
||||
warning.config.template.argument.list.invalid_type: "<yellow>Issue found in file <arg:0> - The template '<arg:1>' is using a 'list' argument which expects a 'List' as argument while the input argument is a(n) '<arg:2>'.</yellow>"
|
||||
warning.config.template.argument.missing_value: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the template argument for '<arg:2>'. Please use the arguments option to configure or set a default value for this parameter.</yellow>"
|
||||
warning.config.vanilla_loot.missing_type: "<yellow>Issue found in file <arg:0> - The vanilla loot '<arg:1>' is missing the required 'type' argument.</yellow>"
|
||||
@@ -544,6 +544,7 @@ warning.config.function.transform_block.missing_block: "<yellow>Issue found in f
|
||||
warning.config.function.cycle_block_property.missing_property: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'property' argument for 'cycle_block_property' function.</yellow>"
|
||||
warning.config.function.set_exp.missing_count: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'count' argument for 'set_exp' function.</yellow>"
|
||||
warning.config.function.set_level.missing_count: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'count' argument for 'set_level' function.</yellow>"
|
||||
warning.config.function.play_totem_animation.missing_item: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'item' argument for 'play_totem_animation' function.</yellow>"
|
||||
warning.config.function.clear_item.missing_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'id' argument for 'clear_item' function.</yellow>"
|
||||
warning.config.selector.missing_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'type' argument for selector.</yellow>"
|
||||
warning.config.selector.invalid_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid selector type '<arg:2>'.</yellow>"
|
||||
|
||||
@@ -88,6 +88,8 @@ command.send_resource_pack.success.multiple: "<white>发送资源包给 <arg:0>
|
||||
command.locale.set.failure: "<red>区域设置格式无效: <arg:0></red>"
|
||||
command.locale.set.success: "<white>已为 <arg:1> 更新选定区域设置为 <arg:0></white>"
|
||||
command.locale.unset.success: "<white>已清除 <arg:0> 的选定区域设置</white>"
|
||||
command.entity_view_distance_scale.set.success: "<white>已为 <arg:1> 的实体可见距离百分比设置为 <arg:0></white>"
|
||||
command.entity_culling.toggle.success: "<white>已为 <arg:1> 的实体剔除状态设置为 <arg:0></white>"
|
||||
warning.network.resource_pack.unverified_uuid: "<yellow>玩家 <arg:0> 使用未经服务器验证的 UUID (<arg:1>) 尝试请求获取资源包</yellow>"
|
||||
warning.config.pack.duplicated_files: "<red>发现重复文件 请通过 config.yml 的 'resource-pack.duplicated-files-handler' 部分解决</red>"
|
||||
warning.config.yaml.duplicated_key: "<red>在文件 <arg:0> 发现问题 - 在第<arg:2>行发现重复的键 '<arg:1>', 这可能会导致一些意料之外的问题</red>"
|
||||
@@ -101,6 +103,7 @@ warning.config.type.quaternionf: "<yellow>在文件 <arg:0> 发现问题 - 无
|
||||
warning.config.type.vector3f: "<yellow>在文件 <arg:0> 发现问题 - 无法加载 '<arg:1>': 无法将 '<arg:2>' 转换为三维向量类型 (选项 '<arg:3>')</yellow>"
|
||||
warning.config.type.vec3d: "<yellow>在文件 <arg:0> 发现问题 - 无法加载 '<arg:1>': 无法将 '<arg:2>' 转换为双精度浮点数三维向量类型 (选项 '<arg:3>')</yellow>"
|
||||
warning.config.type.map: "<yellow>在文件 <arg:0> 发现问题 - 无法加载 '<arg:1>': 无法将 '<arg:2>' 转换为映射类型 (选项 '<arg:3>')</yellow>"
|
||||
warning.config.type.aabb: "<yellow>在文件 <arg:0> 发现问题 - 无法加载 '<arg:1>': 无法将 '<arg:2>' 转换为轴对齐包围盒类型 (选项 '<arg:3>')</yellow>"
|
||||
warning.config.type.snbt.invalid_syntax: "<yellow>在文件 <arg:0> 发现问题 - 无法加载 '<arg:1>': 无效的 SNBT 语法 '<arg:2>'</yellow>"
|
||||
warning.config.type.snbt.invalid_syntax.parse_error: "<yellow><arg:0>,位于第<arg:1>个字符:<arg:2></yellow>"
|
||||
warning.config.type.snbt.invalid_syntax.here: "<yellow><--[此处]</yellow>"
|
||||
@@ -214,6 +217,10 @@ warning.config.translation.unknown_locale: "<yellow>在文件 <arg:0> 发现问
|
||||
warning.config.template.duplicate: "<yellow>在文件 <arg:0> 发现问题 - 重复的模板 '<arg:1>' 请检查其他文件中是否存在相同配置</yellow>"
|
||||
warning.config.template.invalid: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 使用了无效的模板 '<arg:2>'</yellow>"
|
||||
warning.config.template.argument.self_increase_int.invalid_range: "<yellow>在文件 <arg:0> 发现问题 - 模板 '<arg:1>' 在 'self_increase_int' 参数中使用了一个起始值 '<arg:2>' 大于终止值 '<arg:3>'</yellow>"
|
||||
warning.config.template.argument.to_upper_case.invalid_locale: "<yellow>在文件 <arg:0> 发现问题 - 模板 '<arg:1>' 在 'to_upper_case' 参数中使用了无效的区域设置 '<arg:2>'</yellow>"
|
||||
warning.config.template.argument.to_upper_case.missing_value: "<yellow>在文件 <arg:0> 发现问题 - 模板 '<arg:1>' 缺少 'to_upper_case' 参数所需的 'value' 参数</yellow>"
|
||||
warning.config.template.argument.to_lower_case.invalid_locale: "<yellow>在文件 <arg:0> 发现问题 - 模板 '<arg:1>' 在 'to_lower_case' 参数中使用了无效的区域设置 '<arg:2>'</yellow>"
|
||||
warning.config.template.argument.to_lower_case.missing_value: "<yellow>在文件 <arg:0> 发现问题 - 模板 '<arg:1>' 缺少 'to_lower_case' 参数所需的 'value' 参数</yellow>"
|
||||
warning.config.template.argument.list.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - 模板 '<arg:1>' 的 'list' 参数需要列表类型 但输入参数类型为 '<arg:2>'</yellow>"
|
||||
warning.config.template.argument.missing_value: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少了 '<arg:2>' 必要的模板参数值. 请使用 arguments 选项进行配置或为此参数设定默认值</yellow>"
|
||||
warning.config.vanilla_loot.missing_type: "<yellow>在文件 <arg:0> 发现问题 - 原版战利品 '<arg:1>' 缺少必需的 'type' 参数</yellow>"
|
||||
@@ -226,6 +233,7 @@ warning.config.jukebox_song.duplicate: "<yellow>在文件 <arg:0> 发现问题 -
|
||||
warning.config.jukebox_song.missing_sound: "<yellow>在文件 <arg:0> 发现问题 - 唱片机歌曲 '<arg:1>' 缺少必需的 'sound' 参数</yellow>"
|
||||
warning.config.furniture.duplicate: "<yellow>在文件 <arg:0> 发现问题 - 重复的家具 '<arg:1>' 请检查其他文件中是否存在相同配置</yellow>"
|
||||
warning.config.furniture.missing_variants: "<yellow>在文件 <arg:0> 发现问题 - 家具 '<arg:1>' 缺少必需的 'variants' 参数</yellow>"
|
||||
warning.config.furniture.element.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - 家具 '<arg:1>' 使用了无效的元素类型 '<arg:2>'</yellow>"
|
||||
warning.config.furniture.element.item_display.missing_item: "<yellow>在文件 <arg:0> 发现问题 - 家具 '<arg:1>' 的 'item_display' 元素缺少必需的 'item' 参数</yellow>"
|
||||
warning.config.furniture.settings.unknown: "<yellow>在文件 <arg:0> 发现问题 - 家具 '<arg:1>' 使用了未知的设置类型 '<arg:2>'</yellow>"
|
||||
warning.config.furniture.hitbox.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - 家具 '<arg:1>' 使用了无效的碰撞箱类型 '<arg:2>'</yellow>"
|
||||
@@ -536,6 +544,7 @@ warning.config.function.transform_block.missing_block: "<yellow>在文件 <arg:0
|
||||
warning.config.function.cycle_block_property.missing_property: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'cycle_block_property' 函数所需的 'property' 参数</yellow>"
|
||||
warning.config.function.set_exp.missing_count: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'set_exp' 函数所需的 'count' 参数</yellow>"
|
||||
warning.config.function.set_level.missing_count: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'set_level' 函数所需的 'count' 参数</yellow>"
|
||||
warning.config.function.play_totem_animation.missing_item: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'play_totem_animation' 函数所需的 'item' 参数</yellow>"
|
||||
warning.config.function.clear_item.missing_id: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'clear_item' 函数所需的 'id' 参数</yellow>"
|
||||
warning.config.selector.missing_type: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少选择器必需的 'type' 参数</yellow>"
|
||||
warning.config.selector.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 使用了无效的选择器类型 '<arg:2>'</yellow>"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package net.momirealms.craftengine.core.plugin.gui.category;
|
||||
|
||||
import net.momirealms.craftengine.core.plugin.context.Condition;
|
||||
import net.momirealms.craftengine.core.plugin.context.Context;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -14,8 +17,9 @@ public class Category implements Comparable<Category> {
|
||||
private final List<String> members;
|
||||
private final int priority;
|
||||
private final boolean hidden;
|
||||
private final Condition<Context> condition;
|
||||
|
||||
public Category(Key id, String displayName, List<String> displayLore, Key icon, List<String> members, int priority, boolean hidden) {
|
||||
public Category(Key id, String displayName, List<String> displayLore, Key icon, List<String> members, int priority, boolean hidden, Condition<Context> condition) {
|
||||
this.id = id;
|
||||
this.displayName = displayName;
|
||||
this.members = new ArrayList<>(members);
|
||||
@@ -23,6 +27,7 @@ public class Category implements Comparable<Category> {
|
||||
this.priority = priority;
|
||||
this.displayLore = new ArrayList<>(displayLore);
|
||||
this.hidden = hidden;
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public void addMember(String member) {
|
||||
@@ -45,6 +50,11 @@ public class Category implements Comparable<Category> {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Condition<Context> condition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public List<String> displayLore() {
|
||||
return displayLore;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,12 @@ import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdSectionConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.context.Condition;
|
||||
import net.momirealms.craftengine.core.plugin.context.Context;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.condition.AllOfCondition;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventConditions;
|
||||
import net.momirealms.craftengine.core.plugin.gui.*;
|
||||
import net.momirealms.craftengine.core.plugin.gui.Ingredient;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
@@ -120,8 +124,11 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
List<String> members = MiscUtils.getAsStringList(section.getOrDefault("list", List.of()));
|
||||
Key icon = Key.of(section.getOrDefault("icon", ItemKeys.STONE).toString());
|
||||
int priority = ResourceConfigUtils.getAsInt(section.getOrDefault("priority", 0), "priority");
|
||||
Category category = new Category(id, name, MiscUtils.getAsStringList(section.getOrDefault("lore", List.of())), icon, new ArrayList<>(members), priority,
|
||||
ResourceConfigUtils.getAsBoolean(section.getOrDefault("hidden", false), "hidden"));
|
||||
List<String> lore = MiscUtils.getAsStringList(section.getOrDefault("lore", List.of()));
|
||||
boolean hidden = ResourceConfigUtils.getAsBoolean(section.getOrDefault("hidden", false), "hidden");
|
||||
List<Condition<Context>> conditionList = ResourceConfigUtils.parseConfigAsList(ResourceConfigUtils.get(section, "conditions", "condition"), EventConditions::fromMap);
|
||||
Condition<Context> conditions = conditionList.isEmpty() ? null : conditionList.size() == 1 ? conditionList.getFirst() : new AllOfCondition<>(conditionList);
|
||||
Category category = new Category(id, name, lore, icon, new ArrayList<>(members), priority, hidden, conditions);
|
||||
if (ItemBrowserManagerImpl.this.byId.containsKey(id)) {
|
||||
ItemBrowserManagerImpl.this.byId.get(id).merge(category);
|
||||
} else {
|
||||
@@ -162,6 +169,10 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
);
|
||||
|
||||
List<ItemWithAction> iconList = this.categoryOnMainPage.stream().map(it -> {
|
||||
Condition<Context> condition = it.condition();
|
||||
if (condition != null && !condition.test(PlayerOptionalContext.of(player))) {
|
||||
return null;
|
||||
}
|
||||
Item<?> item = this.plugin.itemManager().createWrappedItem(it.icon(), player);
|
||||
if (ItemUtils.isEmpty(item)) {
|
||||
this.plugin.logger().warn("Can't not find item " + it.icon() + " for category icon");
|
||||
@@ -251,6 +262,10 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
item = Objects.requireNonNull(this.plugin.itemManager().createWrappedItem(ItemKeys.BARRIER, player));
|
||||
item.customNameJson(AdventureHelper.componentToJson(Component.text(subCategoryId).color(NamedTextColor.RED).decoration(TextDecoration.ITALIC, false)));
|
||||
} else {
|
||||
Condition<Context> condition = subCategory.condition();
|
||||
if (condition != null && !condition.test(PlayerOptionalContext.of(player))) {
|
||||
return null;
|
||||
}
|
||||
item = this.plugin.itemManager().createWrappedItem(subCategory.icon(), player);
|
||||
if (ItemUtils.isEmpty(item)) {
|
||||
if (!subCategory.icon().equals(ItemKeys.AIR)) {
|
||||
@@ -322,7 +337,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
}
|
||||
});
|
||||
}
|
||||
}).toList();
|
||||
}).filter(Objects::nonNull).toList();
|
||||
|
||||
PagedGui.builder()
|
||||
.addIngredients(itemList)
|
||||
|
||||
Reference in New Issue
Block a user