Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-27 16:40:10 +01:00
Release ConfigurationState buffers on disconnect
They're heap buffers, but still good practice
Dieser Commit ist enthalten in:
Ursprung
494e6ffc05
Commit
9c90445c9c
@ -38,4 +38,7 @@ public interface StorableObject {
|
|||||||
default boolean clearOnServerSwitch() {
|
default boolean clearOnServerSwitch() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void onRemove() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,8 @@ public class ConnectionManagerImpl implements ConnectionManager {
|
|||||||
UUID id = connection.getProtocolInfo().getUuid();
|
UUID id = connection.getProtocolInfo().getUuid();
|
||||||
clients.remove(id);
|
clients.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connection.clearStoredObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,12 +94,19 @@ public class UserConnectionImpl implements UserConnection {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends StorableObject> @Nullable T remove(Class<T> objectClass) {
|
public <T extends StorableObject> @Nullable T remove(Class<T> objectClass) {
|
||||||
return (T) storedObjects.remove(objectClass);
|
final StorableObject object = storedObjects.remove(objectClass);
|
||||||
|
if (object != null) {
|
||||||
|
object.onRemove();
|
||||||
|
}
|
||||||
|
return (T) object;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(StorableObject object) {
|
public void put(StorableObject object) {
|
||||||
storedObjects.put(object.getClass(), object);
|
final StorableObject previousObject = storedObjects.put(object.getClass(), object);
|
||||||
|
if (previousObject != null) {
|
||||||
|
previousObject.onRemove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -122,12 +129,21 @@ public class UserConnectionImpl implements UserConnection {
|
|||||||
@Override
|
@Override
|
||||||
public void clearStoredObjects(boolean isServerSwitch) {
|
public void clearStoredObjects(boolean isServerSwitch) {
|
||||||
if (isServerSwitch) {
|
if (isServerSwitch) {
|
||||||
storedObjects.values().removeIf(StorableObject::clearOnServerSwitch);
|
storedObjects.values().removeIf(storableObject -> {
|
||||||
|
if (storableObject.clearOnServerSwitch()) {
|
||||||
|
storableObject.onRemove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
for (EntityTracker tracker : entityTrackers.values()) {
|
for (EntityTracker tracker : entityTrackers.values()) {
|
||||||
tracker.clearEntities();
|
tracker.clearEntities();
|
||||||
tracker.trackClientEntity();
|
tracker.trackClientEntity();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
for (StorableObject object : storedObjects.values()) {
|
||||||
|
object.onRemove();
|
||||||
|
}
|
||||||
storedObjects.clear();
|
storedObjects.clear();
|
||||||
entityTrackers.clear();
|
entityTrackers.clear();
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public class ConfigurationState implements StorableObject {
|
|||||||
packetQueue.add(toQueuedPacket(wrapper, clientbound, false));
|
packetQueue.add(toQueuedPacket(wrapper, clientbound, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueuedPacket toQueuedPacket(final PacketWrapper wrapper, final boolean clientbound, final boolean skip1_20_2Pipeline) throws Exception {
|
private QueuedPacket toQueuedPacket(final PacketWrapper wrapper, final boolean clientbound, final boolean skipCurrentPipeline) throws Exception {
|
||||||
// Caching packet buffers is cursed, copy to heap buffers to make sure we don't start leaking in dumb cases
|
// Caching packet buffers is cursed, copy to heap buffers to make sure we don't start leaking in dumb cases
|
||||||
final ByteBuf copy = Unpooled.buffer();
|
final ByteBuf copy = Unpooled.buffer();
|
||||||
final PacketType packetType = wrapper.getPacketType();
|
final PacketType packetType = wrapper.getPacketType();
|
||||||
@ -56,7 +56,7 @@ public class ConfigurationState implements StorableObject {
|
|||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
wrapper.setId(-1);
|
wrapper.setId(-1);
|
||||||
wrapper.writeToBuffer(copy);
|
wrapper.writeToBuffer(copy);
|
||||||
return new QueuedPacket(copy, clientbound, packetType, packetId, skip1_20_2Pipeline);
|
return new QueuedPacket(copy, clientbound, packetType, packetId, skipCurrentPipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJoinGamePacket(final PacketWrapper wrapper) throws Exception {
|
public void setJoinGamePacket(final PacketWrapper wrapper) throws Exception {
|
||||||
@ -69,6 +69,16 @@ public class ConfigurationState implements StorableObject {
|
|||||||
return false; // This might be bad
|
return false; // This might be bad
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemove() {
|
||||||
|
for (final QueuedPacket packet : packetQueue) {
|
||||||
|
packet.buf().release();
|
||||||
|
}
|
||||||
|
if (joinGamePacket != null) {
|
||||||
|
joinGamePacket.buf().release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void sendQueuedPackets(final UserConnection connection) throws Exception {
|
public void sendQueuedPackets(final UserConnection connection) throws Exception {
|
||||||
if (joinGamePacket != null) {
|
if (joinGamePacket != null) {
|
||||||
packetQueue.add(0, joinGamePacket);
|
packetQueue.add(0, joinGamePacket);
|
||||||
@ -89,9 +99,9 @@ public class ConfigurationState implements StorableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packet.clientbound()) {
|
if (packet.clientbound()) {
|
||||||
queuedWrapper.send(Protocol1_20_2To1_20.class, packet.skip1_20_2Pipeline());
|
queuedWrapper.send(Protocol1_20_2To1_20.class, packet.skipCurrentPipeline());
|
||||||
} else {
|
} else {
|
||||||
queuedWrapper.sendToServer(Protocol1_20_2To1_20.class, packet.skip1_20_2Pipeline());
|
queuedWrapper.sendToServer(Protocol1_20_2To1_20.class, packet.skipCurrentPipeline());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
packet.buf().release();
|
packet.buf().release();
|
||||||
@ -118,15 +128,15 @@ public class ConfigurationState implements StorableObject {
|
|||||||
private final boolean clientbound;
|
private final boolean clientbound;
|
||||||
private final PacketType packetType;
|
private final PacketType packetType;
|
||||||
private final int packetId;
|
private final int packetId;
|
||||||
private final boolean skip1_20_2Pipeline;
|
private final boolean skipCurrentPipeline;
|
||||||
|
|
||||||
private QueuedPacket(final ByteBuf buf, final boolean clientbound, final PacketType packetType,
|
private QueuedPacket(final ByteBuf buf, final boolean clientbound, final PacketType packetType,
|
||||||
final int packetId, final boolean skip1_20_2Pipeline) {
|
final int packetId, final boolean skipCurrentPipeline) {
|
||||||
this.buf = buf;
|
this.buf = buf;
|
||||||
this.clientbound = clientbound;
|
this.clientbound = clientbound;
|
||||||
this.packetType = packetType;
|
this.packetType = packetType;
|
||||||
this.packetId = packetId;
|
this.packetId = packetId;
|
||||||
this.skip1_20_2Pipeline = skip1_20_2Pipeline;
|
this.skipCurrentPipeline = skipCurrentPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ByteBuf buf() {
|
public ByteBuf buf() {
|
||||||
@ -145,8 +155,8 @@ public class ConfigurationState implements StorableObject {
|
|||||||
return packetType;
|
return packetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean skip1_20_2Pipeline() {
|
public boolean skipCurrentPipeline() {
|
||||||
return skip1_20_2Pipeline;
|
return skipCurrentPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -156,7 +166,7 @@ public class ConfigurationState implements StorableObject {
|
|||||||
", clientbound=" + clientbound +
|
", clientbound=" + clientbound +
|
||||||
", packetType=" + packetType +
|
", packetType=" + packetType +
|
||||||
", packetId=" + packetId +
|
", packetId=" + packetId +
|
||||||
", skip1_20_2Pipeline=" + skip1_20_2Pipeline +
|
", skipCurrentPipeline=" + skipCurrentPipeline +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren