9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2026-01-06 15:52:03 +00:00

修复意外的触发2次PlayerSpawnLocationEvent和AsyncPlayerSpawnLocationEvent

This commit is contained in:
jhqwqmc
2025-11-28 18:46:44 +08:00
parent 37bc06c80d
commit 639813a05e
2 changed files with 42 additions and 10 deletions

View File

@@ -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;
@@ -124,6 +125,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;
public class BukkitNetworkManager implements NetworkManager, Listener, PluginMessageListener {
@@ -1802,6 +1804,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) {
@@ -1852,15 +1863,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);
@@ -1869,13 +1871,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);
});
}
}

View File

@@ -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")