9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-28 03:19:14 +00:00
- 修复部分网络通讯问题
- 第三方等级插件适配切换到levelerbridge库
- 修改(fa)we兼容
This commit is contained in:
jhqwqmc
2025-12-21 01:42:11 +08:00
parent 21689ef6c0
commit cb9d1dff76
26 changed files with 143 additions and 320 deletions

View File

@@ -65,6 +65,8 @@ dependencies {
compileOnly("ca.spottedleaf:concurrentutil:${rootProject.properties["concurrent_util_version"]}")
// ItemBridge
compileOnly("cn.gtemc:itembridge:${rootProject.properties["itembridge_version"]}")
// LevelerBridge
compileOnly("cn.gtemc:levelerbridge:${rootProject.properties["levelerbridge_version"]}")
}
java {
@@ -94,6 +96,7 @@ tasks {
relocate("net.momirealms.sparrow.nbt", "net.momirealms.craftengine.libraries.nbt")
relocate("net.momirealms.antigrieflib", "net.momirealms.craftengine.libraries.antigrieflib")
relocate("cn.gtemc.itembridge", "net.momirealms.craftengine.libraries.itembridge")
relocate("cn.gtemc.levelerbridge", "net.momirealms.craftengine.libraries.levelerbridge")
relocate("org.incendo", "net.momirealms.craftengine.libraries")
relocate("dev.dejvokep", "net.momirealms.craftengine.libraries")
relocate("org.bstats", "net.momirealms.craftengine.libraries.bstats")

View File

@@ -8,12 +8,8 @@ repositories {
maven("https://repo.infernalsuite.com/repository/maven-snapshots/") // slime world
maven("https://repo.momirealms.net/releases/")
maven("https://mvn.lumine.io/repository/maven-public/") // model engine mythic mobs
maven("https://nexus.phoenixdevt.fr/repository/maven-public/") // mmocore
maven("https://repo.viaversion.com") // via
maven("https://repo.skriptlang.org/releases/") // skript
maven("https://nexus.neetgames.com/repository/maven-releases/") // mcmmo
maven("https://repo.dmulloy2.net/repository/public/") // mcmmo required
maven("https://repo.auxilor.io/repository/maven-public/") // eco
maven("https://repo.hiusers.com/releases")
maven("https://jitpack.io")
maven("https://repo.codemc.io/repository/maven-public/") // quickshop
@@ -48,30 +44,14 @@ dependencies {
compileOnly("com.viaversion:viaversion-bukkit:5.5.1")
// Skript
compileOnly("com.github.SkriptLang:Skript:2.11.0")
// AuraSkills
compileOnly("dev.aurelium:auraskills-api-bukkit:2.2.4")
// FAWE
compileOnly(platform("com.intellectualsites.bom:bom-newest:1.52"))
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core")
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false }
// MythicMobs
compileOnly("io.lumine:Mythic-Dist:5.9.0")
// McMMO
compileOnly("com.gmail.nossr50.mcMMO:mcMMO:2.2.038")
// MMOCore
compileOnly("net.Indyuce:MMOCore-API:1.13.1-SNAPSHOT")
compileOnly("io.lumine:MythicLib-dist:1.7.1-SNAPSHOT")
// JobsReborn
compileOnly("com.github.Zrips:Jobs:v5.2.2.3")
// CustomNameplates
compileOnly("net.momirealms:custom-nameplates:3.0.33")
// eco
compileOnly("com.willfp:eco:6.70.1")
compileOnly("com.willfp:EcoJobs:3.56.1")
compileOnly("com.willfp:EcoSkills:3.46.1")
compileOnly("com.willfp:libreforge:4.58.1")
// AureliumSkills
compileOnly("com.github.Archy-X:AureliumSkills:Beta1.3.21")
// WorldGuard
compileOnly(files("${rootProject.rootDir}/libs/worldguard-bukkit-7.0.14-dist.jar"))
// QuickShop
@@ -82,6 +62,8 @@ dependencies {
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
// ItemBridge
compileOnly("cn.gtemc:itembridge:${rootProject.properties["itembridge_version"]}")
// LevelerBridge
compileOnly("cn.gtemc:levelerbridge:${rootProject.properties["levelerbridge_version"]}")
}
java {

View File

@@ -1,12 +1,11 @@
package net.momirealms.craftengine.bukkit.compatibility;
import cn.gtemc.levelerbridge.core.BukkitLevelerBridge;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.block.entity.renderer.element.BukkitBlockEntityElementConfigs;
import net.momirealms.craftengine.bukkit.compatibility.bedrock.FloodgateUtils;
import net.momirealms.craftengine.bukkit.compatibility.bedrock.GeyserUtils;
import net.momirealms.craftengine.bukkit.compatibility.legacy.slimeworld.LegacySlimeFormatStorageAdaptor;
import net.momirealms.craftengine.bukkit.compatibility.leveler.*;
import net.momirealms.craftengine.bukkit.compatibility.model.bettermodel.BetterModelBlockEntityElementConfig;
import net.momirealms.craftengine.bukkit.compatibility.model.bettermodel.BetterModelModel;
import net.momirealms.craftengine.bukkit.compatibility.model.modelengine.ModelEngineBlockEntityElementConfig;
@@ -31,7 +30,6 @@ import net.momirealms.craftengine.core.entity.furniture.ExternalModel;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.loot.LootConditions;
import net.momirealms.craftengine.core.plugin.compatibility.CompatibilityManager;
import net.momirealms.craftengine.core.plugin.compatibility.LevelerProvider;
import net.momirealms.craftengine.core.plugin.compatibility.ModelProvider;
import net.momirealms.craftengine.core.plugin.compatibility.TagResolverProvider;
import net.momirealms.craftengine.core.plugin.config.Config;
@@ -49,12 +47,12 @@ import org.bukkit.plugin.Plugin;
import java.util.*;
public class BukkitCompatibilityManager implements CompatibilityManager {
public class BukkitCompatibilityManager implements CompatibilityManager<org.bukkit.entity.Player> {
private final BukkitCraftEngine plugin;
private final Map<String, ModelProvider> modelProviders;
private final Map<String, LevelerProvider> levelerProviders;
private final Map<String, TagResolverProvider> tagResolverProviders;
private TagResolverProvider[] tagResolverProviderArray = null;
private BukkitLevelerBridge levelerBridge;
private boolean hasPlaceholderAPI;
private boolean hasGeyser;
private boolean hasFloodgate;
@@ -65,7 +63,6 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
"ModelEngine", ModelEngineModel::new,
"BetterModel", BetterModelModel::new
));
this.levelerProviders = new HashMap<>();
this.tagResolverProviders = new HashMap<>();
}
@@ -136,33 +133,6 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
SkriptHook.register();
logHook("Skript");
}
if (this.isPluginEnabled("AuraSkills")) {
this.registerLevelerProvider("AuraSkills", new AuraSkillsLevelerProvider());
logHook("AuraSkills");
}
if (this.isPluginEnabled("AureliumSkills")) {
this.registerLevelerProvider("AureliumSkills", new AureliumSkillsLevelerProvider());
}
if (this.isPluginEnabled("McMMO")) {
this.registerLevelerProvider("mcMMO", new McMMOLevelerProvider());
logHook("McMMO");
}
if (this.isPluginEnabled("MMOCore")) {
this.registerLevelerProvider("MMOCore", new MMOCoreLevelerProvider());
logHook("MMOCore");
}
if (this.isPluginEnabled("Jobs")) {
registerLevelerProvider("Jobs", new JobsRebornLevelerProvider());
logHook("Jobs");
}
if (this.isPluginEnabled("EcoSkills")) {
registerLevelerProvider("EcoSkills", new EcoSkillsLevelerProvider());
logHook("EcoSkills");
}
if (this.isPluginEnabled("EcoJobs")) {
registerLevelerProvider("EcoJobs", new EcoJobsLevelerProvider());
logHook("EcoJobs");
}
if (this.isPluginEnabled("MythicMobs")) {
new MythicItemDropListener(this.plugin);
logHook("MythicMobs");
@@ -178,11 +148,6 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
MythicSkillHelper.execute(skill, power, player);
}
@Override
public void registerLevelerProvider(String plugin, LevelerProvider provider) {
this.levelerProviders.put(plugin, provider);
}
@Override
public void registerTagResolverProvider(TagResolverProvider provider) {
this.tagResolverProviders.put(provider.name(), provider);
@@ -194,20 +159,6 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
this.plugin.logger().info(TranslationManager.instance().translateLog("info.compatibility", plugin));
}
@Override
public void addLevelerExp(Player player, String plugin, String target, double value) {
Optional.ofNullable(this.levelerProviders.get(plugin)).ifPresentOrElse(leveler -> leveler.addExp(player, target, value),
() -> this.plugin.logger().warn("[Compatibility] '" + plugin + "' leveler provider not found"));
}
@Override
public int getLevel(Player player, String plugin, String target) {
return Optional.ofNullable(this.levelerProviders.get(plugin)).map(leveler -> leveler.getLevel(player, target)).orElseGet(() -> {
this.plugin.logger().warn("[Compatibility] '" + plugin + "' leveler provider not found");
return 0;
});
}
@Override
public ExternalModel createModel(String plugin, String id) {
return this.modelProviders.get(plugin).createModel(id);
@@ -254,11 +205,11 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
}
}
@SuppressWarnings({"deprecation", "all"})
@SuppressWarnings({"deprecation", "DataFlowIssue"})
private void initFastAsyncWorldEditHook() {
Plugin fastAsyncWorldEdit = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit");
String version = VersionHelper.isPaper() ? fastAsyncWorldEdit.getPluginMeta().getVersion() : fastAsyncWorldEdit.getDescription().getVersion();
if (!this.fastAsyncWorldEditVersionCheck(version)) {
if (!WorldEditBlockRegister.checkFAWECompatible(version)) {
if (VersionHelper.isOrAbove1_20_3()) {
this.plugin.logger().severe("");
if (Locale.getDefault() == Locale.SIMPLIFIED_CHINESE) {
@@ -271,22 +222,14 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
this.plugin.logger().severe("");
}
}
new WorldEditBlockRegister(BukkitBlockManager.instance(), true);
}
private boolean fastAsyncWorldEditVersionCheck(String version) {
String cleanVersion = version.split("-")[0];
String[] parts = cleanVersion.split("\\.");
int first = Integer.parseInt(parts[0]);
int second = Integer.parseInt(parts[1]);
return first >= 2 && second >= 13;
WorldEditBlockRegister.init(true);
}
private void initWorldEditHook() {
WorldEditBlockRegister weBlockRegister = new WorldEditBlockRegister(BukkitBlockManager.instance(), false);
WorldEditBlockRegister.init(false);
try {
for (int i = 0; i < Config.serverSideBlocks(); i++) {
weBlockRegister.register(BlockManager.createCustomBlockKey(i));
WorldEditBlockRegister.register(BlockManager.createCustomBlockKey(i));
}
} catch (Exception e) {
this.plugin.logger().warn("Failed to initialize world edit hook", e);
@@ -351,4 +294,12 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
}
return uuid.version() == 0;
}
@Override
public BukkitLevelerBridge levelerBridge() {
if (this.levelerBridge == null) {
this.levelerBridge = BukkitLevelerBridge.builder().build();
}
return this.levelerBridge;
}
}

View File

@@ -1,19 +0,0 @@
package net.momirealms.craftengine.bukkit.compatibility.leveler;
import dev.aurelium.auraskills.api.AuraSkillsApi;
import dev.aurelium.auraskills.api.registry.NamespacedId;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.compatibility.LevelerProvider;
public class AuraSkillsLevelerProvider implements LevelerProvider {
@Override
public void addExp(Player player, String target, double amount) {
AuraSkillsApi.get().getUser(player.uuid()).addSkillXp(AuraSkillsApi.get().getGlobalRegistry().getSkill(NamespacedId.fromDefault(target)), amount);
}
@Override
public int getLevel(Player player, String target) {
return AuraSkillsApi.get().getUser(player.uuid()).getSkillLevel(AuraSkillsApi.get().getGlobalRegistry().getSkill(NamespacedId.fromDefault(target)));
}
}

View File

@@ -1,27 +0,0 @@
package net.momirealms.craftengine.bukkit.compatibility.leveler;
import com.archyx.aureliumskills.api.AureliumAPI;
import com.archyx.aureliumskills.leveler.Leveler;
import com.archyx.aureliumskills.skills.SkillRegistry;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.compatibility.LevelerProvider;
public class AureliumSkillsLevelerProvider implements LevelerProvider {
private final Leveler leveler;
private final SkillRegistry skillRegistry;
public AureliumSkillsLevelerProvider() {
this.leveler = AureliumAPI.getPlugin().getLeveler();
this.skillRegistry = AureliumAPI.getPlugin().getSkillRegistry();
}
@Override
public void addExp(Player player, String target, double amount) {
this.leveler.addXp(((org.bukkit.entity.Player) player.platformPlayer()), this.skillRegistry.getSkill(target), amount);
}
@Override
public int getLevel(Player player, String target) {
return AureliumAPI.getSkillLevel(((org.bukkit.entity.Player) player.platformPlayer()), this.skillRegistry.getSkill(target));
}
}

View File

@@ -1,28 +0,0 @@
package net.momirealms.craftengine.bukkit.compatibility.leveler;
import com.willfp.ecojobs.api.EcoJobsAPI;
import com.willfp.ecojobs.jobs.Job;
import com.willfp.ecojobs.jobs.Jobs;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.compatibility.LevelerProvider;
public class EcoJobsLevelerProvider implements LevelerProvider {
@Override
public void addExp(Player player, String target, double amount) {
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.platformPlayer();
for (Job job : EcoJobsAPI.getActiveJobs(bukkitPlayer)) {
if (job.getId().equals(target)) {
EcoJobsAPI.giveJobExperience(bukkitPlayer, job, amount);
return;
}
}
}
@Override
public int getLevel(Player player, String target) {
Job job = Jobs.getByID(target);
if (job == null) return 0;
return EcoJobsAPI.getJobLevel(((org.bukkit.entity.Player) player.platformPlayer()), job);
}
}

View File

@@ -1,21 +0,0 @@
package net.momirealms.craftengine.bukkit.compatibility.leveler;
import com.willfp.ecoskills.api.EcoSkillsAPI;
import com.willfp.ecoskills.skills.Skills;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.compatibility.LevelerProvider;
import java.util.Objects;
public class EcoSkillsLevelerProvider implements LevelerProvider {
@Override
public void addExp(Player player, String target, double amount) {
EcoSkillsAPI.gainSkillXP(((org.bukkit.entity.Player) player.platformPlayer()), Objects.requireNonNull(Skills.INSTANCE.getByID(target)), amount);
}
@Override
public int getLevel(Player player, String target) {
return EcoSkillsAPI.getSkillLevel(((org.bukkit.entity.Player) player.platformPlayer()), Objects.requireNonNull(Skills.INSTANCE.getByID(target)));
}
}

View File

@@ -1,30 +0,0 @@
package net.momirealms.craftengine.bukkit.compatibility.leveler;
import com.gamingmesh.jobs.Jobs;
import com.gamingmesh.jobs.container.Job;
import com.gamingmesh.jobs.container.JobProgression;
import com.gamingmesh.jobs.container.JobsPlayer;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.compatibility.LevelerProvider;
public class JobsRebornLevelerProvider implements LevelerProvider {
@Override
public void addExp(Player player, String target, double amount) {
JobsPlayer jobsPlayer = Jobs.getPlayerManager().getJobsPlayer(player.uuid());
Job job = Jobs.getJob(target);
if (jobsPlayer != null && jobsPlayer.isInJob(job)) {
Jobs.getPlayerManager().addExperience(jobsPlayer, job, amount);
}
}
@Override
public int getLevel(Player player, String target) {
JobsPlayer jobsPlayer = Jobs.getPlayerManager().getJobsPlayer(player.uuid());
if (jobsPlayer != null) {
JobProgression jobProgression = jobsPlayer.getJobProgression(Jobs.getJob(target));
return jobProgression.getLevel();
}
return 0;
}
}

View File

@@ -1,20 +0,0 @@
package net.momirealms.craftengine.bukkit.compatibility.leveler;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.EXPSource;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.compatibility.LevelerProvider;
public class MMOCoreLevelerProvider implements LevelerProvider {
@Override
public void addExp(Player player, String target, double amount) {
MMOCore.plugin.professionManager.get(target).giveExperience(PlayerData.get(player.uuid()), amount, null , EXPSource.OTHER);
}
@Override
public int getLevel(Player player, String target) {
return PlayerData.get(player.uuid()).getCollectionSkills().getLevel(MMOCore.plugin.professionManager.get(target));
}
}

View File

@@ -1,19 +0,0 @@
package net.momirealms.craftengine.bukkit.compatibility.leveler;
import com.gmail.nossr50.api.ExperienceAPI;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.compatibility.LevelerProvider;
public class McMMOLevelerProvider implements LevelerProvider {
@Override
public void addExp(Player player, String target, double amount) {
ExperienceAPI.addRawXP((org.bukkit.entity.Player) player.platformPlayer(), target, (float) amount, "UNKNOWN");
}
@Override
public int getLevel(Player player, String target) {
return ExperienceAPI.getLevel((org.bukkit.entity.Player) player.platformPlayer(), PrimarySkillType.valueOf(target));
}
}

View File

@@ -8,7 +8,7 @@ import com.sk89q.worldedit.util.concurrency.LazyReference;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import net.momirealms.craftengine.core.block.AbstractBlockManager;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.parser.BlockStateParser;
import net.momirealms.craftengine.core.util.Key;
@@ -20,39 +20,55 @@ import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
public class WorldEditBlockRegister {
private final Field field$BlockType$blockMaterial;
private final AbstractBlockManager manager;
private final boolean isFAWE;
public final class WorldEditBlockRegister {
private static final Field field$BlockType$blockMaterial = ReflectionUtils.getDeclaredField(BlockType.class, "blockMaterial");
private static boolean init = false;
public WorldEditBlockRegister(AbstractBlockManager manager, boolean isFAWE) {
this.field$BlockType$blockMaterial = ReflectionUtils.getDeclaredField(BlockType.class, "blockMaterial");
this.manager = manager;
this.isFAWE = isFAWE;
CEBlockParser blockParser = new CEBlockParser(WorldEdit.getInstance());
WorldEdit.getInstance().getBlockFactory().register(blockParser);
public static void init(boolean isFAWE) {
if (init) {
throw new IllegalStateException("WorldEditBlockRegister has already been initialized");
}
init = true;
WorldEdit.getInstance().getBlockFactory().register(new CEBlockParser(isFAWE));
if (isFAWE) {
FastAsyncWorldEditDelegate.init();
}
}
@SuppressWarnings("deprecation")
public void register(Key id) throws ReflectiveOperationException {
BlockType blockType = new BlockType(id.toString(), blockState -> blockState);
this.field$BlockType$blockMaterial.set(blockType, LazyReference.from(() -> new BukkitBlockRegistry.BukkitBlockMaterial(null, Material.STONE)));
BlockType.REGISTRY.register(id.toString(), blockType);
public static boolean checkFAWECompatible(String version) {
BlockType blockType = BlockType.REGISTRY.get("craftengine:custom_0");
if (blockType != null) { // 通过其他办法兼容直接返回成功
return true;
}
String cleanVersion = version.split("-")[0];
String[] parts = cleanVersion.split("\\.");
int first = Integer.parseInt(parts[0]);
int second = Integer.parseInt(parts[1]);
return first >= 2 && second >= 13;
}
private final class CEBlockParser extends InputParser<BaseBlock> {
@SuppressWarnings("deprecation")
public static void register(Key id) throws ReflectiveOperationException {
String string = id.asString();
BlockType blockType = new BlockType(string, blockState -> blockState);
field$BlockType$blockMaterial.set(blockType, LazyReference.from(() -> new BukkitBlockRegistry.BukkitBlockMaterial(null, Material.STONE)));
if (BlockType.REGISTRY.get(string) != null) { // already registered
return;
}
BlockType.REGISTRY.register(string, blockType);
}
private CEBlockParser(WorldEdit worldEdit) {
super(worldEdit);
private static final class CEBlockParser extends InputParser<BaseBlock> {
private final boolean isFAWE;
private CEBlockParser(boolean isFAWE) {
super(WorldEdit.getInstance());
this.isFAWE = isFAWE;
}
@Override
@SuppressWarnings("deprecation")
public Stream<String> getSuggestions(String input) {
Set<String> namespacesInUse = manager.namespacesInUse();
public Stream<String> getSuggestions(String input, ParserContext context) {
Set<String> namespacesInUse = BukkitBlockManager.instance().namespacesInUse();
if (input.isEmpty() || input.equals(":")) {
return namespacesInUse.stream().map(namespace -> namespace + ":");
@@ -75,15 +91,15 @@ public class WorldEditBlockRegister {
@Override
public BaseBlock parseFromInput(String input, ParserContext context) {
if (isFAWE) {
if (this.isFAWE) {
int index = input.indexOf("[");
if (input.charAt(index+1) == ']') return null;
if (input.charAt(index + 1) == ']') return null;
}
int colonIndex = input.indexOf(':');
if (colonIndex == -1) return null;
Set<String> namespacesInUse = manager.namespacesInUse();
Set<String> namespacesInUse = BukkitBlockManager.instance().namespacesInUse();
String namespace = input.substring(0, colonIndex);
if (!namespacesInUse.contains(namespace)) return null;

View File

@@ -29,6 +29,7 @@ dependencies {
implementation("net.momirealms:antigrieflib:${rootProject.properties["anti_grief_version"]}")
implementation("net.momirealms:craft-engine-nms-helper:${rootProject.properties["nms_helper_version"]}")
implementation("cn.gtemc:itembridge:${rootProject.properties["itembridge_version"]}")
implementation("cn.gtemc:levelerbridge:${rootProject.properties["levelerbridge_version"]}")
}
java {
@@ -69,6 +70,7 @@ tasks {
relocate("net.momirealms.sparrow.nbt", "net.momirealms.craftengine.libraries.nbt")
relocate("net.momirealms.antigrieflib", "net.momirealms.craftengine.libraries.antigrieflib")
relocate("cn.gtemc.itembridge", "net.momirealms.craftengine.libraries.itembridge")
relocate("cn.gtemc.levelerbridge", "net.momirealms.craftengine.libraries.levelerbridge")
relocate("org.incendo", "net.momirealms.craftengine.libraries")
relocate("dev.dejvokep", "net.momirealms.craftengine.libraries")
relocate("org.bstats", "net.momirealms.craftengine.libraries.bstats")

View File

@@ -33,6 +33,7 @@ dependencies {
implementation("net.momirealms:antigrieflib:${rootProject.properties["anti_grief_version"]}")
implementation("net.momirealms:craft-engine-nms-helper-mojmap:${rootProject.properties["nms_helper_version"]}")
implementation("cn.gtemc:itembridge:${rootProject.properties["itembridge_version"]}")
implementation("cn.gtemc:levelerbridge:${rootProject.properties["levelerbridge_version"]}")
}
java {
@@ -177,6 +178,7 @@ tasks {
relocate("net.momirealms.sparrow.nbt", "net.momirealms.craftengine.libraries.nbt")
relocate("net.momirealms.antigrieflib", "net.momirealms.craftengine.libraries.antigrieflib")
relocate("cn.gtemc.itembridge", "net.momirealms.craftengine.libraries.itembridge")
relocate("cn.gtemc.levelerbridge", "net.momirealms.craftengine.libraries.levelerbridge")
relocate("org.incendo", "net.momirealms.craftengine.libraries")
relocate("dev.dejvokep", "net.momirealms.craftengine.libraries")
relocate("org.bstats", "net.momirealms.craftengine.libraries.bstats")

View File

@@ -48,6 +48,7 @@ import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
@@ -92,7 +93,7 @@ public class BukkitCraftEngine extends CraftEngine {
Class<?> compatibilityClass = ReflectionUtils.getClazz(COMPATIBILITY_CLASS);
if (compatibilityClass != null) {
try {
super.compatibilityManager = (CompatibilityManager) Objects.requireNonNull(ReflectionUtils.getConstructor(compatibilityClass, 0)).newInstance(this);
super.compatibilityManager = (CompatibilityManager<Player>) Objects.requireNonNull(ReflectionUtils.getConstructor(compatibilityClass, 0)).newInstance(this);
} catch (ReflectiveOperationException e) {
logger().warn("Compatibility class could not be instantiated: " + compatibilityClass.getName());
}
@@ -346,6 +347,11 @@ public class BukkitCraftEngine extends CraftEngine {
return (BukkitFurnitureManager) furnitureManager;
}
@Override
public CompatibilityManager<Player> compatibilityManager() {
return (CompatibilityManager<Player>) compatibilityManager;
}
@Override
public SenderFactory<CraftEngine, CommandSender> senderFactory() {
return (SenderFactory<CraftEngine, CommandSender>) senderFactory;

View File

@@ -276,18 +276,18 @@ public class BukkitNetworkManager implements NetworkManager, Listener {
if (id == -1) return;
ByteBufferPacketListenerHolder[] listeners = switch (direction) {
case SERVERBOUND -> switch (state) {
case HANDSHAKING -> this.c2sHandshakingPacketListeners;
case STATUS -> this.c2sStatusPacketListeners;
case LOGIN -> this.c2sLoginPacketListeners;
case PLAY -> this.c2sPlayPacketListeners;
case CONFIGURATION -> this.c2sConfigurationPacketListeners;
case HANDSHAKING -> c2sHandshakingPacketListeners;
case STATUS -> c2sStatusPacketListeners;
case LOGIN -> c2sLoginPacketListeners;
case PLAY -> c2sPlayPacketListeners;
case CONFIGURATION -> c2sConfigurationPacketListeners;
};
case CLIENTBOUND -> switch (state) {
case HANDSHAKING -> this.s2cHandshakingPacketListeners;
case STATUS -> this.s2cStatusPacketListeners;
case LOGIN -> this.s2cLoginPacketListeners;
case PLAY -> this.s2cPlayPacketListeners;
case CONFIGURATION -> this.s2cConfigurationPacketListeners;
case HANDSHAKING -> s2cHandshakingPacketListeners;
case STATUS -> s2cStatusPacketListeners;
case LOGIN -> s2cLoginPacketListeners;
case PLAY -> s2cPlayPacketListeners;
case CONFIGURATION -> s2cConfigurationPacketListeners;
};
};
if (id < 0 || id >= listeners.length) {
@@ -1035,7 +1035,11 @@ public class BukkitNetworkManager implements NetworkManager, Listener {
protected void handleS2CByteBufPacket(NetWorkUser user, ByteBufPacketEvent event) {
int packetID = event.packetID();
ByteBufferPacketListenerHolder holder = s2cPacketListeners[user.encoderState().ordinal()][packetID];
ByteBufferPacketListenerHolder[] listener = s2cPacketListeners[user.encoderState().ordinal()];
if (packetID >= listener.length) { // fixme 为什么会这样
return;
}
ByteBufferPacketListenerHolder holder = listener[packetID];
if (holder != null) {
try {
holder.listener().onPacketSend(user, event);
@@ -1047,7 +1051,11 @@ public class BukkitNetworkManager implements NetworkManager, Listener {
protected void handleC2SByteBufPacket(NetWorkUser user, ByteBufPacketEvent event) {
int packetID = event.packetID();
ByteBufferPacketListenerHolder holder = c2sPacketListeners[user.decoderState().ordinal()][packetID];
ByteBufferPacketListenerHolder[] listener = c2sPacketListeners[user.decoderState().ordinal()];
if (packetID >= listener.length) { // fixme 为什么会这样
return;
}
ByteBufferPacketListenerHolder holder = listener[packetID];
if (holder != null) {
try {
holder.listener().onPacketReceive(user, event);
@@ -2107,7 +2115,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener {
}
}
public static class StartConfigurationListener implements NMSPacketListener {
public static class StartConfigurationListener implements NMSPacketListener {
@Override
public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) {

View File

@@ -22,23 +22,20 @@ public record DiscardedPayload(Key channel, Object rawPayload) implements Payloa
}
}
public byte[] getData() {
public ByteBuf getData() {
try {
if (useNewMethod) {
return (byte[]) NetworkReflections.method$DiscardedPayload$dataByteArray.invoke(this.rawPayload());
return Unpooled.wrappedBuffer((byte[]) NetworkReflections.method$DiscardedPayload$dataByteArray.invoke(this.rawPayload()));
} else {
ByteBuf buf = (ByteBuf) NetworkReflections.method$DiscardedPayload$data.invoke(this.rawPayload());
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
return data;
return (ByteBuf) NetworkReflections.method$DiscardedPayload$data.invoke(this.rawPayload());
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to get data from DiscardedPayload", e);
return new byte[0];
return Unpooled.EMPTY_BUFFER;
}
}
public FriendlyByteBuf toBuffer() {
return new FriendlyByteBuf(Unpooled.wrappedBuffer(this.getData()));
return new FriendlyByteBuf(this.getData());
}
}

View File

@@ -18,7 +18,6 @@ import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import net.momirealms.craftengine.core.util.ResourceKey;
public class PayloadHelper {
public static final byte[] JADE_RESPONSE = new byte[]{0, 0, 0, 0};
public static void registerDataTypes() {
registerDataType(ClientCustomBlockPacket.TYPE, ClientCustomBlockPacket.CODEC);

View File

@@ -1,28 +1,42 @@
package net.momirealms.craftengine.bukkit.plugin.network.payload;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import net.momirealms.craftengine.core.util.Key;
public record UnknownPayload(Key channel, ByteBuf rawPayload) implements Payload{
public record UnknownPayload(Key channel, Object rawPayload) implements Payload {
public static final boolean isByteArray = NetworkReflections.field$ServerboundCustomPayloadPacket$UnknownPayload$data == null;
public static UnknownPayload from(Object payload) {
try {
Object id = NetworkReflections.field$ServerboundCustomPayloadPacket$UnknownPayload$id.get(payload);
ByteBuf data = (ByteBuf) NetworkReflections.field$ServerboundCustomPayloadPacket$UnknownPayload$data.get(payload);
Key channel = KeyUtils.resourceLocationToKey(id);
return new UnknownPayload(channel, data);
return new UnknownPayload(channel, payload);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to create UnknownPayload", e);
return null;
}
}
public ByteBuf getData() {
try {
if (isByteArray) {
return Unpooled.wrappedBuffer((byte[]) NetworkReflections.field$ServerboundCustomPayloadPacket$UnknownPayload$dataByteArray.get(this.rawPayload()));
} else {
return (ByteBuf) NetworkReflections.field$ServerboundCustomPayloadPacket$UnknownPayload$data.get(this.rawPayload());
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to get data from UnknownPayload", e);
return Unpooled.EMPTY_BUFFER;
}
}
@Override
public FriendlyByteBuf toBuffer() {
return new FriendlyByteBuf(rawPayload);
return new FriendlyByteBuf(this.getData());
}
}

View File

@@ -1662,6 +1662,11 @@ public final class NetworkReflections {
.map(it -> ReflectionUtils.getDeclaredField(it, ByteBuf.class, 0))
.orElse(null);
// 1.20.2~1.20.4 可能打了 https://github.com/PaperMC/Paper/commit/9b1798d.patch 补丁
public static final Field field$ServerboundCustomPayloadPacket$UnknownPayload$dataByteArray = Optional.ofNullable(clazz$ServerboundCustomPayloadPacket$UnknownPayload)
.map(it -> ReflectionUtils.getDeclaredField(it, byte[].class, 0))
.orElse(null);
// 1.20.2~1.20.4
public static final Constructor<?> constructor$ServerboundCustomPayloadPacket$UnknownPayload = Optional.ofNullable(clazz$ServerboundCustomPayloadPacket$UnknownPayload)
.map(it -> ReflectionUtils.getConstructor(it, CoreReflections.clazz$ResourceLocation, ByteBuf.class))

View File

@@ -15,6 +15,7 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.gui.CraftEngineGUIHolder;
import net.momirealms.craftengine.bukkit.plugin.network.payload.DiscardedPayload;
import net.momirealms.craftengine.bukkit.plugin.network.payload.UnknownPayload;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MAttributeHolders;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MMobEffects;
@@ -476,12 +477,10 @@ public class BukkitServerPlayer extends Player {
Object responsePacket;
if (VersionHelper.isOrAbove1_20_2()) {
Object dataPayload;
if (!VersionHelper.isOrAbove1_20_5()) {
dataPayload = NetworkReflections.constructor$ServerboundCustomPayloadPacket$UnknownPayload.newInstance(channelResourceLocation, Unpooled.wrappedBuffer(data));
} else if (DiscardedPayload.useNewMethod) {
dataPayload = NetworkReflections.constructor$DiscardedPayload.newInstance(channelResourceLocation, data);
if (VersionHelper.isOrAbove1_20_5()) {
dataPayload = NetworkReflections.constructor$DiscardedPayload.newInstance(channelResourceLocation, DiscardedPayload.useNewMethod ? data : Unpooled.wrappedBuffer(data));
} else {
dataPayload = NetworkReflections.constructor$DiscardedPayload.newInstance(channelResourceLocation, Unpooled.wrappedBuffer(data));
dataPayload = NetworkReflections.constructor$ServerboundCustomPayloadPacket$UnknownPayload.newInstance(channelResourceLocation, UnknownPayload.isByteArray ? data : Unpooled.wrappedBuffer(data));
}
responsePacket = NetworkReflections.constructor$ClientboundCustomPayloadPacket.newInstance(dataPayload);
} else {

View File

@@ -74,6 +74,8 @@ dependencies {
compileOnly("com.bucket4j:bucket4j_jdk17-core:${rootProject.properties["bucket4j_version"]}")
// ItemBridge
compileOnly("cn.gtemc:itembridge:${rootProject.properties["itembridge_version"]}")
// LevelerBridge
compileOnly("cn.gtemc:levelerbridge:${rootProject.properties["levelerbridge_version"]}")
}
java {
@@ -114,6 +116,7 @@ tasks {
relocate("io.netty.handler.codec.http2", "net.momirealms.craftengine.libraries.netty.handler.codec.http2")
relocate("io.github.bucket4j", "net.momirealms.craftengine.libraries.bucket4j") // bucket4j
relocate("cn.gtemc.itembridge", "net.momirealms.craftengine.libraries.itembridge")
relocate("cn.gtemc.levelerbridge", "net.momirealms.craftengine.libraries.levelerbridge")
}
}

View File

@@ -88,7 +88,7 @@ public abstract class CraftEngine implements Plugin {
protected SoundManager soundManager;
protected VanillaLootManager vanillaLootManager;
protected AdvancementManager advancementManager;
protected CompatibilityManager compatibilityManager;
protected CompatibilityManager<?> compatibilityManager;
protected GlobalVariableManager globalVariableManager;
protected ProjectileManager projectileManager;
protected SeatManager seatManager;
@@ -647,9 +647,10 @@ public abstract class CraftEngine implements Plugin {
return vanillaLootManager;
}
@SuppressWarnings("unchecked")
@Override
public CompatibilityManager compatibilityManager() {
return compatibilityManager;
public <T> CompatibilityManager<T> compatibilityManager() {
return (CompatibilityManager<T>) compatibilityManager;
}
@Override

View File

@@ -94,7 +94,7 @@ public interface Plugin {
VanillaLootManager vanillaLootManager();
CompatibilityManager compatibilityManager();
<T> CompatibilityManager<T> compatibilityManager();
GlobalVariableManager globalVariableManager();

View File

@@ -1,12 +1,13 @@
package net.momirealms.craftengine.core.plugin.compatibility;
import cn.gtemc.levelerbridge.api.LevelerBridge;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.momirealms.craftengine.core.entity.furniture.ExternalModel;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
public interface CompatibilityManager {
public interface CompatibilityManager<P> {
void onLoad();
@@ -14,14 +15,8 @@ public interface CompatibilityManager {
void onDelayedEnable();
void registerLevelerProvider(String plugin, LevelerProvider provider);
void registerTagResolverProvider(TagResolverProvider provider);
void addLevelerExp(Player player, String plugin, String target, double value);
int getLevel(Player player, String plugin, String target);
ExternalModel createModel(String plugin, String id);
int interactionToBaseEntity(int id);
@@ -43,4 +38,6 @@ public interface CompatibilityManager {
TagResolver[] createExternalTagResolvers(Context context);
boolean isBedrockPlayer(Player player);
LevelerBridge<P> levelerBridge();
}

View File

@@ -12,6 +12,7 @@ import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class LevelerExpFunction<CTX extends Context> extends AbstractConditionalFunction<CTX> {
@@ -32,12 +33,12 @@ public class LevelerExpFunction<CTX extends Context> extends AbstractConditional
public void runInternal(CTX ctx) {
if (this.selector == null) {
ctx.getOptionalParameter(DirectContextParameters.PLAYER).ifPresent(it -> {
CraftEngine.instance().compatibilityManager().addLevelerExp(it, this.plugin, this.leveler, this.count.getDouble(ctx));
CraftEngine.instance().compatibilityManager().levelerBridge().addExperience(this.plugin, it.platformPlayer(), this.leveler, this.count.getDouble(ctx));
});
} else {
for (Player target : this.selector.get(ctx)) {
RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target));
CraftEngine.instance().compatibilityManager().addLevelerExp(target, this.plugin, this.leveler, this.count.getDouble(relationalContext));
CraftEngine.instance().compatibilityManager().levelerBridge().addExperience(this.plugin, target.platformPlayer(), this.leveler, this.count.getDouble(relationalContext));
}
}
}
@@ -56,7 +57,7 @@ public class LevelerExpFunction<CTX extends Context> extends AbstractConditional
@Override
public Function<CTX> create(Map<String, Object> arguments) {
Object count = ResourceConfigUtils.requireNonNullOrThrow(arguments.get("count"), "warning.config.function.leveler_exp.missing_count");
String leveler = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("leveler"), "warning.config.function.leveler_exp.missing_leveler");
String leveler = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("leveler"), "warning.config.function.leveler_exp.missing_leveler").toLowerCase(Locale.ROOT);
String plugin = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("plugin"), "warning.config.function.leveler_exp.missing_plugin");
return new LevelerExpFunction<>(getPredicates(arguments), leveler, plugin, PlayerSelectors.fromObject(arguments.get("target"), conditionFactory()), NumberProviders.fromObject(count));
}

View File

@@ -58,6 +58,7 @@ authlib_version=7.0.60
concurrent_util_version=0.0.8-SNAPSHOT
bucket4j_version=8.15.0
itembridge_version=1.0.13
levelerbridge_version=1.0.0
# Proxy settings
systemProp.socks.proxyHost=127.0.0.1