mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
添加2个debug命令
This commit is contained in:
@@ -13,7 +13,6 @@ import org.bukkit.entity.Player;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class CheckItemExpansion extends PlaceholderExpansion {
|
public class CheckItemExpansion extends PlaceholderExpansion {
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Item<ItemStack>> s2c(Item<ItemStack> item, Player player) {
|
public Optional<Item<ItemStack>> s2c(Item<ItemStack> item, @Nullable Player player) {
|
||||||
if (item.isEmpty()) return Optional.empty();
|
if (item.isEmpty()) return Optional.empty();
|
||||||
return this.networkItemHandler.s2c(item, player);
|
return this.networkItemHandler.s2c(item, player);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import net.momirealms.sparrow.nbt.ListTag;
|
|||||||
import net.momirealms.sparrow.nbt.StringTag;
|
import net.momirealms.sparrow.nbt.StringTag;
|
||||||
import net.momirealms.sparrow.nbt.Tag;
|
import net.momirealms.sparrow.nbt.Tag;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -119,7 +120,7 @@ public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Item<ItemStack>> s2c(Item<ItemStack> wrapped, Player player) {
|
public Optional<Item<ItemStack>> s2c(Item<ItemStack> wrapped, @Nullable Player player) {
|
||||||
boolean forceReturn = false;
|
boolean forceReturn = false;
|
||||||
|
|
||||||
// 处理收纳袋
|
// 处理收纳袋
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import net.momirealms.sparrow.nbt.ListTag;
|
|||||||
import net.momirealms.sparrow.nbt.StringTag;
|
import net.momirealms.sparrow.nbt.StringTag;
|
||||||
import net.momirealms.sparrow.nbt.Tag;
|
import net.momirealms.sparrow.nbt.Tag;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -110,7 +111,7 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Item<ItemStack>> s2c(Item<ItemStack> wrapped, Player player) {
|
public Optional<Item<ItemStack>> s2c(Item<ItemStack> wrapped, @Nullable Player player) {
|
||||||
boolean forceReturn = false;
|
boolean forceReturn = false;
|
||||||
|
|
||||||
// 处理收纳袋
|
// 处理收纳袋
|
||||||
|
|||||||
@@ -64,8 +64,9 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
|
|||||||
new SendResourcePackCommand(this, plugin),
|
new SendResourcePackCommand(this, plugin),
|
||||||
new DebugSaveDefaultResourcesCommand(this, plugin),
|
new DebugSaveDefaultResourcesCommand(this, plugin),
|
||||||
new DebugCleanCacheCommand(this, plugin),
|
new DebugCleanCacheCommand(this, plugin),
|
||||||
new DebugGenerateInternalAssetsCommand(this, plugin)
|
new DebugGenerateInternalAssetsCommand(this, plugin),
|
||||||
// new OverrideGiveCommand(this, plugin)
|
new DebugCustomModelDataCommand(this, plugin),
|
||||||
|
new DebugImageCommand(this, plugin)
|
||||||
));
|
));
|
||||||
final LegacyPaperCommandManager<CommandSender> manager = (LegacyPaperCommandManager<CommandSender>) getCommandManager();
|
final LegacyPaperCommandManager<CommandSender> manager = (LegacyPaperCommandManager<CommandSender>) getCommandManager();
|
||||||
manager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true);
|
manager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true);
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package net.momirealms.craftengine.bukkit.plugin.command.feature;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
|
||||||
|
import net.momirealms.craftengine.bukkit.api.CraftEngineItems;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||||
|
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||||
|
import net.momirealms.craftengine.core.item.CustomItem;
|
||||||
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
|
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
|
||||||
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.incendo.cloud.Command;
|
||||||
|
import org.incendo.cloud.CommandManager;
|
||||||
|
import org.incendo.cloud.bukkit.parser.NamespacedKeyParser;
|
||||||
|
import org.incendo.cloud.context.CommandContext;
|
||||||
|
import org.incendo.cloud.context.CommandInput;
|
||||||
|
import org.incendo.cloud.suggestion.Suggestion;
|
||||||
|
import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class DebugCustomModelDataCommand extends BukkitCommandFeature<CommandSender> {
|
||||||
|
|
||||||
|
public DebugCustomModelDataCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
|
||||||
|
super(commandManager, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Command.Builder<? extends CommandSender> assembleCommand(CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
|
||||||
|
return builder
|
||||||
|
.optional("id", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() {
|
||||||
|
@Override
|
||||||
|
public @NonNull CompletableFuture<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext<Object> context, @NonNull CommandInput input) {
|
||||||
|
return CompletableFuture.completedFuture(plugin().itemManager().cachedCustomItemSuggestions());
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.handler(this::handleCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFeatureID() {
|
||||||
|
return "debug_custom_model_data";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleCommand(CommandContext<CommandSender> context) {
|
||||||
|
NamespacedKey namespacedKey = context.getOrDefault("id", null);
|
||||||
|
@Nullable BukkitServerPlayer player = context.sender() instanceof Player p ? BukkitAdaptors.adapt(p) : null;
|
||||||
|
|
||||||
|
if (namespacedKey != null) {
|
||||||
|
Key itemId = KeyUtils.namespacedKey2Key(namespacedKey);
|
||||||
|
CustomItem<ItemStack> customItem = CraftEngineItems.byId(itemId);
|
||||||
|
if (customItem == null) return;
|
||||||
|
Item<ItemStack> item = customItem.buildItem(player);
|
||||||
|
sendMessage(context, getCustomModelData(item, player));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player != null) {
|
||||||
|
Item<ItemStack> item = player.getItemInHand(InteractionHand.MAIN_HAND).copyWithCount(1);
|
||||||
|
sendMessage(context, getCustomModelData(item, player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getCustomModelData(Item<ItemStack> itemStack, BukkitServerPlayer player) {
|
||||||
|
return plugin().itemManager().s2c(itemStack, player)
|
||||||
|
.map(Item::customModelData)
|
||||||
|
.orElse(itemStack.customModelData())
|
||||||
|
.orElse(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessage(CommandContext<CommandSender> context, int customModelData) {
|
||||||
|
Component message = Component.text(customModelData)
|
||||||
|
.hoverEvent(Component.text("Copy", NamedTextColor.YELLOW))
|
||||||
|
.clickEvent(ClickEvent.suggestCommand(String.valueOf(customModelData)));
|
||||||
|
plugin().senderFactory().wrap(context.sender()).sendMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package net.momirealms.craftengine.bukkit.plugin.command.feature;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.TextComponent;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||||
|
import net.momirealms.craftengine.core.font.BitmapImage;
|
||||||
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
|
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
|
||||||
|
import net.momirealms.craftengine.core.util.FormatUtils;
|
||||||
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.incendo.cloud.Command;
|
||||||
|
import org.incendo.cloud.CommandManager;
|
||||||
|
import org.incendo.cloud.bukkit.parser.NamespacedKeyParser;
|
||||||
|
import org.incendo.cloud.context.CommandContext;
|
||||||
|
import org.incendo.cloud.context.CommandInput;
|
||||||
|
import org.incendo.cloud.parser.standard.IntegerParser;
|
||||||
|
import org.incendo.cloud.suggestion.Suggestion;
|
||||||
|
import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class DebugImageCommand extends BukkitCommandFeature<CommandSender> {
|
||||||
|
|
||||||
|
public DebugImageCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
|
||||||
|
super(commandManager, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Command.Builder<? extends CommandSender> assembleCommand(CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
|
||||||
|
return builder
|
||||||
|
.required("id", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() {
|
||||||
|
@Override
|
||||||
|
public @NonNull CompletableFuture<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext<Object> context, @NonNull CommandInput input) {
|
||||||
|
return CompletableFuture.completedFuture(plugin().fontManager().cachedImagesSuggestions());
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.optional("row", IntegerParser.integerParser(0))
|
||||||
|
.optional("column", IntegerParser.integerParser(0))
|
||||||
|
.handler(context -> {
|
||||||
|
Key imageId = KeyUtils.namespacedKey2Key(context.get("id"));
|
||||||
|
plugin().fontManager().bitmapImageByImageId(imageId).ifPresent(image -> {
|
||||||
|
int row = context.getOrDefault("row", 0);
|
||||||
|
int column = context.getOrDefault("column", 0);
|
||||||
|
String string = image.isValidCoordinate(row, column)
|
||||||
|
? imageId.asString() + ((row != 0 || column != 0) ? ":" + row + ":" + column : "") // 自动最小化
|
||||||
|
: imageId.asString() + ":" + (row = 0) + ":" + (column = 0); // 因为是无效的所以说要强调告诉获取的是00
|
||||||
|
Component component = Component.text()
|
||||||
|
.append(Component.text(string)
|
||||||
|
.hoverEvent(image.componentAt(row, column).color(NamedTextColor.WHITE))
|
||||||
|
.clickEvent(ClickEvent.suggestCommand(string)))
|
||||||
|
.append(getHelperInfo(image, row, column))
|
||||||
|
.build();
|
||||||
|
plugin().senderFactory().wrap(context.sender()).sendMessage(component);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFeatureID() {
|
||||||
|
return "debug_image";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextComponent.Builder getHelperInfo(BitmapImage image, int row, int column) {
|
||||||
|
String raw = new String(Character.toChars(image.codepointAt(row, column)));
|
||||||
|
String font = image.font().toString();
|
||||||
|
return Component.text()
|
||||||
|
.append(Component.text(" "))
|
||||||
|
.append(Component.text("[MM]")
|
||||||
|
.color(NamedTextColor.YELLOW)
|
||||||
|
.hoverEvent(Component.text("Copy", NamedTextColor.YELLOW))
|
||||||
|
.clickEvent(ClickEvent.suggestCommand(FormatUtils.miniMessageFont(raw, font))))
|
||||||
|
.append(Component.text(" "))
|
||||||
|
.append(Component.text("[MD]")
|
||||||
|
.color(NamedTextColor.YELLOW)
|
||||||
|
.hoverEvent(Component.text("Copy", NamedTextColor.YELLOW))
|
||||||
|
.clickEvent(ClickEvent.suggestCommand(FormatUtils.mineDownFont(raw, font))))
|
||||||
|
.append(Component.text(" "))
|
||||||
|
.append(Component.text("[RAW]")
|
||||||
|
.color(NamedTextColor.YELLOW)
|
||||||
|
.hoverEvent(Component.text("Copy", NamedTextColor.YELLOW))
|
||||||
|
.clickEvent(ClickEvent.suggestCommand(raw)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -237,6 +237,20 @@ debug_clean_cache:
|
|||||||
- /craftengine debug clean-cache
|
- /craftengine debug clean-cache
|
||||||
- /ce debug clean-cache
|
- /ce debug clean-cache
|
||||||
|
|
||||||
|
debug_custom_model_data:
|
||||||
|
enable: true
|
||||||
|
permission: ce.command.debug.custom_model_data
|
||||||
|
usage:
|
||||||
|
- /craftengine debug custom-model-data
|
||||||
|
- /ce debug custom-model-data
|
||||||
|
|
||||||
|
debug_image:
|
||||||
|
enable: true
|
||||||
|
permission: ce.command.debug.image
|
||||||
|
usage:
|
||||||
|
- /craftengine debug image
|
||||||
|
- /ce debug image
|
||||||
|
|
||||||
debug_generate_internal_assets:
|
debug_generate_internal_assets:
|
||||||
enable: false
|
enable: false
|
||||||
permission: ce.command.debug.generate_internal_assets
|
permission: ce.command.debug.generate_internal_assets
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import net.momirealms.craftengine.core.plugin.text.component.ComponentProvider;
|
|||||||
import net.momirealms.craftengine.core.util.*;
|
import net.momirealms.craftengine.core.util.*;
|
||||||
import org.ahocorasick.trie.Token;
|
import org.ahocorasick.trie.Token;
|
||||||
import org.ahocorasick.trie.Trie;
|
import org.ahocorasick.trie.Trie;
|
||||||
|
import org.incendo.cloud.suggestion.Suggestion;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
@@ -52,6 +53,8 @@ public abstract class AbstractFontManager implements FontManager {
|
|||||||
protected Map<String, Emoji> emojiMapper;
|
protected Map<String, Emoji> emojiMapper;
|
||||||
protected List<Emoji> emojiList;
|
protected List<Emoji> emojiList;
|
||||||
protected List<String> allEmojiSuggestions;
|
protected List<String> allEmojiSuggestions;
|
||||||
|
// Cached command suggestions
|
||||||
|
protected final List<Suggestion> cachedImagesSuggestions = new ArrayList<>();
|
||||||
|
|
||||||
public AbstractFontManager(CraftEngine plugin) {
|
public AbstractFontManager(CraftEngine plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@@ -95,6 +98,7 @@ public abstract class AbstractFontManager implements FontManager {
|
|||||||
public void unload() {
|
public void unload() {
|
||||||
this.fonts.clear();
|
this.fonts.clear();
|
||||||
this.images.clear();
|
this.images.clear();
|
||||||
|
this.cachedImagesSuggestions.clear();
|
||||||
this.illegalChars.clear();
|
this.illegalChars.clear();
|
||||||
this.emojis.clear();
|
this.emojis.clear();
|
||||||
this.networkTagTrie = null;
|
this.networkTagTrie = null;
|
||||||
@@ -415,6 +419,12 @@ public abstract class AbstractFontManager implements FontManager {
|
|||||||
return Optional.ofNullable(this.fonts.get(id));
|
return Optional.ofNullable(this.fonts.get(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Suggestion> cachedImagesSuggestions() {
|
||||||
|
return Collections.unmodifiableCollection(this.cachedImagesSuggestions);
|
||||||
|
}
|
||||||
|
|
||||||
private Font getOrCreateFont(Key key) {
|
private Font getOrCreateFont(Key key) {
|
||||||
return this.fonts.computeIfAbsent(key, Font::new);
|
return this.fonts.computeIfAbsent(key, Font::new);
|
||||||
}
|
}
|
||||||
@@ -712,6 +722,7 @@ public abstract class AbstractFontManager implements FontManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AbstractFontManager.this.images.put(id, bitmapImage);
|
AbstractFontManager.this.images.put(id, bitmapImage);
|
||||||
|
AbstractFontManager.this.cachedImagesSuggestions.add(Suggestion.suggestion(id.asString()));
|
||||||
|
|
||||||
}, () -> GsonHelper.get().toJson(section)));
|
}, () -> GsonHelper.get().toJson(section)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
|||||||
import net.momirealms.craftengine.core.plugin.text.component.ComponentProvider;
|
import net.momirealms.craftengine.core.plugin.text.component.ComponentProvider;
|
||||||
import net.momirealms.craftengine.core.util.*;
|
import net.momirealms.craftengine.core.util.*;
|
||||||
import net.momirealms.sparrow.nbt.Tag;
|
import net.momirealms.sparrow.nbt.Tag;
|
||||||
|
import org.incendo.cloud.suggestion.Suggestion;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -80,6 +81,8 @@ public interface FontManager extends Manageable {
|
|||||||
|
|
||||||
Optional<Font> fontById(Key font);
|
Optional<Font> fontById(Key font);
|
||||||
|
|
||||||
|
Collection<Suggestion> cachedImagesSuggestions();
|
||||||
|
|
||||||
int codepointByImageId(Key imageId, int x, int y);
|
int codepointByImageId(Key imageId, int x, int y);
|
||||||
|
|
||||||
default int codepointByImageId(Key imageId) {
|
default int codepointByImageId(Key imageId) {
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public interface ItemManager<T> extends Manageable, ModelGenerator {
|
|||||||
|
|
||||||
Optional<Item<T>> c2s(Item<T> item);
|
Optional<Item<T>> c2s(Item<T> item);
|
||||||
|
|
||||||
Optional<Item<T>> s2c(Item<T> item, Player player);
|
Optional<Item<T>> s2c(Item<T> item, @Nullable Player player);
|
||||||
|
|
||||||
UniqueIdItem<T> uniqueEmptyItem();
|
UniqueIdItem<T> uniqueEmptyItem();
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public interface NetworkItemHandler<T> {
|
|||||||
String NETWORK_OPERATION = "type";
|
String NETWORK_OPERATION = "type";
|
||||||
String NETWORK_VALUE = "value";
|
String NETWORK_VALUE = "value";
|
||||||
|
|
||||||
Optional<Item<T>> s2c(Item<T> itemStack, Player player);
|
Optional<Item<T>> s2c(Item<T> itemStack, @Nullable Player player);
|
||||||
|
|
||||||
Optional<Item<T>> c2s(Item<T> itemStack);
|
Optional<Item<T>> c2s(Item<T> itemStack);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
|
|
||||||
# Project settings
|
# Project settings
|
||||||
project_version=0.0.65.11
|
project_version=0.0.65.11
|
||||||
config_version=56
|
config_version=57
|
||||||
lang_version=39
|
lang_version=39
|
||||||
project_group=net.momirealms
|
project_group=net.momirealms
|
||||||
latest_supported_version=1.21.10
|
latest_supported_version=1.21.10
|
||||||
|
|||||||
Reference in New Issue
Block a user