Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-16 04:50:07 +01:00
Cancel Erosion futures when disconnecting/switching servers (#5026)
Dieser Commit ist enthalten in:
Ursprung
34f5d71e58
Commit
e194880f7e
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.erosion;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
|
|
||||||
|
public class ErosionCancellationException extends CancellationException {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -42,7 +42,6 @@ public final class GeyserboundHandshakePacketHandler extends AbstractGeyserbound
|
|||||||
public void handleHandshake(GeyserboundHandshakePacket packet) {
|
public void handleHandshake(GeyserboundHandshakePacket packet) {
|
||||||
boolean useTcp = packet.getTransportType().getSocketAddress() == null;
|
boolean useTcp = packet.getTransportType().getSocketAddress() == null;
|
||||||
GeyserboundPacketHandlerImpl handler = new GeyserboundPacketHandlerImpl(session, useTcp ? new GeyserErosionPacketSender(session) : new NettyPacketSender<>());
|
GeyserboundPacketHandlerImpl handler = new GeyserboundPacketHandlerImpl(session, useTcp ? new GeyserErosionPacketSender(session) : new NettyPacketSender<>());
|
||||||
session.setErosionHandler(handler);
|
|
||||||
if (!useTcp) {
|
if (!useTcp) {
|
||||||
if (session.getGeyser().getErosionUnixListener() == null) {
|
if (session.getGeyser().getErosionUnixListener() == null) {
|
||||||
session.disconnect("Erosion configurations using Unix socket handling are not supported on this hardware!");
|
session.disconnect("Erosion configurations using Unix socket handling are not supported on this hardware!");
|
||||||
@ -52,6 +51,7 @@ public final class GeyserboundHandshakePacketHandler extends AbstractGeyserbound
|
|||||||
} else {
|
} else {
|
||||||
handler.onConnect();
|
handler.onConnect();
|
||||||
}
|
}
|
||||||
|
session.setErosionHandler(handler);
|
||||||
session.ensureInEventLoop(() -> session.getChunkCache().clear());
|
session.ensureInEventLoop(() -> session.getChunkCache().clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,10 +171,10 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleHandshake(GeyserboundHandshakePacket packet) {
|
public void handleHandshake(GeyserboundHandshakePacket packet) {
|
||||||
this.close();
|
|
||||||
var handler = new GeyserboundHandshakePacketHandler(this.session);
|
var handler = new GeyserboundHandshakePacketHandler(this.session);
|
||||||
session.setErosionHandler(handler);
|
session.setErosionHandler(handler);
|
||||||
handler.handleHandshake(packet);
|
handler.handleHandshake(packet);
|
||||||
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -198,6 +198,17 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke
|
|||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
this.packetSender.close();
|
this.packetSender.close();
|
||||||
|
|
||||||
|
if (pendingLookup != null) {
|
||||||
|
pendingLookup.completeExceptionally(new ErosionCancellationException());
|
||||||
|
}
|
||||||
|
if (pendingBatchLookup != null) {
|
||||||
|
pendingBatchLookup.completeExceptionally(new ErosionCancellationException());
|
||||||
|
}
|
||||||
|
if (pickBlockLookup != null) {
|
||||||
|
pickBlockLookup.completeExceptionally(new ErosionCancellationException());
|
||||||
|
}
|
||||||
|
asyncPendingLookups.forEach(($, future) -> future.completeExceptionally(new ErosionCancellationException()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextTransactionId() {
|
public int getNextTransactionId() {
|
||||||
|
@ -35,6 +35,7 @@ import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockRequestPac
|
|||||||
import org.geysermc.erosion.packet.backendbound.BackendboundBlockRequestPacket;
|
import org.geysermc.erosion.packet.backendbound.BackendboundBlockRequestPacket;
|
||||||
import org.geysermc.erosion.packet.backendbound.BackendboundPickBlockPacket;
|
import org.geysermc.erosion.packet.backendbound.BackendboundPickBlockPacket;
|
||||||
import org.geysermc.erosion.util.BlockPositionIterator;
|
import org.geysermc.erosion.util.BlockPositionIterator;
|
||||||
|
import org.geysermc.geyser.erosion.ErosionCancellationException;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||||
@ -49,6 +50,8 @@ public class GeyserWorldManager extends WorldManager {
|
|||||||
var erosionHandler = session.getErosionHandler().getAsActive();
|
var erosionHandler = session.getErosionHandler().getAsActive();
|
||||||
if (erosionHandler == null) {
|
if (erosionHandler == null) {
|
||||||
return session.getChunkCache().getBlockAt(x, y, z);
|
return session.getChunkCache().getBlockAt(x, y, z);
|
||||||
|
} else if (session.isClosed()) {
|
||||||
|
throw new ErosionCancellationException();
|
||||||
}
|
}
|
||||||
CompletableFuture<Integer> future = new CompletableFuture<>(); // Boxes
|
CompletableFuture<Integer> future = new CompletableFuture<>(); // Boxes
|
||||||
erosionHandler.setPendingLookup(future);
|
erosionHandler.setPendingLookup(future);
|
||||||
@ -61,6 +64,8 @@ public class GeyserWorldManager extends WorldManager {
|
|||||||
var erosionHandler = session.getErosionHandler().getAsActive();
|
var erosionHandler = session.getErosionHandler().getAsActive();
|
||||||
if (erosionHandler == null) {
|
if (erosionHandler == null) {
|
||||||
return super.getBlockAtAsync(session, x, y, z);
|
return super.getBlockAtAsync(session, x, y, z);
|
||||||
|
} else if (session.isClosed()) {
|
||||||
|
return CompletableFuture.failedFuture(new ErosionCancellationException());
|
||||||
}
|
}
|
||||||
CompletableFuture<Integer> future = new CompletableFuture<>(); // Boxes
|
CompletableFuture<Integer> future = new CompletableFuture<>(); // Boxes
|
||||||
int transactionId = erosionHandler.getNextTransactionId();
|
int transactionId = erosionHandler.getNextTransactionId();
|
||||||
@ -74,6 +79,8 @@ public class GeyserWorldManager extends WorldManager {
|
|||||||
var erosionHandler = session.getErosionHandler().getAsActive();
|
var erosionHandler = session.getErosionHandler().getAsActive();
|
||||||
if (erosionHandler == null) {
|
if (erosionHandler == null) {
|
||||||
return super.getBlocksAt(session, iter);
|
return super.getBlocksAt(session, iter);
|
||||||
|
} else if (session.isClosed()) {
|
||||||
|
throw new ErosionCancellationException();
|
||||||
}
|
}
|
||||||
CompletableFuture<int[]> future = new CompletableFuture<>();
|
CompletableFuture<int[]> future = new CompletableFuture<>();
|
||||||
erosionHandler.setPendingBatchLookup(future);
|
erosionHandler.setPendingBatchLookup(future);
|
||||||
@ -124,6 +131,8 @@ public class GeyserWorldManager extends WorldManager {
|
|||||||
var erosionHandler = session.getErosionHandler().getAsActive();
|
var erosionHandler = session.getErosionHandler().getAsActive();
|
||||||
if (erosionHandler == null) {
|
if (erosionHandler == null) {
|
||||||
return super.getPickItemComponents(session, x, y, z, addNbtData);
|
return super.getPickItemComponents(session, x, y, z, addNbtData);
|
||||||
|
} else if (session.isClosed()) {
|
||||||
|
return CompletableFuture.failedFuture(new ErosionCancellationException());
|
||||||
}
|
}
|
||||||
CompletableFuture<Int2ObjectMap<byte[]>> future = new CompletableFuture<>();
|
CompletableFuture<Int2ObjectMap<byte[]>> future = new CompletableFuture<>();
|
||||||
erosionHandler.setPickBlockLookup(future);
|
erosionHandler.setPickBlockLookup(future);
|
||||||
|
@ -31,6 +31,7 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.Clien
|
|||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
|
import org.geysermc.geyser.erosion.ErosionCancellationException;
|
||||||
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.text.GeyserLocale;
|
import org.geysermc.geyser.text.GeyserLocale;
|
||||||
@ -87,6 +88,8 @@ public class PacketTranslatorRegistry<T> extends AbstractMappedRegistry<Class<?
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
translator.translate(session, packet);
|
translator.translate(session, packet);
|
||||||
|
} catch (ErosionCancellationException ex) {
|
||||||
|
GeyserImpl.getInstance().getLogger().debug("Caught ErosionCancellationException");
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.network.translator.packet.failed", packet.getClass().getSimpleName()), ex);
|
GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.network.translator.packet.failed", packet.getClass().getSimpleName()), ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
@ -130,6 +130,7 @@ import org.geysermc.geyser.entity.type.Tickable;
|
|||||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||||
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
||||||
import org.geysermc.geyser.erosion.AbstractGeyserboundPacketHandler;
|
import org.geysermc.geyser.erosion.AbstractGeyserboundPacketHandler;
|
||||||
|
import org.geysermc.geyser.erosion.ErosionCancellationException;
|
||||||
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
||||||
import org.geysermc.geyser.impl.camera.CameraDefinitions;
|
import org.geysermc.geyser.impl.camera.CameraDefinitions;
|
||||||
import org.geysermc.geyser.impl.camera.GeyserCameraData;
|
import org.geysermc.geyser.impl.camera.GeyserCameraData;
|
||||||
@ -258,7 +259,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Setter
|
@Setter
|
||||||
private AbstractGeyserboundPacketHandler erosionHandler;
|
private volatile AbstractGeyserboundPacketHandler erosionHandler;
|
||||||
|
|
||||||
@Accessors(fluent = true)
|
@Accessors(fluent = true)
|
||||||
@Setter
|
@Setter
|
||||||
@ -1190,9 +1191,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
tickThread.cancel(false);
|
tickThread.cancel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
erosionHandler.close();
|
// Mark session as closed before cancelling erosion futures
|
||||||
|
|
||||||
closed = true;
|
closed = true;
|
||||||
|
erosionHandler.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1213,6 +1214,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
eventLoop.execute(() -> {
|
eventLoop.execute(() -> {
|
||||||
try {
|
try {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
|
} catch (ErosionCancellationException e) {
|
||||||
|
geyser.getLogger().debug("Caught ErosionCancellationException");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
|
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
|
||||||
}
|
}
|
||||||
@ -1230,6 +1233,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
if (!closed) {
|
if (!closed) {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
|
} catch (ErosionCancellationException e) {
|
||||||
|
geyser.getLogger().debug("Caught ErosionCancellationException");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
|
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ import org.geysermc.erosion.Constants;
|
|||||||
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
|
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
|
||||||
import org.geysermc.geyser.api.network.AuthType;
|
import org.geysermc.geyser.api.network.AuthType;
|
||||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||||
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
|
||||||
import org.geysermc.geyser.level.JavaDimension;
|
import org.geysermc.geyser.level.JavaDimension;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
@ -57,11 +56,6 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
|||||||
SessionPlayerEntity entity = session.getPlayerEntity();
|
SessionPlayerEntity entity = session.getPlayerEntity();
|
||||||
entity.setEntityId(packet.getEntityId());
|
entity.setEntityId(packet.getEntityId());
|
||||||
|
|
||||||
if (session.getErosionHandler().isActive()) {
|
|
||||||
session.getErosionHandler().close();
|
|
||||||
session.setErosionHandler(new GeyserboundHandshakePacketHandler(session));
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo();
|
PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo();
|
||||||
JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension());
|
JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension());
|
||||||
|
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
|
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
||||||
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundStartConfigurationPacket;
|
||||||
|
|
||||||
|
@Translator(packet = ClientboundStartConfigurationPacket.class)
|
||||||
|
public class JavaStartConfigurationTranslator extends PacketTranslator<ClientboundStartConfigurationPacket> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void translate(GeyserSession session, ClientboundStartConfigurationPacket packet) {
|
||||||
|
var erosionHandler = session.getErosionHandler();
|
||||||
|
if (erosionHandler.isActive()) {
|
||||||
|
// Set new handler before closing
|
||||||
|
session.setErosionHandler(new GeyserboundHandshakePacketHandler(session));
|
||||||
|
erosionHandler.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldExecuteInEventLoop() {
|
||||||
|
// Execute outside of event loop to cancel any pending erosion futures
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren