mirror of
https://github.com/diamante0018/ServerList.git
synced 2025-04-20 03:15:42 +00:00
feat: update 2025 (I love Java)
This commit is contained in:
parent
2416ef2d54
commit
b7e3d82b51
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Diamante
|
* Copyright (C) 2025 Diamante
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Diamante
|
* Copyright (C) 2025 Diamante
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Diamante
|
* Copyright (C) 2025 Diamante
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -31,7 +31,7 @@ import org.apache.commons.cli.ParseException;
|
|||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
private enum Mode {
|
private enum Mode {
|
||||||
Emulator, Master, MasterPing, Bad;
|
Emulator, Master, MasterPing, ServerPing, Bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mode mode;
|
private Mode mode;
|
||||||
@ -66,6 +66,7 @@ public class Main {
|
|||||||
var master = new Option("master", "master server mode");
|
var master = new Option("master", "master server mode");
|
||||||
var emulator = new Option("emulator", "client emulator mode");
|
var emulator = new Option("emulator", "client emulator mode");
|
||||||
var masterPing = new Option("master_ping", "ping the master server");
|
var masterPing = new Option("master_ping", "ping the master server");
|
||||||
|
var serverPing = new Option("server_ping", "ping the master server as a server");
|
||||||
|
|
||||||
var ping = Option.builder("ping")
|
var ping = Option.builder("ping")
|
||||||
.argName("IP:Port")
|
.argName("IP:Port")
|
||||||
@ -76,6 +77,7 @@ public class Main {
|
|||||||
options.addOption(master);
|
options.addOption(master);
|
||||||
options.addOption(emulator);
|
options.addOption(emulator);
|
||||||
options.addOption(masterPing);
|
options.addOption(masterPing);
|
||||||
|
options.addOption(serverPing);
|
||||||
options.addOption(ping);
|
options.addOption(ping);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
@ -103,6 +105,8 @@ public class Main {
|
|||||||
main.setMode(Mode.Emulator);
|
main.setMode(Mode.Emulator);
|
||||||
} else if (line.hasOption("master_ping")) {
|
} else if (line.hasOption("master_ping")) {
|
||||||
main.setMode(Mode.MasterPing);
|
main.setMode(Mode.MasterPing);
|
||||||
|
} else if (line.hasOption("server_ping")) {
|
||||||
|
main.setMode(Mode.ServerPing);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.hasOption("ping")) {
|
if (line.hasOption("ping")) {
|
||||||
@ -127,6 +131,9 @@ public class Main {
|
|||||||
var ping = new MasterServerPinger();
|
var ping = new MasterServerPinger();
|
||||||
ping.pingMaster();
|
ping.pingMaster();
|
||||||
ping.readReplyFromMaster();
|
ping.readReplyFromMaster();
|
||||||
|
} else if (main.getMode() == Mode.ServerPing) {
|
||||||
|
var ping = new ServerEmulator();
|
||||||
|
ping.pingLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Normal shutdown");
|
System.out.println("Normal shutdown");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Diamante
|
* Copyright (C) 2025 Diamante
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Diamante
|
* Copyright (C) 2025 Diamante
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -29,16 +29,15 @@ import java.net.UnknownHostException;
|
|||||||
*/
|
*/
|
||||||
public class MasterServerPinger {
|
public class MasterServerPinger {
|
||||||
|
|
||||||
private static final String MASTER = "mw3.totalkillaz.ovh";
|
private static final String OFFICIAL_MASTER = "mw3.totalkillaz.ovh";
|
||||||
|
private static final String LAN_MASTER = "127.0.0.1";
|
||||||
private static final int MASTER_PORT = 27017;
|
private static final int MASTER_PORT = 27017;
|
||||||
|
|
||||||
private static final int CLIENT_VERSION = 17039893;
|
|
||||||
|
|
||||||
private Socket clientSocket;
|
private Socket clientSocket;
|
||||||
|
|
||||||
public void pingMaster() {
|
public void pingMaster() {
|
||||||
try {
|
try {
|
||||||
clientSocket = new Socket(MASTER, MASTER_PORT);
|
clientSocket = new Socket(OFFICIAL_MASTER, MASTER_PORT);
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
System.err.println("IOException: Failed to open a socket");
|
System.err.println("IOException: Failed to open a socket");
|
||||||
@ -50,7 +49,7 @@ public class MasterServerPinger {
|
|||||||
var data = new byte[8];
|
var data = new byte[8];
|
||||||
|
|
||||||
var magicLE = Utils.longSwap(Utils.NEW_CLIENT_MAGIC);
|
var magicLE = Utils.longSwap(Utils.NEW_CLIENT_MAGIC);
|
||||||
var versionLE = Utils.longSwap(CLIENT_VERSION);
|
var versionLE = Utils.longSwap(Utils.CLIENT_VERSION);
|
||||||
|
|
||||||
System.arraycopy(magicLE, 0, data, 0, 4);
|
System.arraycopy(magicLE, 0, data, 0, 4);
|
||||||
System.arraycopy(versionLE, 0, data, 4, 4);
|
System.arraycopy(versionLE, 0, data, 4, 4);
|
||||||
@ -66,18 +65,33 @@ public class MasterServerPinger {
|
|||||||
var out = new ByteArrayOutputStream();
|
var out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
System.out.println("readReplyFromMaster: awaiting reply from master server");
|
||||||
var input = clientSocket.getInputStream();
|
var input = clientSocket.getInputStream();
|
||||||
|
System.out.println("readReplyFromMaster: finished waiting for a reply from master server");
|
||||||
var bytes = new byte[0x1000 * 0x6 + 0x4];
|
var bytes = new byte[0x1000 * 0x6 + 0x4];
|
||||||
|
|
||||||
int count;
|
int count = input.read(bytes);
|
||||||
while ((count = input.read(bytes)) > 0) {
|
|
||||||
out.write(bytes, 0, count);
|
out.write(bytes, 0, count);
|
||||||
}
|
|
||||||
|
System.out.println("readReplyFromMaster: finished reading bytes from socket");
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
System.err.println("IOException: Failed to read from a socket");
|
System.err.println("IOException: Failed to read from a socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (out.size() == 0) {
|
||||||
|
System.out.println("readReplyFromMaster: got no reply");
|
||||||
|
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
System.err.println("readReplyFromMaster: IOException in out.close()");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var bytes = out.toByteArray();
|
var bytes = out.toByteArray();
|
||||||
|
|
||||||
var serverCountLE = new byte[4];
|
var serverCountLE = new byte[4];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Diamante
|
* Copyright (C) 2025 Diamante
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
124
src/main/java/com/diamante/serverlist/ServerEmulator.java
Normal file
124
src/main/java/com/diamante/serverlist/ServerEmulator.java
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Diamante
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.diamante.serverlist;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Diamante
|
||||||
|
*/
|
||||||
|
public class ServerEmulator {
|
||||||
|
|
||||||
|
private static final String OFFICIAL_MASTER = "mw3.totalkillaz.ovh";
|
||||||
|
|
||||||
|
private Socket socket;
|
||||||
|
|
||||||
|
private int currentPort;
|
||||||
|
|
||||||
|
private boolean valid;
|
||||||
|
|
||||||
|
public ServerEmulator() {
|
||||||
|
try {
|
||||||
|
var ip = InetAddress.getByName(OFFICIAL_MASTER);
|
||||||
|
socket = new Socket(ip, MasterServer.PORT);
|
||||||
|
currentPort = 0;
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
catch (UnknownHostException ex) {
|
||||||
|
valid = false;
|
||||||
|
System.err.println("ServerEmulator: UnknownHostException in InetAddress.getByName()");
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
valid = false;
|
||||||
|
System.err.println("ServerEmulator: IOException in new Socket()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pingMasterServer(int port, OutputStream out) {
|
||||||
|
var request = new byte[Utils.PACKET_SERVERT_LEN];
|
||||||
|
|
||||||
|
var magicLE = Utils.longSwap(Utils.OLD_SERVER_MAGIC);
|
||||||
|
var versionLE = Utils.longSwap(Utils.CLIENT_VERSION);
|
||||||
|
var portLE = Utils.longSwap(port);
|
||||||
|
|
||||||
|
System.arraycopy(magicLE, 0, request, 0, 4);
|
||||||
|
System.arraycopy(versionLE, 0, request, 4, 4);
|
||||||
|
// Write only two bytes for the port
|
||||||
|
System.arraycopy(portLE, 0, request, 8, 2);
|
||||||
|
|
||||||
|
try {
|
||||||
|
out.write(request);
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
System.err.println("pingMasterServer: IOException in out.write()");
|
||||||
|
setValid(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pingLoop() {
|
||||||
|
while (Main.running.get() && isValid()) {
|
||||||
|
var port = currentPort;
|
||||||
|
currentPort = (currentPort + 1) % 65535;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var out = socket.getOutputStream();
|
||||||
|
pingMasterServer(port, out);
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
System.err.println("pingLoop: IOException in socket.getOutputStream()");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(80);
|
||||||
|
}
|
||||||
|
catch (InterruptedException ex) {
|
||||||
|
setValid(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
// Can happen if multiple instances are launched
|
||||||
|
if (socket == null || socket.isClosed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
System.err.println("stop: IOException in socket.close()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValid(boolean valid) {
|
||||||
|
this.valid = valid;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Diamante
|
* Copyright (C) 2025 Diamante
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -38,12 +38,13 @@ public class Utils {
|
|||||||
public static final int PACKET_SERVERT_LEN = 10;
|
public static final int PACKET_SERVERT_LEN = 10;
|
||||||
|
|
||||||
// (Warning: Remember to take into account endianness)
|
// (Warning: Remember to take into account endianness)
|
||||||
// 2023 Update: They magic was changed, client and server were switched (HELP & THEM)
|
// 2023 Update: They magic was changed
|
||||||
public static final int OLD_SERVER_MAGIC = 1212501072;
|
public static final int OLD_SERVER_MAGIC = 1212501072; // HELP
|
||||||
public static final int NEW_SERVER_MAGIC = 1414022477;
|
|
||||||
|
|
||||||
public static final int OLD_CLIENT_MAGIC = 1414022477;
|
public static final int OLD_CLIENT_MAGIC = 1414022477; // THEM
|
||||||
public static final int NEW_CLIENT_MAGIC = 1212501072;
|
public static final int NEW_CLIENT_MAGIC = 1129268293;
|
||||||
|
|
||||||
|
public static final int CLIENT_VERSION = 17039893;
|
||||||
|
|
||||||
public static boolean isServerMagic(int magic) {
|
public static boolean isServerMagic(int magic) {
|
||||||
return magic == OLD_SERVER_MAGIC;
|
return magic == OLD_SERVER_MAGIC;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user