版本更新 1.2.2 -> 1.2.3
修复拴绳配置同步问题
This commit is contained in:
parent
0b6412548f
commit
18d1d06d39
|
|
@ -123,6 +123,11 @@ legacyForge {
|
||||||
server {
|
server {
|
||||||
server()
|
server()
|
||||||
}
|
}
|
||||||
|
testServer {
|
||||||
|
server()
|
||||||
|
// 设置服务器运行目录
|
||||||
|
gameDirectory = file('run/server')
|
||||||
|
}
|
||||||
data {
|
data {
|
||||||
data()
|
data()
|
||||||
programArguments.addAll '--mod', mod_id, '--all',
|
programArguments.addAll '--mod', mod_id, '--all',
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ mod_name=Super Lead Rope
|
||||||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||||
mod_license=GPLv3
|
mod_license=GPLv3
|
||||||
# The mod version. See https://semver.org/
|
# The mod version. See https://semver.org/
|
||||||
mod_version=1.2.2
|
mod_version=1.2.3
|
||||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||||
# This should match the base package used for the mod sources.
|
# This should match the base package used for the mod sources.
|
||||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import net.minecraftforge.fml.config.ModConfig;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import top.r3944realms.superleadrope.compat.CurtainCompat;
|
||||||
import top.r3944realms.superleadrope.compat.WayStoneCompat;
|
import top.r3944realms.superleadrope.compat.WayStoneCompat;
|
||||||
import top.r3944realms.superleadrope.config.LeashCommonConfig;
|
import top.r3944realms.superleadrope.config.LeashCommonConfig;
|
||||||
import top.r3944realms.superleadrope.core.register.*;
|
import top.r3944realms.superleadrope.core.register.*;
|
||||||
|
|
@ -72,6 +73,7 @@ public class SuperLeadRope {
|
||||||
ModLoadingContext modLoadingContext = ModLoadingContext.get();
|
ModLoadingContext modLoadingContext = ModLoadingContext.get();
|
||||||
ConfigUtil.registerConfig(modLoadingContext, ModConfig.Type.COMMON, LeashCommonConfig.SPEC, c, "leash");
|
ConfigUtil.registerConfig(modLoadingContext, ModConfig.Type.COMMON, LeashCommonConfig.SPEC, c, "leash");
|
||||||
WayStoneCompat.init();
|
WayStoneCompat.init();
|
||||||
|
CurtainCompat.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -104,4 +104,11 @@ public interface IWorkSpaceHelper {
|
||||||
* @return the leash state
|
* @return the leash state
|
||||||
*/
|
*/
|
||||||
Optional<ILeashState> getLeashState(@NotNull Entity pEntity);
|
Optional<ILeashState> getLeashState(@NotNull Entity pEntity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register fake player.
|
||||||
|
*
|
||||||
|
* @param classes the classes
|
||||||
|
*/
|
||||||
|
void registerFakePlayer(@NotNull Class<?>... classes);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,15 +29,11 @@ public class CurtainCompat{
|
||||||
public final static boolean isModLoaded = ModList.get().isLoaded("curtain");
|
public final static boolean isModLoaded = ModList.get().isLoaded("curtain");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is not fake player boolean.
|
* Init.
|
||||||
*
|
|
||||||
* @param player the player
|
|
||||||
* @return the boolean
|
|
||||||
*/
|
*/
|
||||||
public static boolean isNotFakePlayer(Player player) {
|
public static void init() {
|
||||||
if (isModLoaded) {
|
if (isModLoaded) {
|
||||||
return !(player instanceof EntityPlayerMPFake);
|
FakePlayerJudge.registersFakePlayer(EntityPlayerMPFake.class);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Super Lead rope mod
|
||||||
|
* Copyright (C) 2026 R3944Realms
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.r3944realms.superleadrope.compat;
|
||||||
|
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type Fake player judge.
|
||||||
|
*/
|
||||||
|
public class FakePlayerJudge {
|
||||||
|
private final static Set<Class<?>> fakePlayerClasses = new HashSet<>();
|
||||||
|
|
||||||
|
private static void check(final @NotNull Class<?> fakePlayerClass) throws IllegalArgumentException {
|
||||||
|
if(fakePlayerClass.equals(Player.class) || fakePlayerClass.equals(ServerPlayer.class))
|
||||||
|
throw new IllegalArgumentException("Player or ServerPlayer class cannot be used as FakePlayer");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers fake player.
|
||||||
|
*
|
||||||
|
* @param fakePlayerClass the fake player class
|
||||||
|
*/
|
||||||
|
public static void registersFakePlayer(final Class<?> @NotNull ...fakePlayerClass) {
|
||||||
|
for (Class<?> playerClass : fakePlayerClass) {
|
||||||
|
check(playerClass);
|
||||||
|
}
|
||||||
|
fakePlayerClasses.addAll(List.of(fakePlayerClass));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is fake player boolean.
|
||||||
|
*
|
||||||
|
* @param entity the entity
|
||||||
|
* @return the boolean
|
||||||
|
*/
|
||||||
|
public static boolean isNotFakePlayer(@NotNull Entity entity) {
|
||||||
|
if (!(entity instanceof Player)) return true;
|
||||||
|
return !fakePlayerClasses.contains(entity.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -228,7 +228,7 @@ public class LeashConfigManager {
|
||||||
* @return the teleport whitelist
|
* @return the teleport whitelist
|
||||||
*/
|
*/
|
||||||
// ================== 白名单 ==================
|
// ================== 白名单 ==================
|
||||||
public List<String> getTeleportWhitelist() { return Collections.unmodifiableList(teleportWhitelistCache); }
|
public List<String> getTeleportWhitelist() { return new ArrayList<>(teleportWhitelistCache); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is entity teleport allowed boolean.
|
* Is entity teleport allowed boolean.
|
||||||
|
|
@ -358,7 +358,7 @@ public class LeashConfigManager {
|
||||||
*
|
*
|
||||||
* @return the axis elasticity
|
* @return the axis elasticity
|
||||||
*/
|
*/
|
||||||
public List<Double> getAxisElasticity() { return Collections.unmodifiableList(axisElasticity); }
|
public List<Double> getAxisElasticity() { return new ArrayList<>(axisElasticity); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets x elasticity.
|
* Gets x elasticity.
|
||||||
|
|
@ -423,7 +423,7 @@ public class LeashConfigManager {
|
||||||
maxForce = LeashCommonConfig.COMMON.maxForce.get();
|
maxForce = LeashCommonConfig.COMMON.maxForce.get();
|
||||||
playerSpringFactor = LeashCommonConfig.COMMON.playerSpringFactor.get();
|
playerSpringFactor = LeashCommonConfig.COMMON.playerSpringFactor.get();
|
||||||
mobSpringFactor = LeashCommonConfig.COMMON.mobSpringFactor.get();
|
mobSpringFactor = LeashCommonConfig.COMMON.mobSpringFactor.get();
|
||||||
cacheHash = calculateConfigHash();
|
cacheHash = -1;
|
||||||
cacheTag = serializeToNBT();
|
cacheTag = serializeToNBT();
|
||||||
SuperLeadRope.logger.debug("Configs reloaded: {}", getStats());
|
SuperLeadRope.logger.debug("Configs reloaded: {}", getStats());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -476,7 +476,11 @@ public class LeashConfigManager {
|
||||||
* @return the compound tag
|
* @return the compound tag
|
||||||
*/
|
*/
|
||||||
public synchronized CompoundTag serializeToNBT() {
|
public synchronized CompoundTag serializeToNBT() {
|
||||||
if (cacheHash == calculateConfigHash() && cacheTag != null) return cacheTag;
|
int currentHash = calculateConfigHash();
|
||||||
|
|
||||||
|
if (cacheTag != null && cacheHash == currentHash) {
|
||||||
|
return cacheTag;
|
||||||
|
}
|
||||||
CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
|
|
||||||
// 序列化偏移映射
|
// 序列化偏移映射
|
||||||
|
|
@ -518,7 +522,7 @@ public class LeashConfigManager {
|
||||||
tag.put("axis_elasticity", elasticityTag);
|
tag.put("axis_elasticity", elasticityTag);
|
||||||
|
|
||||||
tag.putInt("max_leashes_per_entity", maxLeashesPerEntity);
|
tag.putInt("max_leashes_per_entity", maxLeashesPerEntity);
|
||||||
cacheHash = calculateConfigHash();
|
cacheHash = currentHash;
|
||||||
cacheTag = tag;
|
cacheTag = tag;
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
|
|
@ -554,7 +558,6 @@ public class LeashConfigManager {
|
||||||
LeashCommonConfig.COMMON.maxForce.set(maxForce);
|
LeashCommonConfig.COMMON.maxForce.set(maxForce);
|
||||||
LeashCommonConfig.COMMON.playerSpringFactor.set(playerSpringFactor);
|
LeashCommonConfig.COMMON.playerSpringFactor.set(playerSpringFactor);
|
||||||
LeashCommonConfig.COMMON.mobSpringFactor.set(mobSpringFactor);
|
LeashCommonConfig.COMMON.mobSpringFactor.set(mobSpringFactor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -617,6 +620,9 @@ public class LeashConfigManager {
|
||||||
public void deserializeFromNBT(CompoundTag tag) {
|
public void deserializeFromNBT(CompoundTag tag) {
|
||||||
if (tag == null || tag.isEmpty()) return;
|
if (tag == null || tag.isEmpty()) return;
|
||||||
|
|
||||||
|
cacheHash = -1;
|
||||||
|
cacheTag = null;
|
||||||
|
|
||||||
// 反序列化偏移映射
|
// 反序列化偏移映射
|
||||||
if (tag.contains("offsets", Tag.TAG_COMPOUND)) {
|
if (tag.contains("offsets", Tag.TAG_COMPOUND)) {
|
||||||
CompoundTag offsets = tag.getCompound("offsets");
|
CompoundTag offsets = tag.getCompound("offsets");
|
||||||
|
|
@ -635,7 +641,7 @@ public class LeashConfigManager {
|
||||||
for (int i = 0; i < whitelistTag.size(); i++) {
|
for (int i = 0; i < whitelistTag.size(); i++) {
|
||||||
whitelist.add(whitelistTag.getString(i));
|
whitelist.add(whitelistTag.getString(i));
|
||||||
}
|
}
|
||||||
teleportWhitelistCache = Collections.unmodifiableList(whitelist);
|
teleportWhitelistCache = new ArrayList<>(whitelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.contains("command_prefix", Tag.TAG_STRING)) {
|
if (tag.contains("command_prefix", Tag.TAG_STRING)) {
|
||||||
|
|
@ -681,7 +687,7 @@ public class LeashConfigManager {
|
||||||
for (int i = 0; i < elasticityTag.size(); i++) {
|
for (int i = 0; i < elasticityTag.size(); i++) {
|
||||||
elasticity.add(elasticityTag.getDouble(i));
|
elasticity.add(elasticityTag.getDouble(i));
|
||||||
}
|
}
|
||||||
axisElasticity = Collections.unmodifiableList(elasticity);
|
axisElasticity = new ArrayList<>(elasticity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.contains("max_leashes_per_entity", Tag.TAG_INT)) {
|
if (tag.contains("max_leashes_per_entity", Tag.TAG_INT)) {
|
||||||
|
|
@ -707,10 +713,6 @@ public class LeashConfigManager {
|
||||||
hash = fnv1aHashMap(hash, tagLeashMap);
|
hash = fnv1aHashMap(hash, tagLeashMap);
|
||||||
hash = fnv1aHashMap(hash, modLeashMap);
|
hash = fnv1aHashMap(hash, modLeashMap);
|
||||||
|
|
||||||
// 哈希白名单
|
|
||||||
for (String entry : teleportWhitelistCache) {
|
|
||||||
hash = fnv1aHashString(hash, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 哈希字符串参数
|
// 哈希字符串参数
|
||||||
hash = fnv1aHashString(hash, commandPrefixCache);
|
hash = fnv1aHashString(hash, commandPrefixCache);
|
||||||
|
|
@ -727,8 +729,18 @@ public class LeashConfigManager {
|
||||||
hash = fnv1aHashLong(hash, Double.doubleToLongBits(extremeSnapFactor));
|
hash = fnv1aHashLong(hash, Double.doubleToLongBits(extremeSnapFactor));
|
||||||
hash = fnv1aHashLong(hash, Double.doubleToLongBits(springDampening));
|
hash = fnv1aHashLong(hash, Double.doubleToLongBits(springDampening));
|
||||||
|
|
||||||
// 哈希轴弹性列表
|
|
||||||
for (double value : axisElasticity) {
|
// 白名单排序后再哈希
|
||||||
|
List<String> sortedWhitelist = new ArrayList<>(teleportWhitelistCache);
|
||||||
|
Collections.sort(sortedWhitelist);
|
||||||
|
for (String entry : sortedWhitelist) {
|
||||||
|
hash = fnv1aHashString(hash, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 轴弹性列表排序(或者保持原序但确保两端一致)
|
||||||
|
List<Double> sortedElasticity = new ArrayList<>(axisElasticity);
|
||||||
|
Collections.sort(sortedElasticity);
|
||||||
|
for (double value : sortedElasticity) {
|
||||||
hash = fnv1aHashLong(hash, Double.doubleToLongBits(value));
|
hash = fnv1aHashLong(hash, Double.doubleToLongBits(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -743,7 +755,7 @@ public class LeashConfigManager {
|
||||||
private void serializeOffsetMap(CompoundTag parent, String key, @NotNull Map<String, double[]> map) {
|
private void serializeOffsetMap(CompoundTag parent, String key, @NotNull Map<String, double[]> map) {
|
||||||
CompoundTag mapTag = new CompoundTag();
|
CompoundTag mapTag = new CompoundTag();
|
||||||
for (Map.Entry<String, double[]> entry : map.entrySet()) {
|
for (Map.Entry<String, double[]> entry : map.entrySet()) {
|
||||||
String entryKey = entry.getKey().replace(':', '_'); // 避免NBT键中的冒号问题
|
String entryKey = entry.getKey();
|
||||||
ListTag offsetList = new ListTag();
|
ListTag offsetList = new ListTag();
|
||||||
for (double value : entry.getValue()) {
|
for (double value : entry.getValue()) {
|
||||||
offsetList.add(DoubleTag.valueOf(value));
|
offsetList.add(DoubleTag.valueOf(value));
|
||||||
|
|
@ -764,12 +776,13 @@ public class LeashConfigManager {
|
||||||
for (int i = 0; i < offsetList.size(); i++) {
|
for (int i = 0; i < offsetList.size(); i++) {
|
||||||
offset[i] = offsetList.getDouble(i);
|
offset[i] = offsetList.getDouble(i);
|
||||||
}
|
}
|
||||||
map.put(entryKey.replace('_', ':'), offset); // 恢复原始键名
|
map.put(entryKey, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FNV-1a哈希辅助方法
|
// FNV-1a哈希辅助方法
|
||||||
private int fnv1aHashInt(int hash, int value) {
|
private int fnv1aHashInt(int hash, int value) {
|
||||||
hash ^= (value & 0xFF);
|
hash ^= (value & 0xFF);
|
||||||
|
|
@ -797,7 +810,8 @@ public class LeashConfigManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int fnv1aHashMap(int hash, @NotNull Map<String, double[]> map) {
|
private int fnv1aHashMap(int hash, @NotNull Map<String, double[]> map) {
|
||||||
for (Map.Entry<String, double[]> entry : map.entrySet()) {
|
Map<String, double[]> sortedMap = map instanceof TreeMap ? map : new TreeMap<>(map);
|
||||||
|
for (Map.Entry<String, double[]> entry : sortedMap.entrySet()) {
|
||||||
hash = fnv1aHashString(hash, entry.getKey());
|
hash = fnv1aHashString(hash, entry.getKey());
|
||||||
for (double value : entry.getValue()) {
|
for (double value : entry.getValue()) {
|
||||||
hash = fnv1aHashLong(hash, Double.doubleToLongBits(value));
|
hash = fnv1aHashLong(hash, Double.doubleToLongBits(value));
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import top.r3944realms.superleadrope.SuperLeadRope;
|
||||||
import top.r3944realms.superleadrope.api.event.SuperLeadRopeEvent;
|
import top.r3944realms.superleadrope.api.event.SuperLeadRopeEvent;
|
||||||
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
|
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
|
||||||
import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo;
|
import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo;
|
||||||
import top.r3944realms.superleadrope.compat.CurtainCompat;
|
import top.r3944realms.superleadrope.compat.FakePlayerJudge;
|
||||||
import top.r3944realms.superleadrope.compat.LuckPermsCompat;
|
import top.r3944realms.superleadrope.compat.LuckPermsCompat;
|
||||||
import top.r3944realms.superleadrope.config.LeashConfigManager;
|
import top.r3944realms.superleadrope.config.LeashConfigManager;
|
||||||
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
|
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
|
||||||
|
|
@ -785,7 +785,7 @@ public class LeashDataImpl implements ILeashData {
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void applyLeashForcesClientPlayer() {
|
public void applyLeashForcesClientPlayer() {
|
||||||
if (entity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player)) return;
|
if (entity instanceof ServerPlayer player && FakePlayerJudge.isNotFakePlayer(player)) return;
|
||||||
Vec3 combinedForce = Vec3.ZERO;
|
Vec3 combinedForce = Vec3.ZERO;
|
||||||
Vec3 combinedDirection = Vec3.ZERO;
|
Vec3 combinedDirection = Vec3.ZERO;
|
||||||
Map<Integer, LeashInfo> result = leashHolders.entrySet().stream()
|
Map<Integer, LeashInfo> result = leashHolders.entrySet().stream()
|
||||||
|
|
@ -881,7 +881,7 @@ public class LeashDataImpl implements ILeashData {
|
||||||
if (MinecraftForge.EVENT_BUS.post(hasFocus)) return;
|
if (MinecraftForge.EVENT_BUS.post(hasFocus)) return;
|
||||||
combinedForce = hasFocus.getCombinedForce();
|
combinedForce = hasFocus.getCombinedForce();
|
||||||
// 玩家与普通实体统一力应用
|
// 玩家与普通实体统一力应用
|
||||||
if (targetEntity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player) ) {
|
if (targetEntity instanceof ServerPlayer player && FakePlayerJudge.isNotFakePlayer(player)) {
|
||||||
// 是真实玩家则交给客户端自行处理拴绳逻辑
|
// 是真实玩家则交给客户端自行处理拴绳逻辑
|
||||||
// DO NOTHING
|
// DO NOTHING
|
||||||
if(targetEntity == entity) {
|
if(targetEntity == entity) {
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,12 @@ package top.r3944realms.superleadrope.network.toClient;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import top.r3944realms.superleadrope.CommonEventHandler;
|
import top.r3944realms.superleadrope.CommonEventHandler;
|
||||||
import top.r3944realms.superleadrope.SuperLeadRope;
|
import top.r3944realms.superleadrope.SuperLeadRope;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -54,15 +57,61 @@ public record SyncCommonConfigPacket(CompoundTag config, int hash) {
|
||||||
* @param msg the msg
|
* @param msg the msg
|
||||||
* @param ctx the ctx
|
* @param ctx the ctx
|
||||||
*/
|
*/
|
||||||
public static void handle(SyncCommonConfigPacket msg, Supplier<NetworkEvent.Context> ctx) {
|
public static void handle(SyncCommonConfigPacket msg, @NotNull Supplier<NetworkEvent.Context> ctx) {
|
||||||
ctx.get().enqueueWork(() -> {
|
ctx.get().enqueueWork(() -> {
|
||||||
CompoundTag old = CommonEventHandler.leashConfigManager.serializeToNBT();
|
// 1. 保存当前配置(强制重新序列化,不使用缓存)
|
||||||
|
CompoundTag currentConfig = CommonEventHandler.leashConfigManager.serializeToNBT();
|
||||||
|
int currentHash = CommonEventHandler.leashConfigManager.calculateConfigHash();
|
||||||
|
|
||||||
|
// 2. 应用新配置
|
||||||
CommonEventHandler.leashConfigManager.deserializeFromNBT(msg.config);
|
CommonEventHandler.leashConfigManager.deserializeFromNBT(msg.config);
|
||||||
if (CommonEventHandler.leashConfigManager.calculateConfigHash() != msg.hash) { //BACK
|
|
||||||
SuperLeadRope.logger.error("Hash mismatch! Except:{}, Actual:{}", msg.hash, CommonEventHandler.leashConfigManager.calculateConfigHash());
|
// 3. 验证哈希
|
||||||
CommonEventHandler.leashConfigManager.deserializeFromNBT(old);
|
int newHash = CommonEventHandler.leashConfigManager.calculateConfigHash();
|
||||||
|
if (newHash != msg.hash) {
|
||||||
|
SuperLeadRope.logger.error("Hash mismatch! Expected: {}, Actual: {}", msg.hash, newHash);
|
||||||
|
SuperLeadRope.logger.error("Current hash before deserialization: {}", currentHash);
|
||||||
|
|
||||||
|
// 可选:打印差异详情
|
||||||
|
if (currentConfig != null && msg.config != null) {
|
||||||
|
compareConfigs(currentConfig, msg.config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 恢复旧配置
|
||||||
|
CommonEventHandler.leashConfigManager.deserializeFromNBT(currentConfig);
|
||||||
|
} else {
|
||||||
|
SuperLeadRope.logger.debug("Config sync successful, hash: {}", msg.hash);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ctx.get().setPacketHandled(true);
|
ctx.get().setPacketHandled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 辅助方法:比较配置差异
|
||||||
|
private static void compareConfigs(CompoundTag oldConfig, CompoundTag newConfig) {
|
||||||
|
Set<String> oldKeys = oldConfig.getAllKeys();
|
||||||
|
Set<String> newKeys = newConfig.getAllKeys();
|
||||||
|
|
||||||
|
// 找出只存在于旧配置的键
|
||||||
|
for (String key : oldKeys) {
|
||||||
|
if (!newConfig.contains(key)) {
|
||||||
|
SuperLeadRope.logger.warn("Key only in old config: {}", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找出只存在于新配置的键
|
||||||
|
for (String key : newKeys) {
|
||||||
|
if (!oldConfig.contains(key)) {
|
||||||
|
SuperLeadRope.logger.warn("Key only in new config: {}", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 比较共同键的值
|
||||||
|
for (String key : oldKeys) {
|
||||||
|
if (newConfig.contains(key) && !Objects.equals(oldConfig.get(key), newConfig.get(key))) {
|
||||||
|
SuperLeadRope.logger.warn("Value mismatch for key: {}", key);
|
||||||
|
SuperLeadRope.logger.warn(" Old: {}", oldConfig.get(key));
|
||||||
|
SuperLeadRope.logger.warn(" New: {}", newConfig.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
|
||||||
import top.r3944realms.superleadrope.api.type.capabilty.ILeashState;
|
import top.r3944realms.superleadrope.api.type.capabilty.ILeashState;
|
||||||
import top.r3944realms.superleadrope.api.type.util.ILeashHelper;
|
import top.r3944realms.superleadrope.api.type.util.ILeashHelper;
|
||||||
import top.r3944realms.superleadrope.api.workspace.IWorkSpaceHelper;
|
import top.r3944realms.superleadrope.api.workspace.IWorkSpaceHelper;
|
||||||
|
import top.r3944realms.superleadrope.compat.FakePlayerJudge;
|
||||||
import top.r3944realms.superleadrope.content.capability.impi.LeashDataImpl;
|
import top.r3944realms.superleadrope.content.capability.impi.LeashDataImpl;
|
||||||
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
|
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
|
||||||
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
|
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
|
||||||
|
|
@ -84,4 +85,9 @@ public class WorkSpaceHelper implements IWorkSpaceHelper {
|
||||||
return LeashStateInnerAPI.getLeashState(pEntity);
|
return LeashStateInnerAPI.getLeashState(pEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerFakePlayer(@NotNull Class<?>... classes) {
|
||||||
|
FakePlayerJudge.registersFakePlayer(classes);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user