diff --git a/client/build.gradle.kts b/client/build.gradle.kts index d5d492e..78abd8c 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -38,7 +38,7 @@ application { mainClass = "client.Client" tasks.run.get().workingDir = rootProject.file("dev/client") tasks.run.get().workingDir.mkdirs() - tasks.run.get().systemProperties.put("crash.nodump", "") + tasks.run.get().systemProperties.put("runtime.devmode", "") } tasks.shadowJar { diff --git a/client/src/main/java/client/Client.java b/client/src/main/java/client/Client.java index d8444ef..65c1453 100755 --- a/client/src/main/java/client/Client.java +++ b/client/src/main/java/client/Client.java @@ -19,6 +19,7 @@ import java.util.ArrayDeque; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Queue; @@ -161,7 +162,6 @@ import common.packet.CPacketAction.Action; import common.potion.Potion; import common.potion.PotionEffect; import common.properties.IProperty; -import common.rng.Random; import common.sound.EventType; import common.sound.PositionedSound; import common.util.BlockPos; @@ -2251,8 +2251,6 @@ public class Client implements IThreadListener { } 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)) System.exit(1); 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() { - public void execute(Keysym key) { - if(Client.this.getNetHandler() != null) { - Client.this.getNetHandler().getConnection().sendPacket(new CPacketMessage(CPacketMessage.Type.COMMAND, "shutdown"), new GenericFutureListener>() { - public void operationComplete(Future u) throws Exception { - try { - Thread.sleep(1000L); + if(Util.DEVMODE) + this.registerDebug(Keysym.AE, "Programm sofort beenden und server beenden", new DebugRunner() { + public void execute(Keysym key) { + if(Client.this.getNetHandler() != null) { + Client.this.getNetHandler().getConnection().sendPacket(new CPacketMessage(CPacketMessage.Type.COMMAND, "shutdown"), new GenericFutureListener>() { + public void operationComplete(Future u) throws Exception { + 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) { @@ -2774,12 +2773,19 @@ public class Client implements IThreadListener { public static void main(String[] args) { long time = System.currentTimeMillis(); Util.checkPlatform(); + Thread.currentThread().setName("Render thread"); + Locale.setDefault(Locale.ROOT); + Util.setupHandlers(); 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(); ModelBlock.setAsProvider(); - Registry.setup("Render thread"); + Registry.register(); UniverseRegistry.register(); + Log.setSync(CLIENT); CLIENT.run(time); Window.end(); } @@ -2840,26 +2846,6 @@ public class Client implements IThreadListener { 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 getVar(String name) { return (T)cvars.get(name); } diff --git a/common/src/main/java/common/init/Registry.java b/common/src/main/java/common/init/Registry.java index c01f70e..fecbfde 100755 --- a/common/src/main/java/common/init/Registry.java +++ b/common/src/main/java/common/init/Registry.java @@ -1,23 +1,7 @@ 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 { - private static boolean crashed; - - private static void register() { + public static void register() { NameRegistry.register(); BlockRegistry.register(); FlammabilityRegistry.register(); @@ -30,105 +14,4 @@ public abstract class Registry { EntityRegistry.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(); - } - } - } - }); - } } diff --git a/common/src/main/java/common/util/Util.java b/common/src/main/java/common/util/Util.java index 8208f0d..2fc2605 100644 --- a/common/src/main/java/common/util/Util.java +++ b/common/src/main/java/common/util/Util.java @@ -1,17 +1,29 @@ package common.util; +import java.awt.Desktop; 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.Locale; import java.util.Map; import java.util.function.Function; +import javax.imageio.ImageIO; import javax.swing.JOptionPane; import common.Version; import common.collect.Lists; import common.collect.Maps; import common.log.Log; +import common.rng.Random; public abstract class Util { 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 int PROTOCOL = Version.MAJOR << 16 | Version.MINOR << 8 | Version.PATCH; 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) { StringBuilder sb = new StringBuilder(); @@ -44,100 +58,7 @@ public abstract class Util { } 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) { if(str2.length() > str1.length()) 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 getKeyValue(String text, char separator) { int index = text.indexOf(separator); if(index == -1) diff --git a/server/build.gradle.kts b/server/build.gradle.kts index 1199cc7..86f419c 100644 --- a/server/build.gradle.kts +++ b/server/build.gradle.kts @@ -18,7 +18,7 @@ application { mainClass = "server.Server" tasks.run.get().workingDir = rootProject.file("dev/server") 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` } diff --git a/server/src/main/java/server/Server.java b/server/src/main/java/server/Server.java index 5b3e600..c65feec 100755 --- a/server/src/main/java/server/Server.java +++ b/server/src/main/java/server/Server.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Queue; import java.util.concurrent.Callable; @@ -96,7 +97,7 @@ import server.biome.GenBiome; import server.clipboard.ReorderRegistry; import server.clipboard.RotationRegistry; import server.command.CommandEnvironment; -import server.command.FixedExecutor; +import server.command.Executor; import server.network.HandshakeHandler; import server.network.Player; import server.network.User; @@ -106,7 +107,7 @@ import server.world.Converter; import server.world.Region; import server.world.WorldServer; -public final class Server implements IThreadListener { +public final class Server implements IThreadListener, Executor { private static final LazyLoader SERVER_NIO_EVENTLOOP = new LazyLoader() { protected NioEventLoopGroup load() { 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) { long time = System.currentTimeMillis(); Util.checkPlatform(); + Thread.currentThread().setName("Server thread"); + Locale.setDefault(Locale.ROOT); + Util.setupHandlers(); Log.init(); - Registry.setup("Server thread"); - Log.SYSTEM.info("Starte " + Version.NAME + " Server Version " + Util.VERSION + " (Protokoll #" + Util.PROTOCOL + ")"); + Log.SYSTEM.info("Java " + System.getProperty("java.version")); + 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(); UniverseRegistry.register(); RotationRegistry.register(); ReorderRegistry.register(); final Server server = new Server(); - Registry.addShutdownHook(new Runnable() { + Util.addShutdownHook(new Runnable() { public void run() { server.stopServer(); Log.flushLog(); @@ -224,7 +231,7 @@ public final class Server implements IThreadListener { String version = tag.hasString("Version") ? tag.getString("Version") : null; version = version != null && version.isEmpty() ? "" : version; 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("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(lastPlayed))); if(tag.hasByteArray("PrivateKey") && tag.hasByteArray("PublicKey")) { @@ -403,35 +410,9 @@ public final class Server implements IThreadListener { this.keyPair = EncryptUtil.createKeypair(); } 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.dimensions.put(this.space.dimension.getDimensionId(), this.space); 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); for(Dimension dim : UniverseRegistry.getDimensions()) { if(WorldServer.needsLoading(dim)) { @@ -462,7 +443,7 @@ public final class Server implements IThreadListener { final String cmd = line; Server.this.schedule(new Runnable() { 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; total *= total; Log.TICK.info("Generiere und lade Welt"); -// WorldServer world = this.getWorld(Config.spawnDim); -// world = world == null ? this.space : world; bx = bx >> 4; bz = bz >> 4; 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() { -// 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(); synchronized(this.queue) { while(!this.queue.isEmpty()) { @@ -741,22 +685,6 @@ public final class Server implements IThreadListener { 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) { WorldServer world = this.getWorld(origin.getDimension()); world = world == null ? this.space : world; @@ -806,9 +734,8 @@ public final class Server implements IThreadListener { player.readTags(tag); else player.onInitialSpawn(null); -// player.setWorld(world); 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 " + 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 SPacketWorld(WorldServer.clampGravity(), SVars.dayCycle, SVars.timeFlow)); -// conn.initializeStats(); this.sendPacket(new SPacketPlayerListItem(false, conn)); world.spawnEntityInWorld(player); @@ -945,7 +871,6 @@ public final class Server implements IThreadListener { else { Position rpos = this.getRandomSpawnPosition(origin); 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); if(bed != null ? SVars.checkBed : SVars.spawnRadius >= 0) { @@ -981,20 +906,17 @@ public final class Server implements IThreadListener { oldWorld.untrackEntity(old); oldWorld.removePlayer(old); oldWorld.removePlayerEntityDangerously(old); -// old.dead = false; WorldServer world = tag == null ? this.space : this.getWorld(tag.getInt("Dimension")); world = world == null ? this.space : world; 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) nplayer.readTags(tag); else nplayer.onInitialSpawn(null); -// nplayer.clonePlayer(old); nplayer.setId(old.getId()); 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.addPlayer(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.setPlayerLocation(nplayer.posX, nplayer.posY, nplayer.posZ, nplayer.rotYaw, nplayer.rotPitch); conn.sendPacket(new SPacketSetExperience(nplayer.experience, nplayer.experienceTotal, nplayer.experienceLevel)); -// conn.initializeStats(); conn.addSelfToInternalCraftingInventory(); nplayer.setHealth(nplayer.getHealth()); 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) { WorldServer oldWorld = (WorldServer)player.getServerWorld(); // this.getWorld(player.dimension); -// player.dimension = dimension; WorldServer newWorld = this.getWorld(dimension); player.connection.sendPacket(new SPacketRespawn(newWorld.dimension, EntityRegistry.getEntityID(player), player.connection.isInEditor())); 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); if(pos != null) player.setRotationYawHead(yaw); -// player.interactManager.setWorld(newWorld); this.updateTimeAndWeatherForPlayer((Player)player.connection, newWorld); this.syncPlayerInventory(player); for(PotionEffect effect : player.getEffects()) { @@ -1181,10 +1100,6 @@ public final class Server implements IThreadListener { public Map getWarps() { return this.warps; } -// -// public void start() { -// this.serverThread.start(); -// } private void stopServer() { if(!this.stopped) { @@ -1204,7 +1119,6 @@ public final class Server implements IThreadListener { try { if(this.endpoint != null) 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); this.endpoint = ((ServerBootstrap)((ServerBootstrap)(new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ChannelInitializer() { 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); } - public void logConsole(String message) { - Log.CONSOLE.info(message); - } - public PublicKey getPublicKey() { return this.keyPair.getPublic(); } @@ -1257,4 +1167,20 @@ public final class Server implements IThreadListener { public PrivateKey getPrivateKey() { 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; + } } diff --git a/server/src/main/java/server/command/CommandEnvironment.java b/server/src/main/java/server/command/CommandEnvironment.java index 788921c..12d2a92 100644 --- a/server/src/main/java/server/command/CommandEnvironment.java +++ b/server/src/main/java/server/command/CommandEnvironment.java @@ -163,6 +163,7 @@ public class CommandEnvironment { } public void execute(String cmd, Executor exec) { + Executor prev = this.currentExecutor; this.currentExecutor = exec; try { this.execute(cmd, true); @@ -180,7 +181,7 @@ public class CommandEnvironment { Log.CONSOLE.error(t, "Fehler beim Ausführen von Befehl '%s'", cmd); } finally { - this.currentExecutor = null; + this.currentExecutor = prev; this.previousOutput = null; this.variables.clear(); } @@ -221,22 +222,13 @@ public class CommandEnvironment { } 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() { public String get() { return CommandEnvironment.this.previousOutput == null ? null : CommandEnvironment.this.previousOutput.toString(); } }); + this.registerExecutable(new CommandHelp()); this.registerExecutable(new CommandSpawn()); this.registerExecutable(new CommandPotion()); this.registerExecutable(new CommandMilk()); @@ -267,7 +259,6 @@ public class CommandEnvironment { this.registerExecutable(new CommandClear()); this.registerExecutable(new CommandEntity()); this.registerExecutable(new CommandItem()); - - this.registerExecutable(new CommandHelp(this)); + this.registerExecutable(new CommandAt()); } } diff --git a/server/src/main/java/server/command/Executor.java b/server/src/main/java/server/command/Executor.java index 193de3c..55b1935 100644 --- a/server/src/main/java/server/command/Executor.java +++ b/server/src/main/java/server/command/Executor.java @@ -3,18 +3,17 @@ package server.command; import common.entity.Entity; import common.util.BlockPos; import common.util.Position; +import server.Server; import server.network.Player; public interface Executor { void logConsole(String msg); - String getExecId(); - String getExecName(); Position getExecPos(); Entity getPointedEntity(); BlockPos getPointedPosition(); default boolean isConsole() { - return false; + return this instanceof Server; } default boolean isPlayer() { diff --git a/server/src/main/java/server/command/FixedExecutor.java b/server/src/main/java/server/command/FixedExecutor.java index 79a87da..6095089 100644 --- a/server/src/main/java/server/command/FixedExecutor.java +++ b/server/src/main/java/server/command/FixedExecutor.java @@ -3,11 +3,10 @@ package server.command; import common.entity.Entity; import common.util.BlockPos; 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) { - this.server.logConsole(msg); + this.delegate.logConsole(msg); } public Entity getPointedEntity() { @@ -17,8 +16,4 @@ public record FixedExecutor(Server server, String getExecId, String getExecName, public BlockPos getPointedPosition() { return null; } - - public boolean isConsole() { - return true; - } } diff --git a/server/src/main/java/server/command/commands/CommandAdmin.java b/server/src/main/java/server/command/commands/CommandAdmin.java index 4ea2364..dee122c 100644 --- a/server/src/main/java/server/command/commands/CommandAdmin.java +++ b/server/src/main/java/server/command/commands/CommandAdmin.java @@ -17,7 +17,7 @@ public class CommandAdmin extends Command { public void exec(CommandEnvironment env, Executor exec, User user) { user.setAdmin(true); 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()); } } diff --git a/server/src/main/java/server/command/commands/CommandAt.java b/server/src/main/java/server/command/commands/CommandAt.java new file mode 100644 index 0000000..c20e451 --- /dev/null +++ b/server/src/main/java/server/command/commands/CommandAt.java @@ -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 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; + } +} diff --git a/server/src/main/java/server/command/commands/CommandHelp.java b/server/src/main/java/server/command/commands/CommandHelp.java index 9a667ab..bcf77e8 100644 --- a/server/src/main/java/server/command/commands/CommandHelp.java +++ b/server/src/main/java/server/command/commands/CommandHelp.java @@ -17,7 +17,7 @@ import server.command.RunException; import server.command.StringCompleter; public class CommandHelp extends Command { - public CommandHelp(CommandEnvironment env) { + public CommandHelp() { super("help"); this.setParamsOptional(); diff --git a/server/src/main/java/server/network/Player.java b/server/src/main/java/server/network/Player.java index 85a2687..962faf1 100755 --- a/server/src/main/java/server/network/Player.java +++ b/server/src/main/java/server/network/Player.java @@ -1904,14 +1904,6 @@ public class Player extends User implements ICrafting, Executor, IPlayer this.addConsole(msg); } - public String getExecId() { - return this.getUser(); - } - - public String getExecName() { - return this.entity != null ? this.entity.getCommandName() : this.getUser(); - } - public Position getExecPos() { return this.entity != null ? this.entity.getPos() : null; }