Update #0 - First Release

This commit is contained in:
LAX1DUDE
2022-12-25 01:12:28 -08:00
commit e7179fad45
2154 changed files with 256324 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,112 @@
package net.lax1dude.eaglercraft.v1_8.placeholder_server;
import java.nio.ByteBuffer;
import org.java_websocket.WebSocket;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class DummyConnection {
public final long age;
public long sendRedirectAt = 0l;
public final WebSocket sock;
private boolean hasFirstPacket = false;
public DummyConnection(WebSocket sock) {
this.age = System.currentTimeMillis();
this.sock = sock;
}
public void processString(String str) {
if(!hasFirstPacket) {
hasFirstPacket = true;
str = str.toLowerCase();
if(str.startsWith("accept:")) {
str = str.substring(7).trim();
if(str.startsWith("motd")) {
String subType = "motd";
int i = str.indexOf('.');
if(i > 0 && i != str.length() - 1) {
subType = str.substring(i + 1);
}
JSONObject json = new JSONObject();
json.put("name", PlaceholderServerConfig.serverName);
json.put("brand", "lax1dude");
json.put("vers", "EaglerXPlaceholder/1.0");
json.put("cracked", true);
json.put("secure", false);
json.put("time", System.currentTimeMillis());
json.put("uuid", PlaceholderServerConfig.serverUUID);
json.put("type", str);
JSONObject motdData = new JSONObject();
boolean icon = false;
if(subType.startsWith("cache.anim")) {
motdData.put("unsupported", true);
}else {
if(subType.startsWith("cache")) {
JSONArray arr = new JSONArray();
arr.put("animation");
arr.put("results");
arr.put("trending");
arr.put("portfolio");
motdData.put("cache", arr);
motdData.put("ttl", 7200);
}else {
motdData.put("cache", true);
}
JSONArray motdLines = new JSONArray();
String motd1 = PlaceholderServerConfig.motd1;
String motd2 = PlaceholderServerConfig.motd2;
if(motd1 != null && motd1.length() > 0) motdLines.put(motd1);
if(motd2 != null && motd2.length() > 0) motdLines.put(motd2);
motdData.put("motd", motdLines);
icon = PlaceholderServerConfig.cachedIconPacket != null && !subType.startsWith("noicon")
&& !subType.startsWith("cache.noicon");
motdData.put("icon", icon);
motdData.put("online", 0);
motdData.put("max", 0);
motdData.put("players", new JSONArray());
}
json.put("data", motdData);
sock.send(json.toString());
if(icon) {
sock.send(PlaceholderServerConfig.cachedIconPacket);
}
}
}
sock.close();
}
}
public void processBinary(ByteBuffer bin) {
if(!hasFirstPacket) {
hasFirstPacket = true;
if(bin.remaining() > 2) {
if(bin.get(0) == (byte)2 && bin.get(1) == (byte)69) {
sock.send(PlaceholderServerConfig.cachedLegacyKickRedirectPacket);
sendRedirectAt = System.currentTimeMillis();
return;
}else if(bin.get(0) == (byte)1) {
sock.send(PlaceholderServerConfig.cachedKickPacket);
}
}
sock.close();
}
}
}

View File

@ -0,0 +1,121 @@
package net.lax1dude.eaglercraft.v1_8.placeholder_server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class PlaceholderServer extends WebSocketServer {
public static PlaceholderServer websocketServer = null;
private boolean isOpen = false;
public static void main(String[] args) throws IOException {
System.out.println();
System.out.println("Copyright (c) 2022 lax1dude");
System.out.println("All rights reserved.");
System.out.println();
System.out.println("Starting placeholder 1.8 server...");
System.out.println();
PlaceholderServerConfig.load();
System.out.println("Starting WebSocket server...");
System.out.println();
websocketServer = new PlaceholderServer(new InetSocketAddress(PlaceholderServerConfig.host, PlaceholderServerConfig.port));
websocketServer.start();
long redirTimeout = (PlaceholderServerConfig.redirect != null && PlaceholderServerConfig.redirect.length() > 0) ? 500l : 100l;
while(true) {
try {
Thread.sleep(200l);
long millis = System.currentTimeMillis();
for(WebSocket ws : websocketServer.getConnections()) {
DummyConnection conn = ws.getAttachment();
if (conn != null && ((conn.sendRedirectAt > 0l && millis - conn.sendRedirectAt > redirTimeout)
|| millis - conn.age > (long) PlaceholderServerConfig.clientTimeout)) {
ws.close();
}
}
} catch (Throwable t) {
}
}
}
private PlaceholderServer(InetSocketAddress addr) {
super(addr);
setReuseAddr(true);
setTcpNoDelay(true);
}
@Override
public void onClose(WebSocket arg0, int arg1, String arg2, boolean arg3) {
}
@Override
public void onError(WebSocket arg0, Exception arg1) {
System.err.println();
if(arg0 != null) {
System.err.println("Caught WebSocket exception on " + arg0.getRemoteSocketAddress() + "!");
arg0.close();
}else {
System.err.println("Caught WebSocket exception!");
}
arg1.printStackTrace();
if(!isOpen) {
System.exit(-1);
}
}
@Override
public void onMessage(WebSocket arg0, String arg1) {
((DummyConnection)arg0.getAttachment()).processString(arg1);
}
@Override
public void onMessage(WebSocket arg0, ByteBuffer arg1) {
((DummyConnection)arg0.getAttachment()).processBinary(arg1);
}
@Override
public void onOpen(WebSocket arg0, ClientHandshake arg1) {
arg0.setAttachment(new DummyConnection(arg0));
}
@Override
public void onStart() {
System.out.println();
System.out.println("Listening on: " + getAddress());
isOpen = true;
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
try {
PlaceholderServer.this.stop();
} catch (Throwable t) {
t.printStackTrace();
}
}
}, "Shutdown Thread"));
System.out.println("Use CTRL+C to exit");
}
}

View File

@ -0,0 +1,180 @@
package net.lax1dude.eaglercraft.v1_8.placeholder_server;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class PlaceholderServerConfig {
public static final File configFile = new File("config.json");
public static String host = "0.0.0.0";
public static int port = 8081;
public static String icon = null;
public static String serverName = "EaglercraftX 1.8 Server";
public static String serverUUID = "";
public static int clientTimeout = 3000;
public static String motd1 = "Coming Soon";
public static String motd2 = "";
public static String kick = "This server is still under construction";
public static String redirect = "";
public static byte[] cachedIconPacket = null;
public static byte[] cachedLegacyKickRedirectPacket = null;
public static byte[] cachedKickPacket = null;
public static void load() throws IOException {
if(!configFile.exists()) {
System.out.println("Writing new config file to: " + configFile.getName());
int i;
try(Reader is = new InputStreamReader(PlaceholderServerConfig.class.getResourceAsStream("/config_default.json"));
OutputStream os = new FileOutputStream(configFile)) {
char[] copyBuffer = new char[1024];
StringBuilder sb = new StringBuilder();
while((i = is.read(copyBuffer)) != -1) {
sb.append(copyBuffer, 0, i);
}
String str = sb.toString();
str = str.replace("${random_uuid}", UUID.randomUUID().toString());
os.write(str.getBytes(StandardCharsets.UTF_8));
}
try(InputStream is = PlaceholderServerConfig.class.getResourceAsStream("/server-icon_default.png");
OutputStream os = new FileOutputStream(new File("server-icon.png"))) {
byte[] copyBuffer = new byte[1024];
while((i = is.read(copyBuffer)) != -1) {
os.write(copyBuffer, 0, i);
}
}
}
System.out.println("Reading config file: " + configFile.getName());
byte[] fileBytes = new byte[(int)configFile.length()];
try(InputStream is = new FileInputStream(configFile)) {
int i = 0, j;
while(i < fileBytes.length && (j = is.read(fileBytes, i, fileBytes.length - i)) != -1) {
i += j;
}
}
try {
JSONObject loaded = new JSONObject(new String(fileBytes, StandardCharsets.UTF_8));
host = loaded.getString("server_host");
port = loaded.getInt("server_port");
icon = loaded.getString("server_icon");
serverName = loaded.getString("server_name");
serverUUID = loaded.getString("server_uuid");
clientTimeout = loaded.getInt("client_timeout");
JSONArray motd = loaded.getJSONArray("server_motd");
motd1 = motd.getString(0);
if(motd.length() > 1) {
motd2 = motd.getString(1);
}
kick = loaded.getString("kick_message");
if(kick.length() > 255) {
kick = kick.substring(0, 255);
System.err.println("Warning: kick message was truncated to 255 characters");
}
redirect = loaded.optString("redirect_legacy", null);
}catch(Throwable t) {
throw new IOException("Could not load config file \"" + configFile.getAbsolutePath() + "\"!", t);
}
cacheKickPacket();
cacheRedirectPacket();
if(icon != null && icon.length() > 0) {
cacheIconPacket();
}
}
private static void cacheKickPacket() throws IOException {
ByteArrayOutputStream bao = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bao);
dos.writeByte(0xFF);
dos.writeByte(0x08);
dos.writeByte(kick.length());
for(int i = 0, l = kick.length(); i < l; ++i) {
dos.writeByte(kick.charAt(i) & 0xFF);
}
cachedKickPacket = bao.toByteArray();
}
private static void cacheRedirectPacket() throws IOException {
ByteArrayOutputStream bao = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bao);
if(redirect == null || redirect.length() == 0) {
String message = "This is an EaglercraftX 1.8 server, it is not compatible with 1.5.2!";
dos.writeByte(0xFF);
dos.writeShort(message.length());
for(int i = 0, l = message.length(), j; i < l; ++i) {
j = message.charAt(i);
dos.writeByte((j >> 8) & 0xFF);
dos.writeByte(j & 0xFF);
}
}else {
// Packet1Login
dos.writeByte(0x01);
dos.writeInt(0);
dos.writeShort(0);
dos.writeByte(0);
dos.writeByte(0);
dos.writeByte(0xFF);
dos.writeByte(0);
dos.writeByte(0);
// Packet250CustomPayload
dos.writeByte(0xFA);
String channel = "EAG|Reconnect";
int cl = channel.length();
dos.writeShort(cl);
for(int i = 0; i < cl; ++i) {
dos.writeChar(channel.charAt(i));
}
byte[] redirect_ = redirect.getBytes(StandardCharsets.UTF_8);
dos.writeShort(redirect_.length);
dos.write(redirect_);
}
cachedLegacyKickRedirectPacket = bao.toByteArray();
}
private static void cacheIconPacket() throws IOException {
File f = new File(icon);
int[] iconPixels = ServerIconLoader.createServerIcon(f);
if(iconPixels != null) {
cachedIconPacket = new byte[16384];
for(int i = 0, j; i < 4096; ++i) {
j = i << 2;
cachedIconPacket[j] = (byte)((iconPixels[i] >> 16) & 0xFF);
cachedIconPacket[j + 1] = (byte)((iconPixels[i] >> 8) & 0xFF);
cachedIconPacket[j + 2] = (byte)(iconPixels[i] & 0xFF);
cachedIconPacket[j + 3] = (byte)((iconPixels[i] >> 24) & 0xFF);
}
}else {
System.err.println("Could not load server icon \"" + f.getAbsolutePath() + "\"!");
}
}
}

View File

@ -0,0 +1,79 @@
package net.lax1dude.eaglercraft.v1_8.placeholder_server;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import javax.imageio.ImageIO;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
class ServerIconLoader {
static int[] createServerIcon(BufferedImage awtIcon) {
BufferedImage icon = awtIcon;
boolean gotScaled = false;
if(icon.getWidth() != 64 || icon.getHeight() != 64) {
icon = new BufferedImage(64, 64, awtIcon.getType());
Graphics2D g = (Graphics2D) icon.getGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, (awtIcon.getWidth() < 64 || awtIcon.getHeight() < 64) ?
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR : RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setBackground(new Color(0, true));
g.clearRect(0, 0, 64, 64);
int ow = awtIcon.getWidth();
int oh = awtIcon.getHeight();
int nw, nh;
float aspectRatio = (float)oh / (float)ow;
if(aspectRatio >= 1.0f) {
nw = (int)(64 / aspectRatio);
nh = 64;
}else {
nw = 64;
nh = (int)(64 * aspectRatio);
}
g.drawImage(awtIcon, (64 - nw) / 2, (64 - nh) / 2, (64 - nw) / 2 + nw, (64 - nh) / 2 + nh, 0, 0, awtIcon.getWidth(), awtIcon.getHeight(), null);
g.dispose();
gotScaled = true;
}
int[] pxls = icon.getRGB(0, 0, 64, 64, new int[4096], 0, 64);
if(gotScaled) {
for(int i = 0; i < pxls.length; ++i) {
if((pxls[i] & 0xFFFFFF) == 0) {
pxls[i] = 0;
}
}
}
return pxls;
}
static int[] createServerIcon(InputStream f) {
try {
return createServerIcon(ImageIO.read(f));
}catch(Throwable t) {
return null;
}
}
static int[] createServerIcon(File f) {
try {
return createServerIcon(ImageIO.read(f));
}catch(Throwable t) {
return null;
}
}
}

View File

@ -0,0 +1,13 @@
{
"server_host": "0.0.0.0",
"server_port": 8081,
"server_icon": "server-icon.png",
"server_motd": [
"1.8 is still under construction"
],
"server_name": "EaglercraftX 1.8 Server",
"server_uuid": "${random_uuid}",
"client_timeout": 3000,
"kick_message": "This EaglercraftX 1.8 server is still under construction!",
"redirect_legacy": null
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B