fix dev mode, add @ cmd

This commit is contained in:
Sen 2025-06-13 11:19:29 +02:00
parent 53a4f5f1a8
commit 06517a0d34
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
13 changed files with 238 additions and 395 deletions

View file

@ -38,7 +38,7 @@ application {
mainClass = "client.Client" mainClass = "client.Client"
tasks.run.get().workingDir = rootProject.file("dev/client") tasks.run.get().workingDir = rootProject.file("dev/client")
tasks.run.get().workingDir.mkdirs() tasks.run.get().workingDir.mkdirs()
tasks.run.get().systemProperties.put("crash.nodump", "") tasks.run.get().systemProperties.put("runtime.devmode", "")
} }
tasks.shadowJar { tasks.shadowJar {

View file

@ -19,6 +19,7 @@ import java.util.ArrayDeque;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Queue; import java.util.Queue;
@ -161,7 +162,6 @@ import common.packet.CPacketAction.Action;
import common.potion.Potion; import common.potion.Potion;
import common.potion.PotionEffect; import common.potion.PotionEffect;
import common.properties.IProperty; import common.properties.IProperty;
import common.rng.Random;
import common.sound.EventType; import common.sound.EventType;
import common.sound.PositionedSound; import common.sound.PositionedSound;
import common.util.BlockPos; import common.util.BlockPos;
@ -2251,8 +2251,6 @@ public class Client implements IThreadListener {
} }
public void run(long time) { public void run(long time) {
Log.SYSTEM.info("Java " + System.getProperty("java.version"));
Log.SYSTEM.info(VERSION + " (Protokoll #" + Util.PROTOCOL + ")");
if(!Window.createWindow(VERSION, System.getProperty("opengl.debug") != null)) if(!Window.createWindow(VERSION, System.getProperty("opengl.debug") != null))
System.exit(1); System.exit(1);
Log.SYSTEM.info("OpenGL %s", GL11.glGetString(GL11.GL_VERSION)); Log.SYSTEM.info("OpenGL %s", GL11.glGetString(GL11.GL_VERSION));
@ -2736,25 +2734,26 @@ public class Client implements IThreadListener {
} }
} }
}); });
this.registerDebug(Keysym.AE, "Programm sofort beenden und server beenden", new DebugRunner() { if(Util.DEVMODE)
public void execute(Keysym key) { this.registerDebug(Keysym.AE, "Programm sofort beenden und server beenden", new DebugRunner() {
if(Client.this.getNetHandler() != null) { public void execute(Keysym key) {
Client.this.getNetHandler().getConnection().sendPacket(new CPacketMessage(CPacketMessage.Type.COMMAND, "shutdown"), new GenericFutureListener<Future<? super Void>>() { if(Client.this.getNetHandler() != null) {
public void operationComplete(Future<? super Void> u) throws Exception { Client.this.getNetHandler().getConnection().sendPacket(new CPacketMessage(CPacketMessage.Type.COMMAND, "shutdown"), new GenericFutureListener<Future<? super Void>>() {
try { public void operationComplete(Future<? super Void> u) throws Exception {
Thread.sleep(1000L); try {
Thread.sleep(1000L);
}
catch(InterruptedException e) {
}
Client.this.interrupted = true;
} }
catch(InterruptedException e) { });
} }
Client.this.interrupted = true; else {
} Client.this.interrupted = true;
}); }
} }
else { });
Client.this.interrupted = true;
}
}
});
} }
private boolean handleDebugKey(Keysym key) { private boolean handleDebugKey(Keysym key) {
@ -2774,12 +2773,19 @@ public class Client implements IThreadListener {
public static void main(String[] args) { public static void main(String[] args) {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
Util.checkPlatform(); Util.checkPlatform();
Thread.currentThread().setName("Render thread");
Locale.setDefault(Locale.ROOT);
Util.setupHandlers();
Log.init(); Log.init();
Log.setSync(CLIENT); Log.SYSTEM.info("Java " + System.getProperty("java.version"));
Log.SYSTEM.info("Starte " + VERSION + " (Protokoll #" + Util.PROTOCOL + ")");
if(Util.DEVMODE)
Log.SYSTEM.warn("Entwicklungsmodus aktiv - Debugging-Features sind verfügbar");
Window.init(); Window.init();
ModelBlock.setAsProvider(); ModelBlock.setAsProvider();
Registry.setup("Render thread"); Registry.register();
UniverseRegistry.register(); UniverseRegistry.register();
Log.setSync(CLIENT);
CLIENT.run(time); CLIENT.run(time);
Window.end(); Window.end();
} }
@ -2840,26 +2846,6 @@ public class Client implements IThreadListener {
return data; return data;
} }
// plr_play("/home/sen/Musik/midi50k/Video_Games/ff/ff2cecil.mid", 0);
public static void meltdown() {
Random rand = new Random();
Log.SYSTEM.error("CORE_MELTDOWN: Nuclear processor core meltdown imminent\n\n" +
" ************************ CAUTION ************************\n" +
" KCTL: Processor core #%02d has reached a critical\n" +
" temperature, system explosion is imminent! \n" +
" According to the general core density \n" +
" calculation routine defined by the SKC \n" +
" (Hard) Warfare Testing Facility (SKC-WTF) \n" +
" your processor will cause a detonation with \n" +
" a radius of (roughly) %d.%d kilometers. \n" +
" In addition, it will release appoximately \n" +
" %d megajoules of ionizing radiation. \n" +
" You have an estimate time of %d minutes and \n" +
" %d seconds left to clear the detonation area. \n" +
" ************************ CAUTION ************************\n"
, rand.range(1, 64), rand.range(1, 9), rand.range(0, 9), rand.range(10000, 39999), rand.range(3, 9), rand.range(2, 59));
}
public <T extends CVar> T getVar(String name) { public <T extends CVar> T getVar(String name) {
return (T)cvars.get(name); return (T)cvars.get(name);
} }

View file

@ -1,23 +1,7 @@
package common.init; package common.init;
import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.imageio.ImageIO;
public abstract class Registry { public abstract class Registry {
private static boolean crashed; public static void register() {
private static void register() {
NameRegistry.register(); NameRegistry.register();
BlockRegistry.register(); BlockRegistry.register();
FlammabilityRegistry.register(); FlammabilityRegistry.register();
@ -30,105 +14,4 @@ public abstract class Registry {
EntityRegistry.register(); EntityRegistry.register();
DispenserRegistry.register(); DispenserRegistry.register();
} }
public static void setup(String thread) {
Thread.currentThread().setName(thread);
Locale.setDefault(Locale.ROOT);
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable e) {
System.err.println("Fehler in Thread '" + thread.getName() + "'");
e.printStackTrace(System.err);
if(crashed)
System.exit(1);
if(e instanceof OutOfMemoryError) {
System.gc();
System.gc();
}
if(!thread.getName().startsWith("Thread-") || e instanceof OutOfMemoryError) {
System.err.println("Beende!");
crashed = true;
if(System.getProperty("crash.nodump") == null) {
PrintStream ps = null;
File report = null;
try {
Date date = new Date();
File file = new File("crash-" + new SimpleDateFormat("dd.MM.yyyy_HH.mm.ss").format(date) + ".txt");
FileOutputStream out = new FileOutputStream(file);
ps = new PrintStream(out);
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] info = bean.dumpAllThreads(true, true);
StringBuilder sb = new StringBuilder();
Error error = new Error();
for(ThreadInfo threadinfo : info) {
if(threadinfo.getThreadId() == thread.threadId())
error.setStackTrace(threadinfo.getStackTrace());
sb.append(threadinfo);
}
ps.println("************************************************ " + new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(date) + " ************************************************");
ps.println();
ps.println("\"Wie haste das denn nu wieder geschafft, Bursche?\"");
ps.println("Unerwarteter Fehler in Thread '" + thread.getName() + "':");
e.printStackTrace(ps);
ps.println();
ps.println("---------------------------------------------- Thread-Dump (" + info.length + " Threads) ---------------------------------------------");
ps.println();
ps.print(sb.toString());
ps.println("*********************************************************************************************************************");
report = file;
}
catch(Throwable t) {
System.err.println("Konnte Absturzbericht nicht speichern:");
t.printStackTrace(System.err);
}
finally {
if(ps != null)
ps.close();
}
if(report != null) {
System.err.println("Absturzbericht gespeichert unter " + report.getPath());
try {
Desktop.getDesktop().browse(report.toURI());
}
catch(Throwable e1) {
System.err.println("Konnte " + report + " nicht öffnen: " + e1);
}
}
}
System.exit(1);
}
}
});
ImageIO.setUseCache(false);
Thread timer = new Thread("Timer Hack Thread") {
public void run() {
while(true) {
try {
Thread.sleep(2147483647L);
}
catch(InterruptedException e) {
;
}
}
}
};
timer.setDaemon(true);
timer.start();
System.setProperty("java.net.preferIPv4Stack", "true");
register();
}
public static void addShutdownHook(final Runnable hook) {
Runtime.getRuntime().addShutdownHook(new Thread("Game Shutdown Thread") {
public void run() {
if(!crashed) {
try {
hook.run();
}
catch(Throwable e) {
e.printStackTrace();
}
}
}
});
}
} }

View file

@ -1,17 +1,29 @@
package common.util; package common.util;
import java.awt.Desktop;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import common.Version; import common.Version;
import common.collect.Lists; import common.collect.Lists;
import common.collect.Maps; import common.collect.Maps;
import common.log.Log; import common.log.Log;
import common.rng.Random;
public abstract class Util { public abstract class Util {
private static final long START = getTime(); private static final long START = getTime();
@ -20,6 +32,8 @@ public abstract class Util {
public static final boolean DEVMODE = System.getProperty("runtime.devmode") != null; public static final boolean DEVMODE = System.getProperty("runtime.devmode") != null;
public static final int PROTOCOL = Version.MAJOR << 16 | Version.MINOR << 8 | Version.PATCH; public static final int PROTOCOL = Version.MAJOR << 16 | Version.MINOR << 8 | Version.PATCH;
public static final String VERSION = "v" + Version.MAJOR + "." + Version.MINOR + "." + Version.PATCH + Version.RELEASE; public static final String VERSION = "v" + Version.MAJOR + "." + Version.MINOR + "." + Version.PATCH + Version.RELEASE;
private static boolean crashed;
public static String strip(String str, int offset, int len, char newl, char tab, char unk) { public static String strip(String str, int offset, int len, char newl, char tab, char unk) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -44,100 +58,7 @@ public abstract class Util {
} }
return sb.toString(); return sb.toString();
} }
/*
uint utf_read(const char **ptr) {
uint ch;
byte utf;
char c = *((*ptr)++);
for(utf = 0; (utf < 6) && (c & (0x80 >> utf)); utf++) {
;
}
if(utf == 1)
return CHR_UNK;
for(ch = ((!utf) || ((((uint)c) << 6) | (((**ptr) & 0x3f) & ~(0xff >> utf)))) ? (c & (0x7f >> utf)) : 0; utf > 1; utf--) {
if(((c = **ptr) & 0xc0) == 0x80) {
// if(ch) {
ch <<= 6;
ch |= c & 0x3f;
// }
}
else {
return c ? CHR_UNK : 0;
}
(*ptr)++;
}
// fprintf(stderr, "%d / %c\n", ch, ch);
return (utf && !ch) ? CHR_UNK : ch;
}
uint utf_readn(const char *ptr, int *pos) {
const char *str = &ptr[*pos];
uint ch = utf_read(&str);
*pos = (int)(str-ptr);
return ch;
}
byte utf_write(char **ptr, int *len, uint ch) {
uint test;
uint mask = 0xffffff80;
char utf;
char c;
if(ch & 0x80000000) {
return 1;
}
for(utf = 0; ch & mask & ~(test = (0xffffffff << ((utf + 1) * 6 + (5 - utf)))); utf++) {
mask &= test;
}
// fprintf(stderr, "%d\n", utf);
if(utf + 1 >= (*len)) {
return 0;
}
(*len) -= utf + 1;
*((*ptr)++) = utf ? (~(0x7f >> utf) | (((uint)(ch >> (utf * 6))) & (0x3f >> utf))) : ch;
for(--utf; utf >= 0; utf--) {
*((*ptr)++) = 0x80 | (((uint)(ch >> (utf * 6))) & 0x3f);
}
return 1;
}
byte utf_rwriten(char *ptr, int *pos, int len, uint ch) {
char *str = &ptr[*pos];
len -= (*pos);
byte res = utf_write(&str, &len, ch);
*pos = (int)(str-ptr);
return res;
}
uint utf_rread(const char **ptr, const char *start) {
const char *tp = *ptr;
uint ch;
char c;
do {
if(tp == start)
return 0;
tp--;
} while(((c = (*tp)) & 0xc0) == 0x80);
*ptr = tp;
return (ch = utf_read(&tp)) ? ch : CHR_UNK;
}
uint utf_rreadn(const char *ptr, int *pos) {
const char *str = &ptr[*pos];
uint ch = utf_rread(&str, ptr);
*pos = (int)(str-ptr);
return ch;
}
int utf_len(const char *str) {
int len;
for(len = 0; utf_read(&str); len++) {
;
}
return len;
}
*/
public static int compareLower(String str1, String str2) { public static int compareLower(String str1, String str2) {
if(str2.length() > str1.length()) if(str2.length() > str1.length())
return 0; return 0;
@ -339,6 +260,124 @@ int utf_len(const char *str) {
} }
} }
public static void setupHandlers() {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable e) {
System.err.println("Fehler in Thread '" + thread.getName() + "'");
e.printStackTrace(System.err);
if(crashed)
System.exit(1);
if(e instanceof OutOfMemoryError) {
System.gc();
System.gc();
}
if(!thread.getName().startsWith("Thread-") || e instanceof OutOfMemoryError) {
System.err.println("Beende!");
crashed = true;
if(!DEVMODE) {
PrintStream ps = null;
File report = null;
try {
Date date = new Date();
File file = new File("crash-" + new SimpleDateFormat("dd.MM.yyyy_HH.mm.ss").format(date) + ".txt");
FileOutputStream out = new FileOutputStream(file);
ps = new PrintStream(out);
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] info = bean.dumpAllThreads(true, true);
StringBuilder sb = new StringBuilder();
Error error = new Error();
for(ThreadInfo threadinfo : info) {
if(threadinfo.getThreadId() == thread.threadId())
error.setStackTrace(threadinfo.getStackTrace());
sb.append(threadinfo);
}
ps.println("************************************************ " + new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(date) + " ************************************************");
ps.println();
ps.println("\"Wie haste das denn nu wieder geschafft, Bursche?\"");
ps.println("Unerwarteter Fehler in Thread '" + thread.getName() + "':");
e.printStackTrace(ps);
ps.println();
ps.println("---------------------------------------------- Thread-Dump (" + info.length + " Threads) ---------------------------------------------");
ps.println();
ps.print(sb.toString());
ps.println("*********************************************************************************************************************");
report = file;
}
catch(Throwable t) {
System.err.println("Konnte Absturzbericht nicht speichern:");
t.printStackTrace(System.err);
}
finally {
if(ps != null)
ps.close();
}
if(report != null) {
System.err.println("Absturzbericht gespeichert unter " + report.getPath());
try {
Desktop.getDesktop().browse(report.toURI());
}
catch(Throwable e1) {
System.err.println("Konnte " + report + " nicht öffnen: " + e1);
}
}
}
System.exit(1);
}
}
});
ImageIO.setUseCache(false);
Thread timer = new Thread("Timer Hack Thread") {
public void run() {
while(true) {
try {
Thread.sleep(2147483647L);
}
catch(InterruptedException e) {
;
}
}
}
};
timer.setDaemon(true);
timer.start();
System.setProperty("java.net.preferIPv4Stack", "true");
}
public static void addShutdownHook(final Runnable hook) {
Runtime.getRuntime().addShutdownHook(new Thread("Game Shutdown Thread") {
public void run() {
if(!crashed) {
try {
hook.run();
}
catch(Throwable e) {
e.printStackTrace();
}
}
}
});
}
// plr_play("/home/sen/Musik/midi50k/Video_Games/ff/ff2cecil.mid", 0);
public static void meltdown() {
Random rand = new Random();
Log.SYSTEM.error("CORE_MELTDOWN: Nuclear processor core meltdown imminent\n\n" +
" ************************ CAUTION ************************\n" +
" KCTL: Processor core #%02d has reached a critical\n" +
" temperature, system explosion is imminent! \n" +
" According to the general core density \n" +
" calculation routine defined by the SKC \n" +
" (Hard) Warfare Testing Facility (SKC-WTF) \n" +
" your processor will cause a detonation with \n" +
" a radius of (roughly) %d.%d kilometers. \n" +
" In addition, it will release appoximately \n" +
" %d megajoules of ionizing radiation. \n" +
" You have an estimate time of %d minutes and \n" +
" %d seconds left to clear the detonation area. \n" +
" ************************ CAUTION ************************\n"
, rand.range(1, 64), rand.range(1, 9), rand.range(0, 9), rand.range(10000, 39999), rand.range(3, 9), rand.range(2, 59));
}
public static Pair<String, String> getKeyValue(String text, char separator) { public static Pair<String, String> getKeyValue(String text, char separator) {
int index = text.indexOf(separator); int index = text.indexOf(separator);
if(index == -1) if(index == -1)

View file

@ -18,7 +18,7 @@ application {
mainClass = "server.Server" mainClass = "server.Server"
tasks.run.get().workingDir = rootProject.file("dev/server") tasks.run.get().workingDir = rootProject.file("dev/server")
tasks.run.get().workingDir.mkdirs() tasks.run.get().workingDir.mkdirs()
tasks.run.get().systemProperties.put("crash.nodump", "") tasks.run.get().systemProperties.put("runtime.devmode", "")
tasks.run.get().standardInput = System.`in` tasks.run.get().standardInput = System.`in`
} }

View file

@ -19,6 +19,7 @@ import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@ -96,7 +97,7 @@ import server.biome.GenBiome;
import server.clipboard.ReorderRegistry; import server.clipboard.ReorderRegistry;
import server.clipboard.RotationRegistry; import server.clipboard.RotationRegistry;
import server.command.CommandEnvironment; import server.command.CommandEnvironment;
import server.command.FixedExecutor; import server.command.Executor;
import server.network.HandshakeHandler; import server.network.HandshakeHandler;
import server.network.Player; import server.network.Player;
import server.network.User; import server.network.User;
@ -106,7 +107,7 @@ import server.world.Converter;
import server.world.Region; import server.world.Region;
import server.world.WorldServer; import server.world.WorldServer;
public final class Server implements IThreadListener { public final class Server implements IThreadListener, Executor {
private static final LazyLoader<NioEventLoopGroup> SERVER_NIO_EVENTLOOP = new LazyLoader<NioEventLoopGroup>() { private static final LazyLoader<NioEventLoopGroup> SERVER_NIO_EVENTLOOP = new LazyLoader<NioEventLoopGroup>() {
protected NioEventLoopGroup load() { protected NioEventLoopGroup load() {
return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).build()); return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).build());
@ -156,15 +157,21 @@ public final class Server implements IThreadListener {
public static void main(String[] args) { public static void main(String[] args) {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
Util.checkPlatform(); Util.checkPlatform();
Thread.currentThread().setName("Server thread");
Locale.setDefault(Locale.ROOT);
Util.setupHandlers();
Log.init(); Log.init();
Registry.setup("Server thread"); Log.SYSTEM.info("Java " + System.getProperty("java.version"));
Log.SYSTEM.info("Starte " + Version.NAME + " Server Version " + Util.VERSION + " (Protokoll #" + Util.PROTOCOL + ")"); Log.SYSTEM.info("Starte " + Version.NAME + " Server " + Util.VERSION + " (Protokoll #" + Util.PROTOCOL + ")");
if(Util.DEVMODE)
Log.SYSTEM.warn("Entwicklungsmodus aktiv - Debugging-Features sind verfügbar");
Registry.register();
GenBiome.setAsProvider(); GenBiome.setAsProvider();
UniverseRegistry.register(); UniverseRegistry.register();
RotationRegistry.register(); RotationRegistry.register();
ReorderRegistry.register(); ReorderRegistry.register();
final Server server = new Server(); final Server server = new Server();
Registry.addShutdownHook(new Runnable() { Util.addShutdownHook(new Runnable() {
public void run() { public void run() {
server.stopServer(); server.stopServer();
Log.flushLog(); Log.flushLog();
@ -224,7 +231,7 @@ public final class Server implements IThreadListener {
String version = tag.hasString("Version") ? tag.getString("Version") : null; String version = tag.hasString("Version") ? tag.getString("Version") : null;
version = version != null && version.isEmpty() ? "<unbekannt>" : version; version = version != null && version.isEmpty() ? "<unbekannt>" : version;
long time = tag.hasLong("Time") ? tag.getLong("Time") : World.START_TIME; long time = tag.hasLong("Time") ? tag.getLong("Time") : World.START_TIME;
Log.IO.info("Version: %s", version); Log.IO.info("Config-Version: %s", version);
Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", time, time / 20L); Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", time, time / 20L);
Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(lastPlayed))); Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(lastPlayed)));
if(tag.hasByteArray("PrivateKey") && tag.hasByteArray("PublicKey")) { if(tag.hasByteArray("PrivateKey") && tag.hasByteArray("PublicKey")) {
@ -403,35 +410,9 @@ public final class Server implements IThreadListener {
this.keyPair = EncryptUtil.createKeypair(); this.keyPair = EncryptUtil.createKeypair();
} }
User.loadDatabase(this.users); User.loadDatabase(this.users);
// if(dtime == -1L) // {
// dtime = World.START_TIME;
//// Config.set("spawnDim", "1", null);
//// }
this.worlds.add(this.space = new WorldServer(this, wtime, Space.INSTANCE)); this.worlds.add(this.space = new WorldServer(this, wtime, Space.INSTANCE));
this.dimensions.put(this.space.dimension.getDimensionId(), this.space); this.dimensions.put(this.space.dimension.getDimensionId(), this.space);
new File("players").mkdirs(); new File("players").mkdirs();
// if(Config.spawnY < 0) {
// WorldServer world = this.getWorld(Config.spawnDim);
// world = world == null ? this.space : world;
// Random rand = new Random(world.getSeed());
// int x = 0;
// int z = 0;
// int count = 0;
// while(!(world.getGroundAboveSeaLevel(new BlockPos(x, 0, z)) == Blocks.grass)) {
// if(count == 1000) {
// SKC.warn("Konnte keine Spawn-Position finden");
// break;
// }
// x += rand.zrange(64) - rand.zrange(64);
// z += rand.zrange(64) - rand.zrange(64);
// ++count;
// }
// Config.set("spawnX", "" + x, null);
// Config.set("spawnY", "" + world.getSeaLevel(), null);
// Config.set("spawnZ", "" + z, null);
// Config.set("spawnYaw", "" + (-180.0f + rand.floatv() * 360.0f), null);
// Config.set("spawnPitch", "0.0", null);
// }
this.setTpsTarget(20.0f); this.setTpsTarget(20.0f);
for(Dimension dim : UniverseRegistry.getDimensions()) { for(Dimension dim : UniverseRegistry.getDimensions()) {
if(WorldServer.needsLoading(dim)) { if(WorldServer.needsLoading(dim)) {
@ -462,7 +443,7 @@ public final class Server implements IThreadListener {
final String cmd = line; final String cmd = line;
Server.this.schedule(new Runnable() { Server.this.schedule(new Runnable() {
public void run() { public void run() {
Server.this.scriptEnv.execute(cmd, new FixedExecutor(Server.this, "#con", "KONSOLE", null)); Server.this.scriptEnv.execute(cmd, Server.this);
} }
}); });
} }
@ -518,8 +499,6 @@ public final class Server implements IThreadListener {
int total = SVars.distance * 2 + 1; int total = SVars.distance * 2 + 1;
total *= total; total *= total;
Log.TICK.info("Generiere und lade Welt"); Log.TICK.info("Generiere und lade Welt");
// WorldServer world = this.getWorld(Config.spawnDim);
// world = world == null ? this.space : world;
bx = bx >> 4; bx = bx >> 4;
bz = bz >> 4; bz = bz >> 4;
long last = System.currentTimeMillis(); long last = System.currentTimeMillis();
@ -535,43 +514,8 @@ public final class Server implements IThreadListener {
} }
} }
} }
// public void resetProgress() {
// this.setProgress(-1);
// }
//
// public void setDone() {
// this.setProgress(-2);
// }
private void tick() { private void tick() {
// boolean pause = this.paused;
// this.paused = this.pause;
// if(!pause && this.paused) {
// if(!this.debug)
// Log.info("Speichere und pausiere Spiel...");
// this.saveAllPlayerData(true);
// this.saveAllWorlds(true);
// }
// if(this.paused) {
// synchronized(this.queue) {
// while(!this.queue.isEmpty()) {
// FutureTask<?> task = this.queue.poll();
// try {
// task.run();
// task.get();
// }
// catch(ExecutionException e1) {
// if(!(e1.getCause() instanceof ThreadQuickExitException))
// Log.error("Fehler beim Ausführen von Pause-Task " + task, e1);
// }
// catch(InterruptedException e2) {
// Log.error("Fehler beim Ausführen von Pause-Task " + task, e2);
// }
// }
// }
// return;
// }
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
synchronized(this.queue) { synchronized(this.queue) {
while(!this.queue.isEmpty()) { while(!this.queue.isEmpty()) {
@ -741,22 +685,6 @@ public final class Server implements IThreadListener {
return Thread.currentThread() == this.serverThread; return Thread.currentThread() == this.serverThread;
} }
// private void movePlayerToSpawn(EntityNPC player) {
// BlockPos pos = new BlockPos(Config.spawnX, Config.spawnY, Config.spawnZ);
// int radius = Config.spawnRadius;
// if(radius > 0) {
// pos = ((WorldServer)player.worldObj).getTopSolidOrLiquidBlock(pos.add(
// ExtMath.clampi(player.worldObj.rand.excl(-radius, radius), -World.MAX_SIZE + 1, World.MAX_SIZE - 1), 0,
// ExtMath.clampi(player.worldObj.rand.excl(-radius, radius), -World.MAX_SIZE + 1, World.MAX_SIZE - 1)));
// }
// player.moveToBlockPosAndAngles(pos, radius > 0 ? (-180.0f + player.worldObj.rand.floatv() * 360.0f) : Config.spawnYaw,
// radius > 0 ? 0.0f : Config.spawnPitch);
// while(radius >= 0 && !player.worldObj.getCollidingBoundingBoxes(player, player.getEntityBoundingBox()).isEmpty()
// && player.posY < 511.0D) {
// player.setPosition(player.posX, player.posY + 1.0D, player.posZ);
// }
// }
public Position getRandomSpawnPosition(WorldPos origin) { public Position getRandomSpawnPosition(WorldPos origin) {
WorldServer world = this.getWorld(origin.getDimension()); WorldServer world = this.getWorld(origin.getDimension());
world = world == null ? this.space : world; world = world == null ? this.space : world;
@ -806,9 +734,8 @@ public final class Server implements IThreadListener {
player.readTags(tag); player.readTags(tag);
else else
player.onInitialSpawn(null); player.onInitialSpawn(null);
// player.setWorld(world);
if(tag == null) if(tag == null)
/* this.movePlayerToSpawn(player); */ player.moveToBlockPosAndAngles(new BlockPos(0, 16384, 0), 0.0f, 0.0f); player.moveToBlockPosAndAngles(new BlockPos(0, 16384, 0), 0.0f, 0.0f);
Log.NETWORK.info(loginUser + "[" + connection.getCutAddress() + "] hat sich mit Objekt-ID " Log.NETWORK.info(loginUser + "[" + connection.getCutAddress() + "] hat sich mit Objekt-ID "
+ player.getId() + " auf Level " + world.dimension.getDimensionId() + ": " + player.getId() + " auf Level " + world.dimension.getDimensionId() + ": "
@ -818,7 +745,6 @@ public final class Server implements IThreadListener {
conn.sendPacket(new SPacketHeldItemChange(player.inventory.currentItem)); conn.sendPacket(new SPacketHeldItemChange(player.inventory.currentItem));
conn.sendPacket(new SPacketWorld(WorldServer.clampGravity(), conn.sendPacket(new SPacketWorld(WorldServer.clampGravity(),
SVars.dayCycle, SVars.timeFlow)); SVars.dayCycle, SVars.timeFlow));
// conn.initializeStats();
this.sendPacket(new SPacketPlayerListItem(false, conn)); this.sendPacket(new SPacketPlayerListItem(false, conn));
world.spawnEntityInWorld(player); world.spawnEntityInWorld(player);
@ -945,7 +871,6 @@ public final class Server implements IThreadListener {
else { else {
Position rpos = this.getRandomSpawnPosition(origin); Position rpos = this.getRandomSpawnPosition(origin);
nplayer.setLocationAndAngles(rpos.x(), rpos.y(), rpos.z(), rpos.yaw(), rpos.pitch()); nplayer.setLocationAndAngles(rpos.x(), rpos.y(), rpos.z(), rpos.yaw(), rpos.pitch());
// this.movePlayerToSpawn(nplayer);
} }
world.loadChunk((int)nplayer.posX >> 4, (int)nplayer.posZ >> 4); world.loadChunk((int)nplayer.posX >> 4, (int)nplayer.posZ >> 4);
if(bed != null ? SVars.checkBed : SVars.spawnRadius >= 0) { if(bed != null ? SVars.checkBed : SVars.spawnRadius >= 0) {
@ -981,20 +906,17 @@ public final class Server implements IThreadListener {
oldWorld.untrackEntity(old); oldWorld.untrackEntity(old);
oldWorld.removePlayer(old); oldWorld.removePlayer(old);
oldWorld.removePlayerEntityDangerously(old); oldWorld.removePlayerEntityDangerously(old);
// old.dead = false;
WorldServer world = tag == null ? this.space : this.getWorld(tag.getInt("Dimension")); WorldServer world = tag == null ? this.space : this.getWorld(tag.getInt("Dimension"));
world = world == null ? this.space : world; world = world == null ? this.space : world;
EntityNPC nplayer = conn.createPlayer(world, tag == null ? EntityRegistry.getEntityString(clazz) : tag.getString("id")); EntityNPC nplayer = conn.createPlayer(world, tag == null ? EntityRegistry.getEntityString(clazz) : tag.getString("id"));
// conn.sendPacket(new SPacketRespawn(world.dimension, EntityRegistry.getEntityID(nplayer)));
if(tag != null) if(tag != null)
nplayer.readTags(tag); nplayer.readTags(tag);
else else
nplayer.onInitialSpawn(null); nplayer.onInitialSpawn(null);
// nplayer.clonePlayer(old);
nplayer.setId(old.getId()); nplayer.setId(old.getId());
if(tag == null) if(tag == null)
/* this.movePlayerToSpawn(nplayer); */ nplayer.moveToBlockPosAndAngles(new BlockPos(0, 16384, 0), 0.0f, 0.0f); nplayer.moveToBlockPosAndAngles(new BlockPos(0, 16384, 0), 0.0f, 0.0f);
world.loadChunk((int)nplayer.posX >> 4, (int)nplayer.posZ >> 4); world.loadChunk((int)nplayer.posX >> 4, (int)nplayer.posZ >> 4);
world.addPlayer(nplayer); world.addPlayer(nplayer);
world.spawnEntityInWorld(nplayer); world.spawnEntityInWorld(nplayer);
@ -1002,7 +924,6 @@ public final class Server implements IThreadListener {
conn.sendPacket(new SPacketSkin(nplayer.getId(), nplayer.getSkin())); // , nplayer.getModel())); conn.sendPacket(new SPacketSkin(nplayer.getId(), nplayer.getSkin())); // , nplayer.getModel()));
conn.setPlayerLocation(nplayer.posX, nplayer.posY, nplayer.posZ, nplayer.rotYaw, nplayer.rotPitch); conn.setPlayerLocation(nplayer.posX, nplayer.posY, nplayer.posZ, nplayer.rotYaw, nplayer.rotPitch);
conn.sendPacket(new SPacketSetExperience(nplayer.experience, nplayer.experienceTotal, nplayer.experienceLevel)); conn.sendPacket(new SPacketSetExperience(nplayer.experience, nplayer.experienceTotal, nplayer.experienceLevel));
// conn.initializeStats();
conn.addSelfToInternalCraftingInventory(); conn.addSelfToInternalCraftingInventory();
nplayer.setHealth(nplayer.getHealth()); nplayer.setHealth(nplayer.getHealth());
this.updateTimeAndWeatherForPlayer(conn, world); this.updateTimeAndWeatherForPlayer(conn, world);
@ -1016,7 +937,6 @@ public final class Server implements IThreadListener {
public void transferToDimension(EntityNPC player, int dimension, BlockPos pos, float yaw, float pitch, PortalType portal) { public void transferToDimension(EntityNPC player, int dimension, BlockPos pos, float yaw, float pitch, PortalType portal) {
WorldServer oldWorld = (WorldServer)player.getServerWorld(); // this.getWorld(player.dimension); WorldServer oldWorld = (WorldServer)player.getServerWorld(); // this.getWorld(player.dimension);
// player.dimension = dimension;
WorldServer newWorld = this.getWorld(dimension); WorldServer newWorld = this.getWorld(dimension);
player.connection.sendPacket(new SPacketRespawn(newWorld.dimension, EntityRegistry.getEntityID(player), player.connection.isInEditor())); player.connection.sendPacket(new SPacketRespawn(newWorld.dimension, EntityRegistry.getEntityID(player), player.connection.isInEditor()));
oldWorld.removePlayerEntityDangerously(player); oldWorld.removePlayerEntityDangerously(player);
@ -1031,7 +951,6 @@ public final class Server implements IThreadListener {
player.connection.setPlayerLocation(player.posX, player.posY, player.posZ, pos != null ? yaw : player.rotYaw, pos != null ? pitch : player.rotPitch); player.connection.setPlayerLocation(player.posX, player.posY, player.posZ, pos != null ? yaw : player.rotYaw, pos != null ? pitch : player.rotPitch);
if(pos != null) if(pos != null)
player.setRotationYawHead(yaw); player.setRotationYawHead(yaw);
// player.interactManager.setWorld(newWorld);
this.updateTimeAndWeatherForPlayer((Player)player.connection, newWorld); this.updateTimeAndWeatherForPlayer((Player)player.connection, newWorld);
this.syncPlayerInventory(player); this.syncPlayerInventory(player);
for(PotionEffect effect : player.getEffects()) { for(PotionEffect effect : player.getEffects()) {
@ -1181,10 +1100,6 @@ public final class Server implements IThreadListener {
public Map<String, Position> getWarps() { public Map<String, Position> getWarps() {
return this.warps; return this.warps;
} }
//
// public void start() {
// this.serverThread.start();
// }
private void stopServer() { private void stopServer() {
if(!this.stopped) { if(!this.stopped) {
@ -1204,7 +1119,6 @@ public final class Server implements IThreadListener {
try { try {
if(this.endpoint != null) if(this.endpoint != null)
this.terminateEndpoint("Wechsele auf Port " + port); this.terminateEndpoint("Wechsele auf Port " + port);
// throw new IllegalStateException("Eingangspunkt bereits gesetzt");
Log.NETWORK.info("Öffne Port %d auf 0.0.0.0 (Timeout %ds)", port, SVars.timeout); Log.NETWORK.info("Öffne Port %d auf 0.0.0.0 (Timeout %ds)", port, SVars.timeout);
this.endpoint = ((ServerBootstrap)((ServerBootstrap)(new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ChannelInitializer<Channel>() { this.endpoint = ((ServerBootstrap)((ServerBootstrap)(new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ChannelInitializer<Channel>() {
protected void initChannel(Channel channel) throws Exception { protected void initChannel(Channel channel) throws Exception {
@ -1246,10 +1160,6 @@ public final class Server implements IThreadListener {
"Geladen: " + this.getWorlds().size() + " Welten, " + WorldServer.getLoadedInfo(this); "Geladen: " + this.getWorlds().size() + " Welten, " + WorldServer.getLoadedInfo(this);
} }
public void logConsole(String message) {
Log.CONSOLE.info(message);
}
public PublicKey getPublicKey() { public PublicKey getPublicKey() {
return this.keyPair.getPublic(); return this.keyPair.getPublic();
} }
@ -1257,4 +1167,20 @@ public final class Server implements IThreadListener {
public PrivateKey getPrivateKey() { public PrivateKey getPrivateKey() {
return this.keyPair.getPrivate(); return this.keyPair.getPrivate();
} }
public void logConsole(String msg) {
Log.CONSOLE.info(msg);
}
public Position getExecPos() {
return null;
}
public Entity getPointedEntity() {
return null;
}
public BlockPos getPointedPosition() {
return null;
}
} }

View file

@ -163,6 +163,7 @@ public class CommandEnvironment {
} }
public void execute(String cmd, Executor exec) { public void execute(String cmd, Executor exec) {
Executor prev = this.currentExecutor;
this.currentExecutor = exec; this.currentExecutor = exec;
try { try {
this.execute(cmd, true); this.execute(cmd, true);
@ -180,7 +181,7 @@ public class CommandEnvironment {
Log.CONSOLE.error(t, "Fehler beim Ausführen von Befehl '%s'", cmd); Log.CONSOLE.error(t, "Fehler beim Ausführen von Befehl '%s'", cmd);
} }
finally { finally {
this.currentExecutor = null; this.currentExecutor = prev;
this.previousOutput = null; this.previousOutput = null;
this.variables.clear(); this.variables.clear();
} }
@ -221,22 +222,13 @@ public class CommandEnvironment {
} }
public void registerDefaults() { public void registerDefaults() {
this.registerVariable("*", new Variable() {
public String get() {
return CommandEnvironment.this.currentExecutor.getExecId();
}
});
this.registerVariable("name", new Variable() {
public String get() {
return CommandEnvironment.this.currentExecutor.getExecName();
}
});
this.registerVariable("!", new Variable() { this.registerVariable("!", new Variable() {
public String get() { public String get() {
return CommandEnvironment.this.previousOutput == null ? null : CommandEnvironment.this.previousOutput.toString(); return CommandEnvironment.this.previousOutput == null ? null : CommandEnvironment.this.previousOutput.toString();
} }
}); });
this.registerExecutable(new CommandHelp());
this.registerExecutable(new CommandSpawn()); this.registerExecutable(new CommandSpawn());
this.registerExecutable(new CommandPotion()); this.registerExecutable(new CommandPotion());
this.registerExecutable(new CommandMilk()); this.registerExecutable(new CommandMilk());
@ -267,7 +259,6 @@ public class CommandEnvironment {
this.registerExecutable(new CommandClear()); this.registerExecutable(new CommandClear());
this.registerExecutable(new CommandEntity()); this.registerExecutable(new CommandEntity());
this.registerExecutable(new CommandItem()); this.registerExecutable(new CommandItem());
this.registerExecutable(new CommandAt());
this.registerExecutable(new CommandHelp(this));
} }
} }

View file

@ -3,18 +3,17 @@ package server.command;
import common.entity.Entity; import common.entity.Entity;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.Position; import common.util.Position;
import server.Server;
import server.network.Player; import server.network.Player;
public interface Executor { public interface Executor {
void logConsole(String msg); void logConsole(String msg);
String getExecId();
String getExecName();
Position getExecPos(); Position getExecPos();
Entity getPointedEntity(); Entity getPointedEntity();
BlockPos getPointedPosition(); BlockPos getPointedPosition();
default boolean isConsole() { default boolean isConsole() {
return false; return this instanceof Server;
} }
default boolean isPlayer() { default boolean isPlayer() {

View file

@ -3,11 +3,10 @@ package server.command;
import common.entity.Entity; import common.entity.Entity;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.Position; import common.util.Position;
import server.Server;
public record FixedExecutor(Server server, String getExecId, String getExecName, Position getExecPos) implements Executor { public record FixedExecutor(Executor delegate, Position getExecPos) implements Executor {
public void logConsole(String msg) { public void logConsole(String msg) {
this.server.logConsole(msg); this.delegate.logConsole(msg);
} }
public Entity getPointedEntity() { public Entity getPointedEntity() {
@ -17,8 +16,4 @@ public record FixedExecutor(Server server, String getExecId, String getExecName,
public BlockPos getPointedPosition() { public BlockPos getPointedPosition() {
return null; return null;
} }
public boolean isConsole() {
return true;
}
} }

View file

@ -17,7 +17,7 @@ public class CommandAdmin extends Command {
public void exec(CommandEnvironment env, Executor exec, User user) { public void exec(CommandEnvironment env, Executor exec, User user) {
user.setAdmin(true); user.setAdmin(true);
if(user.isOnline()) if(user.isOnline())
((Player)user).logConsole("Du hast Administatorrechte von %s bekommen", exec.getExecId()); ((Player)user).logConsole("Du hast Administatorrechte von %s bekommen", exec.isPlayer() ? ((Player)exec).getUser() : "der Konsole");
exec.logConsole("%s ist jetzt ein Admin", user.getUser()); exec.logConsole("%s ist jetzt ein Admin", user.getUser());
} }
} }

View file

@ -0,0 +1,32 @@
package server.command.commands;
import java.util.List;
import common.entity.Entity;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.FixedExecutor;
import server.command.UserPolicy;
public class CommandAt extends Command {
public CommandAt() {
super("@");
this.addEntityList("entities", false, UserPolicy.NON_ADMINS_NOT_SELF);
this.addString("command", false);
}
public Object exec(CommandEnvironment env, Executor exec, List<Entity> entities, String command) {
int done = 0;
for(Entity entity : entities) {
if(entity.isEntityAlive()) {
env.execute(command, new FixedExecutor(exec, entity.getPos()));
done++;
}
}
if(done > 1)
exec.logConsole("%d Objekte gefunden", done);
return done;
}
}

View file

@ -17,7 +17,7 @@ import server.command.RunException;
import server.command.StringCompleter; import server.command.StringCompleter;
public class CommandHelp extends Command { public class CommandHelp extends Command {
public CommandHelp(CommandEnvironment env) { public CommandHelp() {
super("help"); super("help");
this.setParamsOptional(); this.setParamsOptional();

View file

@ -1904,14 +1904,6 @@ public class Player extends User implements ICrafting, Executor, IPlayer
this.addConsole(msg); this.addConsole(msg);
} }
public String getExecId() {
return this.getUser();
}
public String getExecName() {
return this.entity != null ? this.entity.getCommandName() : this.getUser();
}
public Position getExecPos() { public Position getExecPos() {
return this.entity != null ? this.entity.getPos() : null; return this.entity != null ? this.entity.getPos() : null;
} }