File size: 4,047 Bytes
d46f4a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package net.minecraft.client.server;

import com.google.common.collect.Lists;
import com.mojang.logging.LogUtils;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
import net.minecraft.DefaultUncaughtExceptionHandler;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.slf4j.Logger;

@OnlyIn(Dist.CLIENT)
public class LanServerDetection {
    static final AtomicInteger UNIQUE_THREAD_ID = new AtomicInteger(0);
    static final Logger LOGGER = LogUtils.getLogger();

    @OnlyIn(Dist.CLIENT)
    public static class LanServerDetector extends Thread {
        private final LanServerDetection.LanServerList serverList;
        private final InetAddress pingGroup;
        private final MulticastSocket socket;

        public LanServerDetector(LanServerDetection.LanServerList p_120090_) throws IOException {
            super("LanServerDetector #" + LanServerDetection.UNIQUE_THREAD_ID.incrementAndGet());
            this.serverList = p_120090_;
            this.setDaemon(true);
            this.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LanServerDetection.LOGGER));
            this.socket = new MulticastSocket(4445);
            this.pingGroup = InetAddress.getByName("224.0.2.60");
            this.socket.setSoTimeout(5000);
            this.socket.joinGroup(this.pingGroup);
        }

        @Override
        public void run() {
            byte[] abyte = new byte[1024];

            while (!this.isInterrupted()) {
                DatagramPacket datagrampacket = new DatagramPacket(abyte, abyte.length);

                try {
                    this.socket.receive(datagrampacket);
                } catch (SocketTimeoutException sockettimeoutexception) {
                    continue;
                } catch (IOException ioexception1) {
                    LanServerDetection.LOGGER.error("Couldn't ping server", (Throwable)ioexception1);
                    break;
                }

                String s = new String(datagrampacket.getData(), datagrampacket.getOffset(), datagrampacket.getLength(), StandardCharsets.UTF_8);
                LanServerDetection.LOGGER.debug("{}: {}", datagrampacket.getAddress(), s);
                this.serverList.addServer(s, datagrampacket.getAddress());
            }

            try {
                this.socket.leaveGroup(this.pingGroup);
            } catch (IOException ioexception) {
            }

            this.socket.close();
        }
    }

    @OnlyIn(Dist.CLIENT)
    public static class LanServerList {
        private final List<LanServer> servers = Lists.newArrayList();
        private boolean isDirty;

        @Nullable
        public synchronized List<LanServer> takeDirtyServers() {
            if (this.isDirty) {
                List<LanServer> list = List.copyOf(this.servers);
                this.isDirty = false;
                return list;
            } else {
                return null;
            }
        }

        public synchronized void addServer(String p_120097_, InetAddress p_120098_) {
            String s = LanServerPinger.parseMotd(p_120097_);
            String s1 = LanServerPinger.parseAddress(p_120097_);
            if (s1 != null) {
                s1 = p_120098_.getHostAddress() + ":" + s1;
                boolean flag = false;

                for (LanServer lanserver : this.servers) {
                    if (lanserver.getAddress().equals(s1)) {
                        lanserver.updatePingTime();
                        flag = true;
                        break;
                    }
                }

                if (!flag) {
                    this.servers.add(new LanServer(s, s1));
                    this.isDirty = true;
                }
            }
        }
    }
}