small network code cleanup

This commit is contained in:
Sen 2025-05-24 20:42:53 +02:00
parent bd4b8d427a
commit d6d934f1f3
2 changed files with 203 additions and 264 deletions

View file

@ -23,310 +23,250 @@ import io.netty.util.AttributeKey;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.GenericFutureListener;
public class NetConnection extends SimpleChannelInboundHandler<Packet> public class NetConnection extends SimpleChannelInboundHandler<Packet> {
{
private static final Pattern IP_REPLACER = Pattern.compile("([0-9]*)\\.([0-9]*)\\.[0-9]*\\.[0-9]*"); private static final Pattern IP_REPLACER = Pattern.compile("([0-9]*)\\.([0-9]*)\\.[0-9]*\\.[0-9]*");
public static final AttributeKey<PacketRegistry> ATTR_STATE = AttributeKey.<PacketRegistry>valueOf("protocol"); public static final AttributeKey<PacketRegistry> ATTR_STATE = AttributeKey.<PacketRegistry>valueOf("protocol");
private final Queue<NetConnection.InboundHandlerTuplePacketListener> queue = new ConcurrentLinkedQueue<InboundHandlerTuplePacketListener>(); private final Queue<NetConnection.InboundHandlerTuplePacketListener> queue = new ConcurrentLinkedQueue<InboundHandlerTuplePacketListener>();
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private Channel channel; private Channel channel;
private SocketAddress address; private SocketAddress address;
private NetHandler handler; private NetHandler handler;
private String exitReason; private String exitReason;
private boolean disconnected; private boolean disconnected;
public void channelActive(ChannelHandlerContext context) throws Exception public void channelActive(ChannelHandlerContext context) throws Exception {
{ super.channelActive(context);
super.channelActive(context); this.channel = context.channel();
this.channel = context.channel(); this.address = this.channel.remoteAddress();
this.address = this.channel.remoteAddress();
try try {
{ this.setConnectionState(PacketRegistry.HANDSHAKE);
this.setConnectionState(PacketRegistry.HANDSHAKE); }
} catch(Throwable t) {
catch (Throwable t) Log.JNI.error(t, "Fehler beim Aufbauen der Verbindung für Handshake");
{ }
Log.JNI.error(t, "Fehler beim Aufbauen der Verbindung für Handshake"); }
}
}
public void setConnectionState(PacketRegistry newState) public void setConnectionState(PacketRegistry newState) {
{ this.channel.attr(ATTR_STATE).set(newState);
this.channel.attr(ATTR_STATE).set(newState); this.channel.config().setAutoRead(true);
this.channel.config().setAutoRead(true);
// Log.debug("Automatisches Lesen eingeschaltet"); // Log.debug("Automatisches Lesen eingeschaltet");
} }
public void channelInactive(ChannelHandlerContext context) throws Exception public void channelInactive(ChannelHandlerContext context) throws Exception {
{ this.closeChannel("Ende der Datenübertragung");
this.closeChannel("Ende der Datenübertragung"); }
}
public void exceptionCaught(ChannelHandlerContext context, Throwable throwable) throws Exception public void exceptionCaught(ChannelHandlerContext context, Throwable throwable) throws Exception {
{ String comp;
String comp;
if (throwable instanceof TimeoutException) if(throwable instanceof TimeoutException) {
{ comp = "Zeitüberschreitung";
comp = "Zeitüberschreitung"; }
} else {
else comp = "Interner Fehler: " + throwable;
{ if(!(throwable instanceof ClosedChannelException))
comp = "Interner Fehler: " + throwable; Log.SYSTEM.error(throwable, "Fehler in der Verbindung mit %s", this.getCutAddress());
if(!(throwable instanceof ClosedChannelException)) }
Log.SYSTEM.error(throwable, "Fehler in der Verbindung mit %s", this.getCutAddress());
}
this.closeChannel(comp); this.closeChannel(comp);
} }
protected void channelRead0(ChannelHandlerContext context, Packet packet) throws Exception protected void channelRead0(ChannelHandlerContext context, Packet packet) throws Exception {
{ if(this.channel.isOpen()) {
if (this.channel.isOpen()) try {
{ packet.processPacket(this.handler);
try }
{ catch(ThreadQuickExitException e) {
packet.processPacket(this.handler); ;
} }
catch (ThreadQuickExitException e) }
{ }
;
}
}
}
public void setNetHandler(NetHandler handler) public void setNetHandler(NetHandler handler) {
{ if(handler == null) {
if (handler == null) {
throw new NullPointerException("Handler ist Null"); throw new NullPointerException("Handler ist Null");
} }
// Log.debug("Setze Handler von " + this + " auf " + handler); // Log.debug("Setze Handler von " + this + " auf " + handler);
this.handler = handler; this.handler = handler;
} }
public void sendPacket(Packet packetIn) public void sendPacket(Packet packet) {
{ if(this.isChannelOpen()) {
if (this.isChannelOpen()) this.flushOutboundQueue();
{ this.dispatchPacket(packet, null);
this.flushOutboundQueue(); }
this.dispatchPacket(packetIn, null); else {
} this.lock.writeLock().lock();
else
{
this.lock.writeLock().lock();
try try {
{ this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packet, null));
this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packetIn, null)); }
} finally {
finally this.lock.writeLock().unlock();
{ }
this.lock.writeLock().unlock(); }
} }
}
}
public void sendPacket(Packet packetIn, GenericFutureListener <? extends Future <? super Void >> listener) public void sendPacket(Packet packet, GenericFutureListener<? extends Future<? super Void>> listener) {
{ if(this.isChannelOpen()) {
if (this.isChannelOpen()) this.flushOutboundQueue();
{ this.dispatchPacket(packet, new GenericFutureListener[] {listener});
this.flushOutboundQueue(); }
this.dispatchPacket(packetIn, new GenericFutureListener[] {listener}); else {
} this.lock.writeLock().lock();
else
{
this.lock.writeLock().lock();
try try {
{ this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packet, listener));
this.queue.add(new NetConnection.InboundHandlerTuplePacketListener(packetIn, listener)); }
} finally {
finally this.lock.writeLock().unlock();
{ }
this.lock.writeLock().unlock(); }
} }
}
}
private void dispatchPacket(final Packet inPacket, final GenericFutureListener <? extends Future <? super Void >> [] futureListeners) private void dispatchPacket(final Packet packet, final GenericFutureListener<? extends Future<? super Void>>[] listeners) {
{ final PacketRegistry state = PacketRegistry.getType(packet);
final PacketRegistry state = PacketRegistry.getType(inPacket); final PacketRegistry current = this.channel.attr(ATTR_STATE).get();
final PacketRegistry current = this.channel.attr(ATTR_STATE).get();
if (current != state) if(current != state) {
{
// Log.debug("Automatisches Lesen ausgeschaltet"); // Log.debug("Automatisches Lesen ausgeschaltet");
this.channel.config().setAutoRead(false); this.channel.config().setAutoRead(false);
} }
if (this.channel.eventLoop().inEventLoop()) if(this.channel.eventLoop().inEventLoop()) {
{ if(state != current) {
if (state != current) this.setConnectionState(state);
{ }
this.setConnectionState(state);
}
ChannelFuture channelfuture = this.channel.writeAndFlush(inPacket); ChannelFuture future = this.channel.writeAndFlush(packet);
if (futureListeners != null) if(listeners != null) {
{ future.addListeners(listeners);
channelfuture.addListeners(futureListeners); }
}
channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); future.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} }
else else {
{ this.channel.eventLoop().execute(new Runnable() {
this.channel.eventLoop().execute(new Runnable() public void run() {
{ if(state != current) {
public void run() NetConnection.this.setConnectionState(state);
{ }
if (state != current)
{
NetConnection.this.setConnectionState(state);
}
ChannelFuture channelfuture1 = NetConnection.this.channel.writeAndFlush(inPacket); ChannelFuture future = NetConnection.this.channel.writeAndFlush(packet);
if (futureListeners != null) if(listeners != null) {
{ future.addListeners(listeners);
channelfuture1.addListeners(futureListeners); }
}
channelfuture1.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); future.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} }
}); });
} }
} }
private void flushOutboundQueue() private void flushOutboundQueue() {
{ if(this.channel != null && this.channel.isOpen()) {
if (this.channel != null && this.channel.isOpen()) this.lock.readLock().lock();
{
this.lock.readLock().lock();
try try {
{ while(!this.queue.isEmpty()) {
while (!this.queue.isEmpty()) NetConnection.InboundHandlerTuplePacketListener entry = this.queue.poll();
{ if(entry != null) // NPE Fix
NetConnection.InboundHandlerTuplePacketListener entry = this.queue.poll(); this.dispatchPacket(entry.packet, entry.listeners);
if(entry != null) // NPE Fix }
this.dispatchPacket(entry.packet, entry.listeners); }
} finally {
} this.lock.readLock().unlock();
finally }
{ }
this.lock.readLock().unlock(); }
}
}
}
public void processReceivedPackets() public void processReceivedPackets() {
{ this.flushOutboundQueue();
this.flushOutboundQueue(); this.handler.update();
this.handler.update(); if(this.channel != null)
if(this.channel != null) this.channel.flush();
this.channel.flush(); }
}
public String getCutAddress() { public String getCutAddress() {
return this.address == null ? "?.?.*.*" : IP_REPLACER.matcher(this.address.toString()).replaceAll("$1.$2.*.*"); return this.address == null ? "?.?.*.*" : IP_REPLACER.matcher(this.address.toString()).replaceAll("$1.$2.*.*");
} }
public void closeChannel(String message) public void closeChannel(String message) {
{ if(this.channel.isOpen()) {
if (this.channel.isOpen()) this.channel.close().awaitUninterruptibly();
{ this.exitReason = message;
this.channel.close().awaitUninterruptibly(); }
this.exitReason = message; }
}
}
public boolean isChannelOpen() public boolean isChannelOpen() {
{ return this.channel != null && this.channel.isOpen();
return this.channel != null && this.channel.isOpen(); }
}
public boolean hasNoChannel() public boolean hasNoChannel() {
{ return this.channel == null;
return this.channel == null; }
}
public void disableAutoRead() public void disableAutoRead() {
{ this.channel.config().setAutoRead(false);
this.channel.config().setAutoRead(false); }
}
public void setCompressionTreshold(int treshold) public void setCompressionTreshold(int treshold) {
{ if(treshold >= 0) {
if (treshold >= 0) if(this.channel.pipeline().get("decompress") instanceof CompressionDecoder) {
{ ((CompressionDecoder)this.channel.pipeline().get("decompress")).setTreshold(treshold);
if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder) }
{ else {
((CompressionDecoder)this.channel.pipeline().get("decompress")).setTreshold(treshold); this.channel.pipeline().addBefore("decoder", "decompress", new CompressionDecoder(treshold));
} }
else
{
this.channel.pipeline().addBefore("decoder", "decompress", new CompressionDecoder(treshold));
}
if (this.channel.pipeline().get("compress") instanceof CompressionEncoder) if(this.channel.pipeline().get("compress") instanceof CompressionEncoder) {
{ ((CompressionEncoder)this.channel.pipeline().get("compress")).setTreshold(treshold);
((CompressionEncoder)this.channel.pipeline().get("compress")).setTreshold(treshold); }
} else {
else this.channel.pipeline().addBefore("encoder", "compress", new CompressionEncoder(treshold));
{ }
this.channel.pipeline().addBefore("encoder", "compress", new CompressionEncoder(treshold)); }
} else {
} if(this.channel.pipeline().get("decompress") instanceof CompressionDecoder) {
else this.channel.pipeline().remove("decompress");
{ }
if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder)
{
this.channel.pipeline().remove("decompress");
}
if (this.channel.pipeline().get("compress") instanceof CompressionEncoder) if(this.channel.pipeline().get("compress") instanceof CompressionEncoder) {
{ this.channel.pipeline().remove("compress");
this.channel.pipeline().remove("compress"); }
} }
} }
}
public void checkDisconnected() public void checkDisconnected() {
{ if(this.channel != null && !this.channel.isOpen()) {
if (this.channel != null && !this.channel.isOpen()) if(!this.disconnected) {
{ this.disconnected = true;
if (!this.disconnected) if(this.handler != null)
{ this.handler.onDisconnect(this.exitReason != null ? this.exitReason : "Verbindung getrennt");
this.disconnected = true; }
if(this.handler != null) else {
this.handler.onDisconnect(this.exitReason != null ? this.exitReason : "Verbindung getrennt"); Log.JNI.warn("handleDisconnection() zweifach aufgerufen");
} }
else }
{ }
Log.JNI.warn("handleDisconnection() zweifach aufgerufen");
}
}
}
public void startEncryption(SecretKey key) { public void startEncryption(SecretKey key) {
this.channel.pipeline().addBefore("splitter", "decrypt", new EncryptionDecoder(EncryptUtil.createCipher(Cipher.DECRYPT_MODE, key))); this.channel.pipeline().addBefore("splitter", "decrypt", new EncryptionDecoder(EncryptUtil.createCipher(Cipher.DECRYPT_MODE, key)));
this.channel.pipeline().addBefore("prepender", "encrypt", new EncryptionEncoder(EncryptUtil.createCipher(Cipher.ENCRYPT_MODE, key))); this.channel.pipeline().addBefore("prepender", "encrypt", new EncryptionEncoder(EncryptUtil.createCipher(Cipher.ENCRYPT_MODE, key)));
} }
private static class InboundHandlerTuplePacketListener private static class InboundHandlerTuplePacketListener {
{ private final Packet packet;
private final Packet packet; private final GenericFutureListener<? extends Future<? super Void>>[] listeners;
private final GenericFutureListener <? extends Future <? super Void >> [] listeners;
public InboundHandlerTuplePacketListener(Packet packet, GenericFutureListener <? extends Future <? super Void >> listener) public InboundHandlerTuplePacketListener(Packet packet, GenericFutureListener<? extends Future<? super Void>> listener) {
{ this.packet = packet;
this.packet = packet; this.listeners = listener == null ? null : new GenericFutureListener[] {listener};
this.listeners = listener == null ? null : new GenericFutureListener[] {listener}; }
} }
}
} }

View file

@ -95,8 +95,7 @@ import common.packet.SPacketTrades;
import common.packet.SPacketUpdateHealth; import common.packet.SPacketUpdateHealth;
import common.packet.SPacketWorld; import common.packet.SPacketWorld;
public enum PacketRegistry public enum PacketRegistry {
{
HANDSHAKE {{ HANDSHAKE {{
this.client(HPacketHandshake.class); this.client(HPacketHandshake.class);
}}, }},