mirror of
https://github.com/ayunami2000/ayungee.git
synced 2024-12-30 02:14:11 -08:00
ADD BUILT-IN AUTHENTICATION :D:D:D
who doesn't like more proprietary file formats?????????
This commit is contained in:
parent
5e5e54dde1
commit
c704c49162
|
@ -1,11 +1,13 @@
|
|||
# ayungee
|
||||
|
||||
lightweight bungeecord alternative for eaglercraft servers running protocolsupport
|
||||
~~lightweight~~ bungeecord alternative for eaglercraft servers running protocolsupport
|
||||
|
||||
now contains an optional **login system**!! :D
|
||||
|
||||
Thanks to LAX1DUDE and md-5 for very small snippets of EaglerBungee used in this project (specifically for the server icon, skins, & entity remapping)
|
||||
|
||||
**TODO: built-in auth system & more bungee backwards compatibility**
|
||||
**TODO: more bungee backwards compatibility, a few more kick messages/reasons, scoreboard & tab clearing, & automatic java player skins**
|
||||
|
||||
|
||||
|
||||
**if you have questions about the license, please, reach out to me. i just put the license i put on most of my projects on this, but if you have a problem with it, let me know.
|
||||
**if you have questions about the license, please, reach out to me. i just put the license i put on most of my projects on this, but if you have a problem with it, **let me know**.
|
5
pom.xml
5
pom.xml
|
@ -29,6 +29,11 @@
|
|||
<artifactId>json-simple</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.mkammerer</groupId>
|
||||
<artifactId>argon2-jvm</artifactId>
|
||||
<version>2.11</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
118
src/main/java/me/ayunami2000/ayungee/Auth.java
Normal file
118
src/main/java/me/ayunami2000/ayungee/Auth.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
package me.ayunami2000.ayungee;
|
||||
|
||||
import de.mkammerer.argon2.Argon2;
|
||||
import de.mkammerer.argon2.Argon2Factory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
public class Auth {
|
||||
private static class AuthData {
|
||||
public String passHash;
|
||||
public Set<String> ips;
|
||||
|
||||
public AuthData(String p, Set<String> i) {
|
||||
passHash = p;
|
||||
ips = i;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Argon2 argon2 = Argon2Factory.create(Argon2Factory.Argon2Types.ARGON2id);
|
||||
|
||||
private static Map<String, AuthData> database = new HashMap<>();
|
||||
|
||||
public static boolean register(String username, char[] password, String ip) {
|
||||
AuthData authData = database.get(username);
|
||||
if (authData != null) return false;
|
||||
if (isIpAtTheLimit(ip)) return false;
|
||||
String hash = argon2.hash(10, 65536, 1, password);
|
||||
Set<String> initIps = new HashSet<>();
|
||||
initIps.add(ip);
|
||||
database.put(username, new AuthData(hash, initIps));
|
||||
writeDatabase();
|
||||
return true;
|
||||
// todo: registering & packet cancellation
|
||||
}
|
||||
|
||||
public static boolean isRegistered(String username) {
|
||||
return database.containsKey(username);
|
||||
}
|
||||
|
||||
public static boolean changePass(String username, char[] password) {
|
||||
AuthData authData = database.get(username);
|
||||
authData.passHash = argon2.hash(10, 65536, 1, password);
|
||||
writeDatabase();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean login(String username, char[] password) {
|
||||
AuthData authData = database.get(username);
|
||||
if (authData == null) return false;
|
||||
return argon2.verify(authData.passHash, password);
|
||||
}
|
||||
|
||||
private static boolean isIpAtTheLimit(String ip) {
|
||||
if (Main.authIpLimit <= 0) return false;
|
||||
Map<String, AuthData> cache = new HashMap<>(database);
|
||||
int num = 0;
|
||||
for (AuthData authData : cache.values()) {
|
||||
if (authData.ips.contains(ip)) num++;
|
||||
if (num >= Main.authIpLimit) {
|
||||
cache.clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
cache.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// only use once, on load
|
||||
public static void readDatabase() {
|
||||
try {
|
||||
File authFile = new File("auth.uwu");
|
||||
if (!authFile.exists()) authFile.createNewFile();
|
||||
|
||||
Map<String, AuthData> cache = new HashMap<>();
|
||||
|
||||
String[] lines = new String(Files.readAllBytes(authFile.toPath())).trim().split("\n");
|
||||
if (lines.length == 1 && lines[0].isEmpty()) return;
|
||||
for (String line : lines) {
|
||||
String[] pieces = line.split("\u0000");
|
||||
cache.put(pieces[0], new AuthData(pieces[2], new HashSet<>(Arrays.asList(pieces[1].split("§")))));
|
||||
}
|
||||
|
||||
database.clear();
|
||||
database.putAll(cache);
|
||||
cache.clear();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeDatabase() {
|
||||
StringBuilder out = new StringBuilder();
|
||||
|
||||
Map<String, AuthData> cache = new HashMap<>(database);
|
||||
|
||||
for (String username : cache.keySet()) {
|
||||
AuthData entry = cache.get(username);
|
||||
out.append(username);
|
||||
out.append("\u0000");
|
||||
out.append(String.join("§", entry.ips));
|
||||
out.append("\u0000");
|
||||
out.append(entry.passHash);
|
||||
out.append("\n");
|
||||
}
|
||||
|
||||
cache.clear();
|
||||
|
||||
try {
|
||||
Files.write(Paths.get("auth.uwu"), out.toString().getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package me.ayunami2000.ayungee;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ChatHandler {
|
||||
|
@ -14,9 +13,15 @@ public class ChatHandler {
|
|||
if (!message.startsWith("/")) return false;
|
||||
int ind = message.indexOf(' ');
|
||||
String commandBase = message.substring(1, ind != -1 ? ind : message.length()).toLowerCase();
|
||||
String args = ind != -1 ? message.substring(ind + 1) : "";
|
||||
String args = ind == -1 ? "" : message.substring(ind + 1);
|
||||
int ind2 = args.indexOf(' ');
|
||||
// todo: make it an array at this point dumbass
|
||||
String firstArg = ind2 == -1 ? args : args.substring(0, ind);
|
||||
String secondArg = args.substring(firstArg.length());
|
||||
switch (commandBase) {
|
||||
case "server":
|
||||
if (!client.authed) return false;
|
||||
|
||||
if (args.isEmpty()) {
|
||||
//usage msg
|
||||
client.conn.send(new byte[] { 3, 0, 25, 0, (byte) 167, 0, 57, 0, 85, 0, 115, 0, 97, 0, 103, 0, 101, 0, 58, 0, 32, 0, 47, 0, 115, 0, 101, 0, 114, 0, 118, 0, 101, 0, 114, 0, 32, 0, 60, 0, 110, 0, 117, 0, 109, 0, 98, 0, 101, 0, 114, 0, 62 });
|
||||
|
@ -30,14 +35,70 @@ public class ChatHandler {
|
|||
}
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case "register":
|
||||
|
||||
case "reg":
|
||||
if (!Main.useAuth) return false;
|
||||
if (client.authed) return false;
|
||||
if (firstArg.isEmpty()) {
|
||||
client.conn.send(new byte[] { 3, 0, 30, 0, (byte) 167, 0, 57, 0, 89, 0, 111, 0, 117, 0, 32, 0, 109, 0, 117, 0, 115, 0, 116, 0, 32, 0, 115, 0, 112, 0, 101, 0, 99, 0, 105, 0, 102, 0, 121, 0, 32, 0, 97, 0, 32, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 46 });
|
||||
return true;
|
||||
}
|
||||
if (!firstArg.equals(secondArg)) {
|
||||
client.conn.send(new byte[] { 3, 0, 31, 0, (byte) 167, 0, 57, 0, 84, 0, 104, 0, 111, 0, 115, 0, 101, 0, 32, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 115, 0, 32, 0, 100, 0, 111, 0, 32, 0, 110, 0, 111, 0, 116, 0, 32, 0, 109, 0, 97, 0, 116, 0, 99, 0, 104, 0, 33 });
|
||||
return true;
|
||||
}
|
||||
if (Auth.register(client.username, firstArg.toCharArray(), Main.getIp(client.conn))) {
|
||||
Main.printMsg("Player " + client + " registered successfully!");
|
||||
client.authed = true;
|
||||
client.server = -1;
|
||||
} else {
|
||||
client.conn.send(new byte[] { (byte) 255, 0, 38, 0, (byte) 167, 0, 57, 0, 84, 0, 104, 0, 105, 0, 115, 0, 32, 0, 117, 0, 115, 0, 101, 0, 114, 0, 110, 0, 97, 0, 109, 0, 101, 0, 32, 0, 105, 0, 115, 0, 32, 0, 97, 0, 108, 0, 114, 0, 101, 0, 97, 0, 100, 0, 121, 0, 32, 0, 114, 0, 101, 0, 103, 0, 105, 0, 115, 0, 116, 0, 101, 0, 114, 0, 101, 0, 100, 0, 33 });
|
||||
client.conn.close();
|
||||
}
|
||||
break;
|
||||
case "login":
|
||||
|
||||
case "l":
|
||||
if (!Main.useAuth) return false;
|
||||
if (client.authed) return false;
|
||||
if (firstArg.isEmpty()) {
|
||||
client.conn.send(new byte[] { 3, 0, 30, 0, (byte) 167, 0, 57, 0, 89, 0, 111, 0, 117, 0, 32, 0, 109, 0, 117, 0, 115, 0, 116, 0, 32, 0, 115, 0, 112, 0, 101, 0, 99, 0, 105, 0, 102, 0, 121, 0, 32, 0, 97, 0, 32, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 46 });
|
||||
return true;
|
||||
}
|
||||
if (Auth.login(client.username, firstArg.toCharArray())) {
|
||||
Main.printMsg("Player " + client + " logged in!");
|
||||
client.authed = true;
|
||||
} else {
|
||||
client.conn.send(new byte[] { (byte) 255, 0, 29, 0, (byte) 167, 0, 57, 0, 84, 0, 104, 0, 97, 0, 116, 0, 32, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 32, 0, 105, 0, 115, 0, 32, 0, 105, 0, 110, 0, 99, 0, 111, 0, 114, 0, 114, 0, 101, 0, 99, 0, 116, 0, 33 });
|
||||
client.conn.close();
|
||||
}
|
||||
break;
|
||||
case "changepass":
|
||||
case "changepassword":
|
||||
case "changeepasswd":
|
||||
case "changepwd":
|
||||
case "changepw":
|
||||
if (!Main.useAuth) return false;
|
||||
if (!client.authed) return false;
|
||||
if (firstArg.isEmpty() || secondArg.isEmpty()) {
|
||||
client.conn.send(new byte[] { 3, 0, 63, 0, (byte) 167, 0, 57, 0, 80, 0, 108, 0, 101, 0, 97, 0, 115, 0, 101, 0, 32, 0, 115, 0, 112, 0, 101, 0, 99, 0, 105, 0, 102, 0, 121, 0, 32, 0, 116, 0, 104, 0, 101, 0, 32, 0, 111, 0, 108, 0, 100, 0, 32, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 32, 0, 102, 0, 111, 0, 108, 0, 108, 0, 111, 0, 119, 0, 101, 0, 100, 0, 32, 0, 98, 0, 121, 0, 32, 0, 116, 0, 104, 0, 101, 0, 32, 0, 110, 0, 101, 0, 119, 0, 32, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 33 });
|
||||
return true;
|
||||
}
|
||||
if (!Auth.isRegistered(client.username)) {
|
||||
// register first...
|
||||
client.conn.send(new byte[] { 3, 0, 60, 0, (byte) 167, 0, 57, 0, 89, 0, 111, 0, 117, 0, 32, 0, 109, 0, 117, 0, 115, 0, 116, 0, 32, 0, 114, 0, 101, 0, 103, 0, 105, 0, 115, 0, 116, 0, 101, 0, 114, 0, 32, 0, 97, 0, 110, 0, 32, 0, 97, 0, 99, 0, 99, 0, 111, 0, 117, 0, 110, 0, 116, 0, 32, 0, 102, 0, 105, 0, 114, 0, 115, 0, 116, 0, 32, 0, 116, 0, 111, 0, 32, 0, 99, 0, 104, 0, 97, 0, 110, 0, 103, 0, 101, 0, 32, 0, 105, 0, 116, 0, 115, 0, 32, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 33 });
|
||||
return true;
|
||||
}
|
||||
if (!Auth.login(client.username, firstArg.toCharArray())) {
|
||||
// invalid old password
|
||||
client.conn.send(new byte[] { 3, 0, 29, 0, (byte) 167, 0, 57, 0, 84, 0, 104, 0, 97, 0, 116, 0, 32, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 32, 0, 105, 0, 115, 0, 32, 0, 105, 0, 110, 0, 99, 0, 111, 0, 114, 0, 114, 0, 101, 0, 99, 0, 116, 0, 33 });
|
||||
return true;
|
||||
}
|
||||
if (Auth.changePass(client.username, secondArg.toCharArray())) {
|
||||
// changed password!
|
||||
Main.printMsg("Player " + client + " changed their password!");
|
||||
client.conn.send(new byte[] { 3, 0, 33, 0, (byte) 167, 0, 57, 0, 89, 0, 111, 0, 117, 0, 114, 0, 32, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 32, 0, 104, 0, 97, 0, 115, 0, 32, 0, 98, 0, 101, 0, 101, 0, 110, 0, 32, 0, 99, 0, 104, 0, 97, 0, 110, 0, 103, 0, 101, 0, 100, 0, 33 });
|
||||
}
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -28,9 +28,14 @@ public class Client {
|
|||
|
||||
public boolean hasLoginHappened = false;
|
||||
|
||||
public boolean authed = !Main.useAuth;
|
||||
|
||||
public int clientEntityId;
|
||||
public int serverEntityId;
|
||||
|
||||
public List<byte[]> packetCache = new ArrayList<>();
|
||||
public byte[] positionPacket = null;
|
||||
|
||||
public void setSocket(Socket sock) throws IOException {
|
||||
socket = sock;
|
||||
socketOut = sock.getOutputStream();
|
||||
|
|
|
@ -24,6 +24,11 @@ public class Main {
|
|||
|
||||
public static boolean forwarded = false;
|
||||
|
||||
public static boolean filterUsernames = true;
|
||||
|
||||
public static boolean useAuth = false;
|
||||
public static int authIpLimit = -1;
|
||||
|
||||
public static WebSocketServer webSocketServer = null;
|
||||
|
||||
public static Map<WebSocket, Client> clients = new HashMap<>();
|
||||
|
@ -112,6 +117,19 @@ public class Main {
|
|||
}
|
||||
}
|
||||
|
||||
Map<String, Object> configAuth = new HashMap<>();
|
||||
configAuth.put("enabled", false);
|
||||
configAuth.put("ip_limit", -1);
|
||||
|
||||
configAuth = (LinkedHashMap<String, Object>) config.getOrDefault("auth", configAuth);
|
||||
|
||||
useAuth = (boolean) configAuth.getOrDefault("enabled", false);
|
||||
|
||||
if (useAuth) {
|
||||
authIpLimit = (int) configAuth.getOrDefault("ip_limit", 0);
|
||||
Auth.readDatabase();
|
||||
}
|
||||
|
||||
webPort = (int) config.getOrDefault("web_port", 25565);
|
||||
forwarded = (boolean) config.getOrDefault("forwarded", false);
|
||||
|
||||
|
@ -279,6 +297,10 @@ public class Main {
|
|||
break;
|
||||
}
|
||||
*/
|
||||
if (!targetUser.authed) {
|
||||
printMsg("That user is not yet authenticated!");
|
||||
break;
|
||||
}
|
||||
try {
|
||||
int destServer = Integer.parseInt(pieces[2]);
|
||||
targetUser.server = Math.max(0, Math.min(servers.size() - 1, destServer));
|
||||
|
|
|
@ -14,6 +14,7 @@ public class PluginMessages {
|
|||
try {
|
||||
String bungeeTag = dataIn.readUTF();
|
||||
if (bungeeTag.equals("Connect")) { // actually send current player to server :D
|
||||
if (!client.authed) return true;
|
||||
String destServer = dataIn.readUTF();
|
||||
try {
|
||||
int destServerInt = Integer.parseInt(destServer);
|
||||
|
|
|
@ -53,9 +53,9 @@ public class WebSocketProxy extends WebSocketServer {
|
|||
}
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException ignored) {}
|
||||
if (conn.isOpen() && (Main.bans.contains(Main.getIp(conn)) || !Main.clients.containsKey(conn))) conn.close();
|
||||
if (conn.isOpen() && (Main.bans.contains(Main.getIp(conn)) || !Main.clients.containsKey(conn) || !Main.clients.get(conn).authed)) conn.close();
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
@ -113,6 +113,10 @@ public class WebSocketProxy extends WebSocketServer {
|
|||
StringBuilder unameBuilder = new StringBuilder();
|
||||
for (int i = 0; i < unameLen; i++) unameBuilder.append(message.getChar());
|
||||
String username = unameBuilder.toString();
|
||||
if (!username.equals(username.replaceAll("[^A-Za-z0-9_-]", "_"))) {
|
||||
conn.close();
|
||||
return;
|
||||
}
|
||||
if (Main.clients.values().stream().anyMatch(client -> client.username.equals(username) || client.conn == conn)) {
|
||||
conn.close();
|
||||
return;
|
||||
|
@ -123,9 +127,16 @@ public class WebSocketProxy extends WebSocketServer {
|
|||
try {
|
||||
while (conn.isOpen()) {
|
||||
int currServer = selfClient.server;
|
||||
if (currServer == -1 && selfClient.authed) currServer = selfClient.server = 0;
|
||||
selfClient.hasLoginHappened = false;
|
||||
if (!selfClient.firstTime) Main.printMsg("Player " + selfClient + " joined server " + selfClient.server + "!");
|
||||
if (!selfClient.firstTime) Main.printMsg("Player " + selfClient + " joined server " + currServer + "!");
|
||||
ServerItem chosenServer = Main.servers.get(currServer);
|
||||
/*
|
||||
if (chosenServer.host.equals(Main.authKey)) {
|
||||
// todo: custom server here
|
||||
return;
|
||||
}
|
||||
*/
|
||||
Socket selfSocket = new Socket();
|
||||
try {
|
||||
// todo: pregenerate InetSocketAddresses
|
||||
|
@ -154,6 +165,7 @@ public class WebSocketProxy extends WebSocketServer {
|
|||
}
|
||||
if (ChatHandler.serverChatMessage(selfClient, data)) continue;
|
||||
if (PluginMessages.serverPluginMessage(selfClient, data)) continue;
|
||||
if (!selfClient.authed && data[0] == 13) selfClient.positionPacket = data;
|
||||
boolean loginPacket = data[0] == 1;
|
||||
if (loginPacket && !selfClient.hasLoginHappened) selfClient.hasLoginHappened = true;
|
||||
if (selfClient.firstTime && loginPacket) selfClient.clientEntityId = selfClient.serverEntityId = EntityMap.readInt(data, 1);
|
||||
|
@ -182,7 +194,17 @@ public class WebSocketProxy extends WebSocketServer {
|
|||
if (conn.isOpen()) conn.send(new byte[] { 9, 0, 0, 0, -1, 0, 0, 1, 0, 0, 7, 0, 100, 0, 101, 0, 102, 0, 97, 0, 117, 0, 108, 0, 116 });
|
||||
}
|
||||
EntityMap.rewrite(data, selfClient.serverEntityId, selfClient.clientEntityId);
|
||||
if (conn.isOpen()) conn.send(data);
|
||||
if (selfClient.authed || ((loginPacket || data[0] == 51 || data[0] == 13 || data[0] == 6) || !selfClient.hasLoginHappened)) {
|
||||
if (selfClient.authed) {
|
||||
while (selfClient.packetCache.size() > 0) {
|
||||
if (conn.isOpen()) conn.send(selfClient.packetCache.remove(0));
|
||||
}
|
||||
}
|
||||
if (conn.isOpen()) conn.send(data);
|
||||
} else {
|
||||
// cache data
|
||||
selfClient.packetCache.add(data);
|
||||
}
|
||||
if (loginPacket) sendToServer(new byte[] { (byte) 250, 0, 8, 0, 82, 0, 69, 0, 71, 0, 73, 0, 83, 0, 84, 0, 69, 0, 82, 0, 10, 66, 117, 110, 103, 101, 101, 67, 111, 114, 100 }, selfClient);
|
||||
}
|
||||
if (conn.isOpen() && selfClient.server == currServer) conn.close();
|
||||
|
@ -216,6 +238,13 @@ public class WebSocketProxy extends WebSocketServer {
|
|||
}
|
||||
|
||||
public void sendToServer(byte[] orig, Client client) throws IOException {
|
||||
if (!client.authed) {
|
||||
if (orig.length > 0) {
|
||||
if (orig[0] == 2 || orig[0] == 3) client.conn.send(new byte[] { 3, 0, 114, 0, (byte) 167, 0, 57, 0, 80, 0, 108, 0, 101, 0, 97, 0, 115, 0, 101, 0, 32, 0, 114, 0, 101, 0, 103, 0, 105, 0, 115, 0, 116, 0, 101, 0, 114, 0, 32, 0, 111, 0, 114, 0, 32, 0, 108, 0, 111, 0, 103, 0, 105, 0, 110, 0, 32, 0, 116, 0, 111, 0, 32, 0, 99, 0, 111, 0, 110, 0, 116, 0, 105, 0, 110, 0, 117, 0, 101, 0, 32, 0, 116, 0, 111, 0, 32, 0, 116, 0, 104, 0, 105, 0, 115, 0, 32, 0, 115, 0, 101, 0, 114, 0, 118, 0, 101, 0, 114, 0, 33, 0, 32, 0, 47, 0, 114, 0, 101, 0, 103, 0, 105, 0, 115, 0, 116, 0, 101, 0, 114, 0, 32, 0, 60, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 62, 0, 32, 0, 60, 0, 99, 0, 111, 0, 110, 0, 102, 0, 105, 0, 114, 0, 109, 0, 80, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 62, 0, 32, 0, 111, 0, 114, 0, 32, 0, 47, 0, 108, 0, 111, 0, 103, 0, 105, 0, 110, 0, 32, 0, 60, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 62 });
|
||||
if (orig[0] == 10 || orig[0] == 11 || orig[0] == 12 || orig[0] == 13 || orig[0] == 14 || orig[0] == 15) client.conn.send(client.positionPacket);
|
||||
}
|
||||
if (client.hasLoginHappened) return; // drop client packets :trol:
|
||||
}
|
||||
byte[] data = orig.clone();
|
||||
EntityMap.rewrite(data, client.clientEntityId, client.serverEntityId);
|
||||
client.socketOut.write(data);
|
||||
|
|
|
@ -11,6 +11,12 @@ origin_blacklist: "https://g.eags.us/eaglercraft/origin_blacklist.txt"
|
|||
# for example,
|
||||
# - "https://g.eags.us"
|
||||
origins: []
|
||||
# authentication info
|
||||
auth:
|
||||
# use auth
|
||||
enabled: false
|
||||
# max registers per ip (set to 0 for unlimited, not recommended, but necessary for servers that cannot see user IPs)
|
||||
ip_limit: 0
|
||||
# motd info
|
||||
motd:
|
||||
# the motd itself
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user