LANDiscoveryThread class

Пакет: com.hypixel.hytale.builtin.landiscovery

Файл: com/hypixel/hytale/builtin/landiscovery/LANDiscoveryThread.java

extends: Thread

Поля (19)

МодификаторыТипИмя
final byte[] REPLY_HEADER
continue
String var1
var1
InetAddress var10
LANDiscoveryThread.ReplyPacket var11
var11
var11
StructLayout var2
byte[] var2
byte[] var3
LANDiscoveryThread.ReplyPacket var3
MemorySegment var4
LANDiscoveryThread.ReplyPacket var4
int var5
byte[] var6
DatagramPacket var7
DatagramPacket var8
InetSocketAddress var9

Методы (8)

МодификаторыВозвратСигнатура
private record ReplyPacketrecord ReplyPacket(byte[] bytes, MemorySegment segment, long addressOffset, long portOffset, long playerCountOffset, long maxPlayersOffset)
static LANDiscoveryThread.ReplyPacket createReplyPacketLANDiscoveryThread.ReplyPacket createReplyPacket(int var0, byte[] var1)
public MulticastSocket getSocketMulticastSocket getSocket()
if if(var9 != null)
if if(var10 instanceof Inet4Address)
if if(this.socket != null)
abstract super super("LAN Discovery Listener")
void writevoid write(byte[] var1, int var2, int var3, int var4)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.landiscovery;

class="kw">import com.hypixel.hytale.common.util.ArrayUtil;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.server.core.HytaleServer;
class="kw">import com.hypixel.hytale.server.core.io.ServerManager;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
class="kw">import com.hypixel.hytale.server.core.util.io.MemorySegmentUtil;
class="kw">import java.lang.foreign.MemoryLayout;
class="kw">import java.lang.foreign.MemorySegment;
class="kw">import java.lang.foreign.StructLayout;
class="kw">import java.lang.foreign.ValueLayout;
class="kw">import java.lang.foreign.MemoryLayout.PathElement;
class="kw">import java.net.DatagramPacket;
class="kw">import java.net.Inet4Address;
class="kw">import java.net.Inet6Address;
class="kw">import java.net.InetAddress;
class="kw">import java.net.InetSocketAddress;
class="kw">import java.net.MulticastSocket;
class="kw">import java.net.SocketException;
class="kw">import java.nio.charset.StandardCharsets;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;

class LANDiscoveryThread class="kw">extends Thread {
   class="kw">private class="kw">static class="kw">final byte[] REPLY_HEADER = "HYTALE_DISCOVER_REPLY".getBytes(StandardCharsets.US_ASCII);
   class="kw">private class="kw">static class="kw">final byte[] REQUEST_HEADER = "HYTALE_DISCOVER_REQUEST".getBytes(StandardCharsets.US_ASCII);
   class="kw">public class="kw">static class="kw">final int LAN_DISCOVERY_PORT = 5510;
   @Nonnull
   class="kw">private class="kw">final HytaleLogger LOGGER;
   class="kw">private MulticastSocket socket;

   class="kw">public LANDiscoveryThread() {
      super("LAN Discovery Listener");
      this.setDaemon(true);
      this.LOGGER = LANDiscoveryPlugin.get().getLogger();
   }

   class="kw">private class="kw">static LANDiscoveryThread.ReplyPacket createReplyPacket(int var0, byte[] var1) {
      StructLayout var2 = MemoryLayout.structLayout(
         MemoryLayout.sequenceLayout(REPLY_HEADER.length, ValueLayout.JAVA_BYTE).withName("header"),
         ValueLayout.JAVA_BYTE.withName("separator"),
         ValueLayout.JAVA_BYTE.withName("addrType"),
         MemoryLayout.sequenceLayout(var0, ValueLayout.JAVA_BYTE).withName("address"),
         MemorySegmentUtil.SHORT_LE.withName("port"),
         MemorySegmentUtil.SHORT_LE.withName("nameLength"),
         MemoryLayout.sequenceLayout(var1.length, ValueLayout.JAVA_BYTE).withName("name"),
         MemorySegmentUtil.INT_LE.withName("playerCount"),
         MemorySegmentUtil.INT_LE.withName("maxPlayers")
      );
      byte[] var3 = new byte[(int)var2.byteSize()];
      MemorySegment var4 = MemorySegment.ofArray(var3);
      MemorySegment.copy(REPLY_HEADER, 0, var4, ValueLayout.JAVA_BYTE, 0L, REPLY_HEADER.length);
      var4.set(ValueLayout.JAVA_BYTE, var2.byteOffset(PathElement.groupElement("addrType")), (byte)var0);
      var4.set(MemorySegmentUtil.SHORT_LE, var2.byteOffset(PathElement.groupElement("nameLength")), (short)var1.length);
      MemorySegment.copy(var1, 0, var4, ValueLayout.JAVA_BYTE, var2.byteOffset(PathElement.groupElement("name")), var1.length);
      class="kw">return new LANDiscoveryThread.ReplyPacket(
         var3,
         var4,
         var2.byteOffset(PathElement.groupElement("address")),
         var2.byteOffset(PathElement.groupElement("port")),
         var2.byteOffset(PathElement.groupElement("playerCount")),
         var2.byteOffset(PathElement.groupElement("maxPlayers"))
      );
   }

   @Override
   class="kw">public void run() {
      try {
         this.socket = new MulticastSocket(5510);
         this.socket.setBroadcast(true);
         this.LOGGER.at(Level.INFO).log("Bound to UDP 0.0.0.0:5510 for LAN discovery");
         String var1 = HytaleServer.get().getServerName();
         if (var1.length() > 16377) {
            var1 = var1.substring(0, 16377) + "...";
         }

         byte[] var2 = var1.getBytes(StandardCharsets.UTF_8);
         LANDiscoveryThread.ReplyPacket var3 = createReplyPacket(4, var2);
         LANDiscoveryThread.ReplyPacket var4 = createReplyPacket(16, var2);
         int var5 = HytaleServer.get().getConfig().getMaxPlayers();
         byte[] var6 = new byte[15000];
         DatagramPacket var7 = new DatagramPacket(var6, var6.length);
         DatagramPacket var8 = new DatagramPacket(new byte[0], 0);

         while (!this.isInterrupted()) {
            this.socket.receive(var7);
            if (ArrayUtil.startsWith(var7.getData(), REQUEST_HEADER)) {
               InetSocketAddress var9 = ServerManager.get().getNonLoopbackAddress();
               if (var9 != null) {
                  InetAddress var10 = var9.getAddress();
                  if (var10 != null && !var10.isLoopbackAddress()) {
                     LANDiscoveryThread.ReplyPacket var11;
                     if (var10 class="kw">instanceof Inet4Address) {
                        var11 = var3;
                     } else {
                        if (!(var10 class="kw">instanceof Inet6Address)) {
                           this.LOGGER.at(Level.WARNING).log("Unrecognized target address class %s: %s", var10.getClass(), var10);
                           class="kw">continue;
                        }

                        var11 = var4;
                     }

                     var11.write(var10.getAddress(), var9.getPort(), Universe.get().getPlayerCount(), Math.max(var5, 0));
                     var8.setData(var11.bytes());
                     var8.setSocketAddress(var7.getSocketAddress());
                     this.socket.send(var8);
                     this.LOGGER.at(Level.FINE).log("Was discovered by %s:%d", var7.getAddress(), var7.getPort());
                  } else {
                     this.LOGGER.at(Level.WARNING).log("No class="kw">public address to send as response!");
                  }
               }
            }
         }
      } catch (SocketException var16) {
         if (!"Socket closed".equalsIgnoreCase(var16.getMessage()) && !"Socket is closed".equalsIgnoreCase(var16.getMessage())) {
            ((HytaleLogger.Api)this.LOGGER.at(Level.SEVERE).withCause(var16)).log("Exception in lan discovery listener:");
         }
      } catch (Throwable var17) {
         ((HytaleLogger.Api)this.LOGGER.at(Level.SEVERE).withCause(var17)).log("Exception in lan discovery listener:");
      } class="kw">finally {
         if (this.socket != null) {
            this.socket.close();
         }
      }

      this.LOGGER.at(Level.INFO).log("Stopped listing on UDP 0.0.0.0:5510 for LAN discovery");
   }

   class="kw">public MulticastSocket getSocket() {
      class="kw">return this.socket;
   }

   class="kw">private record ReplyPacket(byte[] bytes, MemorySegment segment, long addressOffset, long portOffset, long playerCountOffset, long maxPlayersOffset) {
      class="kw">private ReplyPacket {
      }

      void write(byte[] var1, int var2, int var3, int var4) {
         MemorySegment.copy(var1, 0, this.segment, ValueLayout.JAVA_BYTE, this.addressOffset, var1.length);
         this.segment.set(MemorySegmentUtil.SHORT_LE, this.portOffset, (short)var2);
         this.segment.set(MemorySegmentUtil.INT_LE, this.playerCountOffset, var3);
         this.segment.set(MemorySegmentUtil.INT_LE, this.maxPlayersOffset, var4);
      }
   }
}