add server
This commit is contained in:
parent
d5269922b9
commit
76ecfb39ab
25 changed files with 603 additions and 520 deletions
|
@ -1,34 +1,25 @@
|
||||||
package game;
|
package game;
|
||||||
|
|
||||||
import java.awt.Desktop;
|
|
||||||
import java.awt.GraphicsEnvironment;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
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.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.net.IDN;
|
import java.net.IDN;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayDeque;
|
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;
|
||||||
|
@ -40,8 +31,6 @@ import java.util.concurrent.FutureTask;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.opengl.GL13;
|
import org.lwjgl.opengl.GL13;
|
||||||
|
|
||||||
|
@ -92,7 +81,6 @@ import game.item.ItemStack;
|
||||||
import game.log.Log;
|
import game.log.Log;
|
||||||
import game.log.LogLevel;
|
import game.log.LogLevel;
|
||||||
import game.log.Message;
|
import game.log.Message;
|
||||||
import game.log.NettyLogger;
|
|
||||||
import game.material.Material;
|
import game.material.Material;
|
||||||
import game.model.ModelManager;
|
import game.model.ModelManager;
|
||||||
import game.network.IThreadListener;
|
import game.network.IThreadListener;
|
||||||
|
@ -167,7 +155,6 @@ import game.world.Region;
|
||||||
import game.world.State;
|
import game.world.State;
|
||||||
import game.world.World;
|
import game.world.World;
|
||||||
import game.world.WorldClient;
|
import game.world.WorldClient;
|
||||||
import game.world.WorldServer;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Een net ganz funktionierndes Programm ...
|
Een net ganz funktionierndes Programm ...
|
||||||
|
@ -409,7 +396,6 @@ public class Game implements IThreadListener {
|
||||||
|
|
||||||
@Variable(name = "srv_port", category = CVarCategory.SYSTEM, min = 0, max = 65535, display = "Standard Hosting-Port")
|
@Variable(name = "srv_port", category = CVarCategory.SYSTEM, min = 0, max = 65535, display = "Standard Hosting-Port")
|
||||||
public int port = Config.PORT;
|
public int port = Config.PORT;
|
||||||
public int bind = -1;
|
|
||||||
|
|
||||||
@Variable(name = "snd_enabled", category = CVarCategory.SOUND, display = "Tonausgabe")
|
@Variable(name = "snd_enabled", category = CVarCategory.SOUND, display = "Tonausgabe")
|
||||||
public boolean soundEnabled = true;
|
public boolean soundEnabled = true;
|
||||||
|
@ -418,12 +404,13 @@ public class Game implements IThreadListener {
|
||||||
@Variable(name = "snd_frame_size", category = CVarCategory.SOUND, min = 2, max = 8192, display = "PCM-Intervall")
|
@Variable(name = "snd_frame_size", category = CVarCategory.SOUND, min = 2, max = 8192, display = "PCM-Intervall")
|
||||||
public int soundFrameSize = 32;
|
public int soundFrameSize = 32;
|
||||||
|
|
||||||
private Server server;
|
private ServerProcess server;
|
||||||
|
private String serverInfo;
|
||||||
|
private int lastServerTick;
|
||||||
private AudioInterface audio;
|
private AudioInterface audio;
|
||||||
private long start;
|
private long start;
|
||||||
private boolean cfgDirty;
|
private boolean cfgDirty;
|
||||||
private String buffer = "";
|
private String buffer = "";
|
||||||
private boolean crashed;
|
|
||||||
private boolean waitingForFile;
|
private boolean waitingForFile;
|
||||||
private boolean refreshing;
|
private boolean refreshing;
|
||||||
|
|
||||||
|
@ -450,20 +437,20 @@ public class Game implements IThreadListener {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect(String address, int port, String user, String pass, String access) {
|
public void connect(String address, int port, String user, String pass, String access, byte[] local) {
|
||||||
Log.JNI.info("Verbinde zu " + address + ":" + port);
|
Log.JNI.info("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port);
|
||||||
NetConnection connection = null;
|
NetConnection connection = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
connection = NetConnection.createNetworkManagerAndConnect(InetAddress.getByName(IDN.toASCII(address)), port);
|
connection = NetConnection.createNetworkManagerAndConnect(address == null ? InetAddress.getLoopbackAddress() : InetAddress.getByName(IDN.toASCII(address)), port);
|
||||||
connection.setNetHandler(new ClientLoginHandler(connection, this));
|
connection.setNetHandler(new ClientLoginHandler(connection, this));
|
||||||
connection.sendPacket(new HPacketHandshake(Config.PROTOCOL));
|
connection.sendPacket(new HPacketHandshake(Config.PROTOCOL));
|
||||||
connection.sendPacket(new LPacketPasswordResponse(user, access, pass));
|
connection.sendPacket(new LPacketPasswordResponse(user, access, pass, local));
|
||||||
}
|
}
|
||||||
catch (UnknownHostException u)
|
catch (UnknownHostException u)
|
||||||
{
|
{
|
||||||
Log.JNI.error(u, "Konnte nicht zu Server verbinden");
|
Log.JNI.error(u, "Konnte nicht zu Server verbinden");
|
||||||
this.disconnected("Unbekannter Hostname: " + address);
|
this.disconnected("Unbekannter Hostname: " + (address == null ? "localhost" : address));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -475,17 +462,6 @@ public class Game implements IThreadListener {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connectToIntegrated(Server server, String user) {
|
|
||||||
this.debugWorld = server.getFolder() == null;
|
|
||||||
// this.displayGuiScreen(null);
|
|
||||||
SocketAddress socket = server.setLocalEndpoint();
|
|
||||||
NetConnection connection = NetConnection.provideLocalClient(socket);
|
|
||||||
connection.setNetHandler(new ClientLoginHandler(connection, this));
|
|
||||||
connection.sendPacket(new HPacketHandshake(Config.PROTOCOL));
|
|
||||||
connection.sendPacket(new LPacketPasswordResponse(user, "", ""));
|
|
||||||
this.connection = connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unloadWorld() {
|
public void unloadWorld() {
|
||||||
ClientPlayer netHandler = this.getNetHandler();
|
ClientPlayer netHandler = this.getNetHandler();
|
||||||
if(netHandler != null)
|
if(netHandler != null)
|
||||||
|
@ -496,6 +472,7 @@ public class Game implements IThreadListener {
|
||||||
this.connection = null;
|
this.connection = null;
|
||||||
this.theWorld = null;
|
this.theWorld = null;
|
||||||
this.thePlayer = null;
|
this.thePlayer = null;
|
||||||
|
this.serverInfo = null;
|
||||||
this.soundManager.stopSounds();
|
this.soundManager.stopSounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1013,7 +990,7 @@ public class Game implements IThreadListener {
|
||||||
int y1 = 0;
|
int y1 = 0;
|
||||||
int y2 = this.fb_y;
|
int y2 = this.fb_y;
|
||||||
// int pos = 0;
|
// int pos = 0;
|
||||||
String str = this.getLeft(this.server);
|
String str = this.getLeft();
|
||||||
// if(jstr)
|
// if(jstr)
|
||||||
// str = (*jsys.env)->GetStringUTFChars(jsys.env, jstr, NULL);
|
// str = (*jsys.env)->GetStringUTFChars(jsys.env, jstr, NULL);
|
||||||
// elem->r_dirty = 1;
|
// elem->r_dirty = 1;
|
||||||
|
@ -1624,8 +1601,14 @@ public class Game implements IThreadListener {
|
||||||
return this.itemRenderer;
|
return this.itemRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTicked() {
|
public void setTicked(String info) {
|
||||||
this.lastTicked = System.currentTimeMillis();
|
this.lastTicked = System.currentTimeMillis();
|
||||||
|
this.serverInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastTick(int tick) {
|
||||||
|
this.lastTicked = System.currentTimeMillis();
|
||||||
|
this.lastServerTick = tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePlayerMoveState()
|
public void updatePlayerMoveState()
|
||||||
|
@ -1664,7 +1647,7 @@ public class Game implements IThreadListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLeft(Server server) {
|
public String getLeft() {
|
||||||
long maxMem = Runtime.getRuntime().maxMemory();
|
long maxMem = Runtime.getRuntime().maxMemory();
|
||||||
long totalMem = Runtime.getRuntime().totalMemory();
|
long totalMem = Runtime.getRuntime().totalMemory();
|
||||||
long freeMem = Runtime.getRuntime().freeMemory();
|
long freeMem = Runtime.getRuntime().freeMemory();
|
||||||
|
@ -1767,13 +1750,8 @@ public class Game implements IThreadListener {
|
||||||
) + "\n" +
|
) + "\n" +
|
||||||
String.format("Letzte Zeitsynch.: + %d.%d s",
|
String.format("Letzte Zeitsynch.: + %d.%d s",
|
||||||
ticked / 1000L, (ticked / 100L) % 10L
|
ticked / 1000L, (ticked / 100L) % 10L
|
||||||
) + "\n" +
|
) +
|
||||||
(server != null ?
|
(this.serverInfo != null ? "\n" + this.serverInfo : "")
|
||||||
String.format("Server: %.3f T/s (%.1fx), Z: %.1f T/s, D: %.3f ms", server.getTpsRate(),
|
|
||||||
server.getTpsRate() / 20.0f,
|
|
||||||
server.getTpsTarget(), server.getAverageTps()) : "Server: <remote>") + "\n" +
|
|
||||||
(server != null ? "Geladen: " + server.getWorlds().size() + " Welten, " + WorldServer.getLoadedInfo(server) :
|
|
||||||
"Geladen: <?>")
|
|
||||||
// WorldServer world = this.server.getWorld(this.theWorld.dimension.getDimensionId());
|
// WorldServer world = this.server.getWorld(this.theWorld.dimension.getDimensionId());
|
||||||
// if(world != null)
|
// if(world != null)
|
||||||
// list.add("Seed: " + world.getSeed());
|
// list.add("Seed: " + world.getSeed());
|
||||||
|
@ -2100,7 +2078,7 @@ public class Game implements IThreadListener {
|
||||||
return;
|
return;
|
||||||
this.frameWait = 50000000L - ((n - (this.frameLast + this.frameWait)) < 50000000L ? (n - (this.frameLast + this.frameWait)) : 0L);
|
this.frameWait = 50000000L - ((n - (this.frameLast + this.frameWait)) < 50000000L ? (n - (this.frameLast + this.frameWait)) : 0L);
|
||||||
this.frameLast = n;
|
this.frameLast = n;
|
||||||
this.tickTimes[this.tickIndex++] = this.server != null ? (int)this.server.getLastTick() : 0;
|
this.tickTimes[this.tickIndex++] = this.lastServerTick;
|
||||||
if(this.tickIndex == 240) {
|
if(this.tickIndex == 240) {
|
||||||
this.tickIndex = 0;
|
this.tickIndex = 0;
|
||||||
}
|
}
|
||||||
|
@ -2369,11 +2347,13 @@ public class Game implements IThreadListener {
|
||||||
|
|
||||||
public void unload(boolean loading) {
|
public void unload(boolean loading) {
|
||||||
if(this.theWorld != null) {
|
if(this.theWorld != null) {
|
||||||
|
if(server != null)
|
||||||
|
this.performAction(Action.SHUTDOWN);
|
||||||
if(server == null && this.getNetHandler() != null)
|
if(server == null && this.getNetHandler() != null)
|
||||||
this.getNetHandler().getNetworkManager().closeChannel("Quitting");
|
this.getNetHandler().getNetworkManager().closeChannel("Quitting");
|
||||||
this.unloadWorld();
|
this.unloadWorld();
|
||||||
if(server != null)
|
// if(server != null)
|
||||||
server.shutdown();
|
// server.shutdown();
|
||||||
}
|
}
|
||||||
if(server != null) {
|
if(server != null) {
|
||||||
if(loading) {
|
if(loading) {
|
||||||
|
@ -2396,9 +2376,11 @@ public class Game implements IThreadListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startServer(File dir, String user) {
|
public void startServer(File dir, String user) {
|
||||||
server = new Server(dir);
|
byte[] key = new byte[256];
|
||||||
|
new SecureRandom().nextBytes(key);
|
||||||
|
server = new ServerProcess(dir, 1024, 4096, this.port, this.renderDistance, key);
|
||||||
server.start();
|
server.start();
|
||||||
this.displayGuiScreen(GuiLoading.makeLoadTask(server, user));
|
this.displayGuiScreen(GuiLoading.makeLoadTask(server, user, key));
|
||||||
// while(server != null && !server.isStarted()) {
|
// while(server != null && !server.isStarted()) {
|
||||||
// try {
|
// try {
|
||||||
// Thread.sleep(10L);
|
// Thread.sleep(10L);
|
||||||
|
@ -2451,16 +2433,11 @@ public class Game implements IThreadListener {
|
||||||
return ((double)rtime()) / 1000000.0;
|
return ((double)rtime()) / 1000000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(int port) {
|
|
||||||
if(server != null)
|
|
||||||
server.bind(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void distance(int distance) {
|
public void distance(int distance) {
|
||||||
if(this.renderGlobal != null)
|
if(this.renderGlobal != null)
|
||||||
this.renderGlobal.setDisplayListEntitiesDirty();
|
this.renderGlobal.setDisplayListEntitiesDirty();
|
||||||
if(this.server != null)
|
if(this.server != null && this.thePlayer != null)
|
||||||
this.server.setVar("viewDistance", "" + distance);
|
this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.SET_VIEWDIST, distance));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerDebug(Keysym key, String help, DebugRunner runner) {
|
private void registerDebug(Keysym key, String help, DebugRunner runner) {
|
||||||
|
@ -2575,13 +2552,7 @@ public class Game implements IThreadListener {
|
||||||
});
|
});
|
||||||
this.registerDebug(Keysym.W, "Server-Tick-Limit umschalten (Welt beschleunigen / Warpmodus)", new DebugRunner() {
|
this.registerDebug(Keysym.W, "Server-Tick-Limit umschalten (Welt beschleunigen / Warpmodus)", new DebugRunner() {
|
||||||
public void execute(Keysym key) {
|
public void execute(Keysym key) {
|
||||||
if(server != null) {
|
Game.this.performAction(Action.WARP_MODE);
|
||||||
server.schedule(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
server.setTpsTarget(server.getTpsTarget() < 10000.0f ? 10000.0f : 20.0f);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.registerDebug(Keysym.M, "Alle Gegenstände herbei ziehen (Magnetmodus)", new DebugRunner() {
|
this.registerDebug(Keysym.M, "Alle Gegenstände herbei ziehen (Magnetmodus)", new DebugRunner() {
|
||||||
|
@ -2662,116 +2633,9 @@ public class Game implements IThreadListener {
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
if(System.getProperty("os.name").startsWith("Windows") || System.getProperty("os.name").startsWith("Mac")) {
|
Util.checkOs();
|
||||||
String info = "Inkompatibles Betriebssystem";
|
|
||||||
String msg = "Linux oder *BSD ist erforderlich, um dieses Programm auszuführen.\n" +
|
|
||||||
"Alle Versionen von Windows und Mac OS (X) sind nicht kompatibel.";
|
|
||||||
System.err.println("#################################################################");
|
|
||||||
System.err.println("*** " + info + " ***");
|
|
||||||
System.err.println(msg);
|
|
||||||
System.err.println("#################################################################");
|
|
||||||
if(!GraphicsEnvironment.isHeadless())
|
|
||||||
JOptionPane.showMessageDialog(null, msg, info, JOptionPane.ERROR_MESSAGE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Window.init();
|
Window.init();
|
||||||
Locale.setDefault(Locale.ROOT);
|
Registry.setup("Render thread");
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
|
|
||||||
public void uncaughtException(Thread thread, Throwable e) {
|
|
||||||
System.err.println("Fehler in Thread '" + thread.getName() + "'");
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
if(INSTANCE.crashed)
|
|
||||||
System.exit(1);
|
|
||||||
if(e instanceof OutOfMemoryError) {
|
|
||||||
System.gc();
|
|
||||||
System.gc();
|
|
||||||
}
|
|
||||||
if(!thread.getName().startsWith("Thread-") || e instanceof OutOfMemoryError) {
|
|
||||||
System.err.println("Beende!");
|
|
||||||
INSTANCE.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.getId())
|
|
||||||
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");
|
|
||||||
NettyLogger.init();
|
|
||||||
Registry.register();
|
|
||||||
// game = new Game();
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread("Game Shutdown Thread") {
|
|
||||||
public void run() {
|
|
||||||
if(!INSTANCE.crashed && INSTANCE.server != null) {
|
|
||||||
try {
|
|
||||||
INSTANCE.server.stopServer();
|
|
||||||
}
|
|
||||||
catch(Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Thread.currentThread().setName("Render thread");
|
|
||||||
INSTANCE.run();
|
INSTANCE.run();
|
||||||
Window.end();
|
Window.end();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package game;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -32,6 +31,7 @@ import game.entity.npc.EntityHuman;
|
||||||
import game.entity.npc.EntityNPC;
|
import game.entity.npc.EntityNPC;
|
||||||
import game.init.Config;
|
import game.init.Config;
|
||||||
import game.init.EntityRegistry;
|
import game.init.EntityRegistry;
|
||||||
|
import game.init.Registry;
|
||||||
import game.init.UniverseRegistry;
|
import game.init.UniverseRegistry;
|
||||||
import game.log.Log;
|
import game.log.Log;
|
||||||
import game.nbt.NBTLoader;
|
import game.nbt.NBTLoader;
|
||||||
|
@ -41,8 +41,7 @@ import game.network.IThreadListener;
|
||||||
import game.network.LazyLoadBase;
|
import game.network.LazyLoadBase;
|
||||||
import game.network.NetConnection;
|
import game.network.NetConnection;
|
||||||
import game.network.NetHandler.ThreadQuickExitException;
|
import game.network.NetHandler.ThreadQuickExitException;
|
||||||
import game.network.HandshakeHandlerMemory;
|
import game.network.HandshakeHandler;
|
||||||
import game.network.HandshakeHandlerTCP;
|
|
||||||
import game.network.Player;
|
import game.network.Player;
|
||||||
import game.network.Packet;
|
import game.network.Packet;
|
||||||
import game.network.PacketDecoder;
|
import game.network.PacketDecoder;
|
||||||
|
@ -65,6 +64,7 @@ import game.packet.SPacketTimeUpdate;
|
||||||
import game.packet.SPacketWorld;
|
import game.packet.SPacketWorld;
|
||||||
import game.potion.PotionEffect;
|
import game.potion.PotionEffect;
|
||||||
import game.util.ExtMath;
|
import game.util.ExtMath;
|
||||||
|
import game.util.Util;
|
||||||
import game.world.BlockPos;
|
import game.world.BlockPos;
|
||||||
import game.world.PortalType;
|
import game.world.PortalType;
|
||||||
import game.world.Position;
|
import game.world.Position;
|
||||||
|
@ -81,23 +81,20 @@ import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.local.LocalAddress;
|
|
||||||
import io.netty.channel.local.LocalServerChannel;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
import io.netty.util.concurrent.GenericFutureListener;
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
|
|
||||||
public final class Server implements Runnable, IThreadListener {
|
public final class Server implements IThreadListener {
|
||||||
private static final LazyLoadBase<NioEventLoopGroup> SERVER_NIO_EVENTLOOP = new LazyLoadBase<NioEventLoopGroup>() {
|
private static final LazyLoadBase<NioEventLoopGroup> SERVER_NIO_EVENTLOOP = new LazyLoadBase<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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final Thread serverThread;
|
private final Thread serverThread = Thread.currentThread();
|
||||||
private final List<NetConnection> clients = Collections.<NetConnection>synchronizedList(Lists.<NetConnection>newArrayList());
|
private final List<NetConnection> clients = Collections.<NetConnection>synchronizedList(Lists.<NetConnection>newArrayList());
|
||||||
private final List<Player> players = Lists.<Player>newArrayList();
|
private final List<Player> players = Lists.<Player>newArrayList();
|
||||||
private final Map<String, Player> usermap = Maps.<String, Player>newHashMap();
|
private final Map<String, Player> usermap = Maps.<String, Player>newHashMap();
|
||||||
|
@ -109,17 +106,11 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
private final List<Dimension> unload = Lists.<Dimension>newArrayList();
|
private final List<Dimension> unload = Lists.<Dimension>newArrayList();
|
||||||
private final Map<String, Position> warps = Maps.<String, Position>newTreeMap();
|
private final Map<String, Position> warps = Maps.<String, Position>newTreeMap();
|
||||||
private final CommandEnvironment scriptEnv = new CommandEnvironment(this);
|
private final CommandEnvironment scriptEnv = new CommandEnvironment(this);
|
||||||
// private final String owner;
|
|
||||||
private final File playerDir;
|
|
||||||
private final File baseDir;
|
|
||||||
// private final int port;
|
|
||||||
private final boolean debug;
|
private final boolean debug;
|
||||||
|
|
||||||
private WorldServer space;
|
private WorldServer space;
|
||||||
private ChannelFuture endpoint;
|
private ChannelFuture endpoint;
|
||||||
private ChannelFuture localEndpoint;
|
|
||||||
private String localUser;
|
private String localUser;
|
||||||
private String message;
|
|
||||||
|
|
||||||
private boolean running = true;
|
private boolean running = true;
|
||||||
private boolean stopped;
|
private boolean stopped;
|
||||||
|
@ -140,28 +131,29 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
private int pingTimer;
|
private int pingTimer;
|
||||||
private int syncTimer;
|
private int syncTimer;
|
||||||
private int perfTimer;
|
private int perfTimer;
|
||||||
private int progress = -1;
|
|
||||||
private int total = 0;
|
|
||||||
|
|
||||||
Server(File dir) {
|
public static void main(String[] args) {
|
||||||
// this.owner = owner;
|
Util.checkOs();
|
||||||
this.serverThread = new Thread(this, "Server thread");
|
Registry.setup("Server thread");
|
||||||
this.baseDir = dir; // dir != null ? new File(dir) : null;
|
final Server server = new Server(false);
|
||||||
this.playerDir = new File(this.baseDir, "players");
|
Registry.addShutdownHook(new Runnable() {
|
||||||
this.debug = this.baseDir == null;
|
public void run() {
|
||||||
// this.port = port;
|
server.stopServer();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
server.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Server(boolean debug) {
|
||||||
|
this.debug = debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandEnvironment getScriptEnvironment() {
|
public CommandEnvironment getScriptEnvironment() {
|
||||||
return this.scriptEnv;
|
return this.scriptEnv;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isStarted() {
|
|
||||||
return this.started;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getUsers() {
|
public String[] getUsers() {
|
||||||
String[] list = this.debug ? null : this.playerDir.list();
|
String[] list = this.debug ? null : new File("players").list();
|
||||||
if(list == null) {
|
if(list == null) {
|
||||||
list = new String[0];
|
list = new String[0];
|
||||||
}
|
}
|
||||||
|
@ -182,8 +174,8 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
|
|
||||||
public void saveWorldInfo() {
|
public void saveWorldInfo() {
|
||||||
if(!this.debug) {
|
if(!this.debug) {
|
||||||
Region.saveWorldInfo(this.baseDir, this.space.getDayTime(), this.localUser);
|
Region.saveWorldInfo(null, this.space.getDayTime(), this.localUser);
|
||||||
WorldServer.saveWarps(this.baseDir, this.warps);
|
WorldServer.saveWarps(this.warps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +184,7 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
return null;
|
return null;
|
||||||
NBTTagCompound tag = null;
|
NBTTagCompound tag = null;
|
||||||
try {
|
try {
|
||||||
File dat = new File(this.playerDir, user + ".nbt");
|
File dat = new File(new File("players"), user + ".nbt");
|
||||||
|
|
||||||
if(dat.exists() && dat.isFile()) {
|
if(dat.exists() && dat.isFile()) {
|
||||||
tag = NBTLoader.readGZip(dat);
|
tag = NBTLoader.readGZip(dat);
|
||||||
|
@ -235,7 +227,7 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
private void startProgress(boolean save, int amount) {
|
private void startProgress(boolean save, int amount) {
|
||||||
this.setTotal(amount);
|
this.setTotal(amount);
|
||||||
this.setProgress(0);
|
this.setProgress(0);
|
||||||
Log.JNI.info((save ? "Speichere" : "Generiere und lade") + " Level " + (this.baseDir == null ? "." : this.baseDir.getName()));
|
Log.JNI.info((save ? "Speichere" : "Generiere und lade") + " Welt");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unloadWorld(WorldServer world) {
|
public void unloadWorld(WorldServer world) {
|
||||||
|
@ -258,15 +250,15 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
Log.JNI.info("Starte Server Version " + Config.VERSION);
|
Log.JNI.info("Starte Server Version " + Config.VERSION);
|
||||||
if(!this.debug) {
|
if(!this.debug) {
|
||||||
this.setMessage("Welt wird erstellt und geladen");
|
this.setMessage("Welt wird erstellt und geladen");
|
||||||
FolderInfo info = Region.loadWorldInfo(this.baseDir);
|
FolderInfo info = Region.loadWorldInfo(null);
|
||||||
// if(dtime == -1L) // {
|
// if(dtime == -1L) // {
|
||||||
// dtime = World.START_TIME;
|
// dtime = World.START_TIME;
|
||||||
//// Config.set("spawnDim", "1", null);
|
//// Config.set("spawnDim", "1", null);
|
||||||
//// }
|
//// }
|
||||||
this.worlds.add(this.space = new WorldServer(this, this.baseDir, info == null ? World.START_TIME : info.time,
|
this.worlds.add(this.space = new WorldServer(this, info == null ? World.START_TIME : info.time,
|
||||||
Space.INSTANCE, false));
|
Space.INSTANCE, false));
|
||||||
this.dimensions.put(this.space.dimension.getDimensionId(), this.space);
|
this.dimensions.put(this.space.dimension.getDimensionId(), this.space);
|
||||||
this.playerDir.mkdirs();
|
new File("players").mkdirs();
|
||||||
// if(Config.spawnY < 0) {
|
// if(Config.spawnY < 0) {
|
||||||
// WorldServer world = this.getWorld(Config.spawnDim);
|
// WorldServer world = this.getWorld(Config.spawnDim);
|
||||||
// world = world == null ? this.space : world;
|
// world = world == null ? this.space : world;
|
||||||
|
@ -297,17 +289,17 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
Config.set("weatherChanges", "false", null);
|
Config.set("weatherChanges", "false", null);
|
||||||
Config.set("mobSpawning", "false", null);
|
Config.set("mobSpawning", "false", null);
|
||||||
Config.set("spawnRadius", "0", null);
|
Config.set("spawnRadius", "0", null);
|
||||||
this.worlds.add(this.space = new WorldServer(this, null, World.START_TIME,
|
this.worlds.add(this.space = new WorldServer(this, World.START_TIME,
|
||||||
Space.INSTANCE, true));
|
Space.INSTANCE, true));
|
||||||
this.dimensions.put(this.space.dimension.getDimensionId(), this.space);
|
this.dimensions.put(this.space.dimension.getDimensionId(), this.space);
|
||||||
}
|
}
|
||||||
this.setTpsTarget(20.0f);
|
this.setTpsTarget(20.0f);
|
||||||
if(!this.debug) {
|
if(!this.debug) {
|
||||||
for(Dimension dim : UniverseRegistry.getDimensions()) {
|
for(Dimension dim : UniverseRegistry.getDimensions()) {
|
||||||
if(WorldServer.needsLoading(this.baseDir, dim)) {
|
if(WorldServer.needsLoading(dim)) {
|
||||||
this.getWorld(dim.getDimensionId()).loadForcedChunks();
|
this.getWorld(dim.getDimensionId()).loadForcedChunks();
|
||||||
}
|
}
|
||||||
WorldServer.loadWarps(this.baseDir, dim, this.warps);
|
WorldServer.loadWarps(dim, this.warps);
|
||||||
}
|
}
|
||||||
// this.openLAN();
|
// this.openLAN();
|
||||||
}
|
}
|
||||||
|
@ -339,17 +331,22 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
this.lastPoll = this.currentTime;
|
this.lastPoll = this.currentTime;
|
||||||
this.ticksDone = 0L;
|
this.ticksDone = 0L;
|
||||||
}
|
}
|
||||||
this.started = true;
|
if(!this.started) {
|
||||||
|
this.started = true;
|
||||||
|
this.sendPipeIPC("running", true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.stopServer();
|
this.stopServer();
|
||||||
this.stopped = true;
|
this.stopped = true;
|
||||||
|
this.sendPipeIPC("running", false);
|
||||||
}
|
}
|
||||||
catch(Throwable e) {
|
catch(Throwable e) {
|
||||||
Log.JNI.error(e, "Fehler beim Beenden des Servers");
|
Log.JNI.error(e, "Fehler beim Beenden des Servers");
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
this.stopped = true;
|
this.stopped = true;
|
||||||
|
this.sendPipeIPC("running", false);
|
||||||
Log.JNI.info("Server wurde beendet");
|
Log.JNI.info("Server wurde beendet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,8 +362,8 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
bx = bx >> 4;
|
bx = bx >> 4;
|
||||||
bz = bz >> 4;
|
bz = bz >> 4;
|
||||||
long last = System.currentTimeMillis();
|
long last = System.currentTimeMillis();
|
||||||
for(int x = -Config.distance; x <= Config.distance && this.running; x++) {
|
for(int x = -Config.distance; x <= Config.distance; x++) {
|
||||||
for(int z = -Config.distance; z <= Config.distance && this.running; z++) {
|
for(int z = -Config.distance; z <= Config.distance; z++) {
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
if(time - last >= 10L) {
|
if(time - last >= 10L) {
|
||||||
this.setProgress(done);
|
this.setProgress(done);
|
||||||
|
@ -436,7 +433,7 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(++this.syncTimer == 20) {
|
if(++this.syncTimer == 20) {
|
||||||
this.sendPacket(new SPacketTimeUpdate(this.space.getDayTime()));
|
this.sendPacket(new SPacketTimeUpdate(this.space.getDayTime(), this.getInfo()));
|
||||||
this.syncTimer = 0;
|
this.syncTimer = 0;
|
||||||
}
|
}
|
||||||
this.ticked.clear();
|
this.ticked.clear();
|
||||||
|
@ -477,7 +474,7 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
Dimension dim = UniverseRegistry.getDimension(dimension);
|
Dimension dim = UniverseRegistry.getDimension(dimension);
|
||||||
if(dim == null)
|
if(dim == null)
|
||||||
return null;
|
return null;
|
||||||
world = new WorldServer(this, this.baseDir, this.space.getDayTime(),
|
world = new WorldServer(this, this.space.getDayTime(),
|
||||||
dim, this.debug);
|
dim, this.debug);
|
||||||
this.worlds.add(world);
|
this.worlds.add(world);
|
||||||
this.dimensions.put(dimension, world);
|
this.dimensions.put(dimension, world);
|
||||||
|
@ -498,10 +495,6 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
return this.worlds;
|
return this.worlds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isStopped() {
|
|
||||||
return this.stopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long[] getTickTimes() {
|
public long[] getTickTimes() {
|
||||||
return this.tickTimes;
|
return this.tickTimes;
|
||||||
}
|
}
|
||||||
|
@ -548,40 +541,16 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
return this.usermap.get(user);
|
return this.usermap.get(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
synchronized(this) {
|
|
||||||
return this.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProgress() {
|
|
||||||
synchronized(this) {
|
|
||||||
return this.progress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTotal() {
|
|
||||||
synchronized(this) {
|
|
||||||
return this.total;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setMessage(String message) {
|
private void setMessage(String message) {
|
||||||
synchronized(this) {
|
this.sendPipeIPC("message", message);
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setProgress(int progress) {
|
private void setProgress(int progress) {
|
||||||
synchronized(this) {
|
this.sendPipeIPC("progress", progress);
|
||||||
this.progress = progress;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTotal(int total) {
|
private void setTotal(int total) {
|
||||||
synchronized(this) {
|
this.sendPipeIPC("total", total);
|
||||||
this.total = total;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVar(String cv, String value) {
|
public void setVar(String cv, String value) {
|
||||||
|
@ -592,10 +561,6 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFolder() {
|
|
||||||
return this.baseDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
private <V> ListenableFuture<V> callFromMainThread(Callable<V> callable) {
|
private <V> ListenableFuture<V> callFromMainThread(Callable<V> callable) {
|
||||||
if(!this.isMainThread() && !this.stopped) {
|
if(!this.isMainThread() && !this.stopped) {
|
||||||
ListenableFutureTask<V> task = ListenableFutureTask.<V>create(callable);
|
ListenableFutureTask<V> task = ListenableFutureTask.<V>create(callable);
|
||||||
|
@ -661,35 +626,33 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
Player conn = new Player(this, connection, loginUser);
|
Player conn = new Player(this, connection, loginUser);
|
||||||
if(tag != null)
|
if(tag != null)
|
||||||
conn.readFromNBT(tag);
|
conn.readFromNBT(tag);
|
||||||
if(!connection.isLocalChannel()) {
|
if(Config.playerLimit > 0 && this.players.size() >= Config.playerLimit && !conn.isAdmin())
|
||||||
if(Config.playerLimit > 0 && this.players.size() >= Config.playerLimit && !conn.getAdmin())
|
return String.format("Der Server ist voll (%d/%d)!", this.players.size(), Config.playerLimit);
|
||||||
return String.format("Der Server ist voll (%d/%d)!", this.players.size(), Config.playerLimit);
|
if(!connection.isLocalChannel() && Config.auth) {
|
||||||
if(Config.auth) {
|
if(conn.getPassword() == null) {
|
||||||
if(conn.getPassword() == null) {
|
if(!Config.register)
|
||||||
if(!Config.register)
|
return "Anmeldung neuer Accounts ist auf diesem Server deaktiviert (Whitelisted)";
|
||||||
return "Anmeldung neuer Accounts ist auf diesem Server deaktiviert (Whitelisted)";
|
if(loginPass.length() == 0)
|
||||||
if(loginPass.length() == 0)
|
return "Ein neues Passwort ist erforderlich um diesen Server zu betreten (mindestens 8 Zeichen)";
|
||||||
return "Ein neues Passwort ist erforderlich um diesen Server zu betreten (mindestens 8 Zeichen)";
|
if(loginPass.length() < 8)
|
||||||
if(loginPass.length() < 8)
|
return "Passwort ist zu kurz, mindestens 8 Zeichen";
|
||||||
return "Passwort ist zu kurz, mindestens 8 Zeichen";
|
conn.setPassword(loginPass);
|
||||||
conn.setPassword(loginPass);
|
Log.JNI.info(loginUser + " registrierte sich mit Passwort");
|
||||||
Log.JNI.info(loginUser + " registrierte sich mit Passwort");
|
}
|
||||||
}
|
else if(!conn.getPassword().equals(loginPass)) {
|
||||||
else if(!conn.getPassword().equals(loginPass)) {
|
return "Falsches Passwort";
|
||||||
return "Falsches Passwort";
|
}
|
||||||
}
|
else {
|
||||||
else {
|
Log.JNI.info(loginUser + " loggte sich mit Passwort ein");
|
||||||
Log.JNI.info(loginUser + " loggte sich mit Passwort ein");
|
}
|
||||||
}
|
}
|
||||||
}
|
if(Config.compression >= 0) {
|
||||||
if(Config.compression >= 0) {
|
connection.sendPacket(new RPacketEnableCompression(Config.compression), new ChannelFutureListener() {
|
||||||
connection.sendPacket(new RPacketEnableCompression(Config.compression), new ChannelFutureListener() {
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
connection.setCompressionTreshold(Config.compression);
|
||||||
connection.setCompressionTreshold(Config.compression);
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
connection.sendPacket(new RPacketLoginSuccess());
|
connection.sendPacket(new RPacketLoginSuccess());
|
||||||
connection.setNetHandler(conn);
|
connection.setNetHandler(conn);
|
||||||
this.players.add(conn);
|
this.players.add(conn);
|
||||||
|
@ -766,7 +729,7 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
return null;
|
return null;
|
||||||
NBTTagCompound tag = null;
|
NBTTagCompound tag = null;
|
||||||
try {
|
try {
|
||||||
File dat = new File(this.playerDir, user + ".nbt");
|
File dat = new File(new File("players"), user + ".nbt");
|
||||||
|
|
||||||
if(dat.exists() && dat.isFile()) {
|
if(dat.exists() && dat.isFile()) {
|
||||||
tag = NBTLoader.readGZip(dat);
|
tag = NBTLoader.readGZip(dat);
|
||||||
|
@ -794,8 +757,8 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
// else
|
// else
|
||||||
// etag = new NBTTagCompound();
|
// etag = new NBTTagCompound();
|
||||||
conn.writeToNBT(tag);
|
conn.writeToNBT(tag);
|
||||||
File tmp = new File(this.playerDir, conn.getUser() + ".nbt.tmp");
|
File tmp = new File(new File("players"), conn.getUser() + ".nbt.tmp");
|
||||||
File dat = new File(this.playerDir, conn.getUser() + ".nbt");
|
File dat = new File(new File("players"), conn.getUser() + ".nbt");
|
||||||
NBTLoader.writeGZip(tag, tmp);
|
NBTLoader.writeGZip(tag, tmp);
|
||||||
if(dat.exists()) {
|
if(dat.exists()) {
|
||||||
dat.delete();
|
dat.delete();
|
||||||
|
@ -1020,7 +983,7 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTimeAndWeatherForPlayer(Player conn, WorldServer world) {
|
private void updateTimeAndWeatherForPlayer(Player conn, WorldServer world) {
|
||||||
conn.sendPacket(new SPacketTimeUpdate(world.getDayTime()));
|
conn.sendPacket(new SPacketTimeUpdate(world.getDayTime(), this.getInfo()));
|
||||||
conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.SET_WEATHER, world.getWeather().getID()));
|
conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.SET_WEATHER, world.getWeather().getID()));
|
||||||
conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.RAIN_STRENGTH, world.getRainStrength()));
|
conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.RAIN_STRENGTH, world.getRainStrength()));
|
||||||
conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.DARKNESS, world.getDarkness()));
|
conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.DARKNESS, world.getDarkness()));
|
||||||
|
@ -1055,41 +1018,21 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
NetConnection manager = new NetConnection();
|
NetConnection manager = new NetConnection();
|
||||||
Server.this.clients.add(manager);
|
Server.this.clients.add(manager);
|
||||||
channel.pipeline().addLast((String)"packet_handler", (ChannelHandler)manager);
|
channel.pipeline().addLast((String)"packet_handler", (ChannelHandler)manager);
|
||||||
manager.setNetHandler(new HandshakeHandlerTCP(Server.this, manager));
|
manager.setNetHandler(new HandshakeHandler(Server.this, manager));
|
||||||
}
|
}
|
||||||
}).group(SERVER_NIO_EVENTLOOP.getValue()).localAddress((InetAddress)null, port)).bind().syncUninterruptibly();
|
}).group(SERVER_NIO_EVENTLOOP.getValue()).localAddress((InetAddress)null, port)).bind().syncUninterruptibly();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SocketAddress setLocalEndpoint() {
|
|
||||||
// ChannelFuture future;
|
|
||||||
synchronized(this.serverThread) {
|
|
||||||
if(this.localEndpoint == null) {
|
|
||||||
// throw new IllegalStateException("Lokaler Eingangspunkt bereits gesetzt");
|
|
||||||
// }
|
|
||||||
this.localEndpoint = ((ServerBootstrap)((ServerBootstrap)(new ServerBootstrap()).channel(LocalServerChannel.class)).childHandler(new ChannelInitializer<Channel>() {
|
|
||||||
protected void initChannel(Channel channel) throws Exception {
|
|
||||||
NetConnection manager = new NetConnection();
|
|
||||||
manager.setNetHandler(new HandshakeHandlerMemory(Server.this, manager));
|
|
||||||
Server.this.clients.add(manager);
|
|
||||||
channel.pipeline().addLast((String)"packet_handler", (ChannelHandler)manager);
|
|
||||||
}
|
|
||||||
}).group((EventLoopGroup)SERVER_NIO_EVENTLOOP.getValue()).localAddress(LocalAddress.ANY)).bind().syncUninterruptibly();
|
|
||||||
// this.localEndpoint = future;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.localEndpoint.channel().localAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unsetLanEndpoint() {
|
private void unsetLanEndpoint() {
|
||||||
for(Player conn : Lists.newArrayList(this.players)) {
|
for(Player conn : Lists.newArrayList(this.players)) {
|
||||||
if(!conn.isLocal())
|
if(!conn.isLocal())
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
}
|
}
|
||||||
this.terminateEndpoints(false);
|
this.terminateEndpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void terminateEndpoints(boolean local) {
|
private void terminateEndpoint() {
|
||||||
synchronized(this.serverThread) {
|
synchronized(this.serverThread) {
|
||||||
if(this.endpoint != null) {
|
if(this.endpoint != null) {
|
||||||
Log.JNI.info("Schließe Port");
|
Log.JNI.info("Schließe Port");
|
||||||
|
@ -1101,15 +1044,6 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
Log.JNI.warn("Unterbrochen beim Schließen des Kanals");
|
Log.JNI.warn("Unterbrochen beim Schließen des Kanals");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(local && this.localEndpoint != null) {
|
|
||||||
try {
|
|
||||||
this.localEndpoint.channel().close().sync();
|
|
||||||
this.localEndpoint = null;
|
|
||||||
}
|
|
||||||
catch(InterruptedException e) {
|
|
||||||
Log.JNI.warn("Unterbrochen beim Schließen des lokalen Kanals");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1128,9 +1062,6 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
manager.processReceivedPackets();
|
manager.processReceivedPackets();
|
||||||
}
|
}
|
||||||
catch(Exception e) {
|
catch(Exception e) {
|
||||||
if(manager.isLocalChannel()) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
Log.JNI.error(e, "Konnte Paket von " + manager.getCutAddress() + " nicht verarbeiten");
|
Log.JNI.error(e, "Konnte Paket von " + manager.getCutAddress() + " nicht verarbeiten");
|
||||||
manager.sendPacket(new SPacketDisconnect(), new GenericFutureListener<Future<? super Void>>() {
|
manager.sendPacket(new SPacketDisconnect(), new GenericFutureListener<Future<? super Void>>() {
|
||||||
public void operationComplete(Future<? super Void> future) throws Exception {
|
public void operationComplete(Future<? super Void> future) throws Exception {
|
||||||
|
@ -1148,12 +1079,12 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
public Map<String, Position> getWarps() {
|
public Map<String, Position> getWarps() {
|
||||||
return this.warps;
|
return this.warps;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// public void start() {
|
||||||
|
// this.serverThread.start();
|
||||||
|
// }
|
||||||
|
|
||||||
public void start() {
|
private void stopServer() {
|
||||||
this.serverThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopServer() {
|
|
||||||
if(!this.stopped) {
|
if(!this.stopped) {
|
||||||
this.setProgress(-1);
|
this.setProgress(-1);
|
||||||
this.setMessage("Stoppe server");
|
this.setMessage("Stoppe server");
|
||||||
|
@ -1162,7 +1093,7 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
for(Player conn : Lists.newArrayList(this.players)) {
|
for(Player conn : Lists.newArrayList(this.players)) {
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
}
|
}
|
||||||
this.terminateEndpoints(true);
|
this.terminateEndpoint();
|
||||||
if(this.started) {
|
if(this.started) {
|
||||||
Log.JNI.info("Speichere Spieler");
|
Log.JNI.info("Speichere Spieler");
|
||||||
this.saveAllPlayerData(true);
|
this.saveAllPlayerData(true);
|
||||||
|
@ -1203,4 +1134,14 @@ public final class Server implements Runnable, IThreadListener {
|
||||||
}));
|
}));
|
||||||
this.running = false;
|
this.running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getInfo() {
|
||||||
|
return String.format("Server: %.3f T/s (%.1fx), Z: %.1f T/s, D: %.3f ms", this.getTpsRate(), this.getTpsRate() / 20.0f, this.getTpsTarget(), this.getAverageTps()) + "\n" +
|
||||||
|
"Geladen: " + this.getWorlds().size() + " Welten, " + WorldServer.getLoadedInfo(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendPipeIPC(String key, Object value) {
|
||||||
|
System.out.println("#" + key + (value == null ? "" : " " + String.valueOf(value)));
|
||||||
|
System.out.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
114
java/src/game/ServerProcess.java
Normal file
114
java/src/game/ServerProcess.java
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
package game;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
|
||||||
|
import game.log.Log;
|
||||||
|
import game.util.Tuple;
|
||||||
|
import game.util.Util;
|
||||||
|
|
||||||
|
public class ServerProcess {
|
||||||
|
private final ProcessBuilder builder;
|
||||||
|
|
||||||
|
private Process process;
|
||||||
|
private BufferedWriter writer;
|
||||||
|
private boolean running;
|
||||||
|
private String message;
|
||||||
|
private int total;
|
||||||
|
private int progress = -1;
|
||||||
|
|
||||||
|
public ServerProcess(File dir, int minMem, int maxMem, int port, int distance, byte[] key) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for(int z = 0; z < key.length; z++) {
|
||||||
|
sb.append(String.format("%02x", key[z] & 255));
|
||||||
|
}
|
||||||
|
this.builder = new ProcessBuilder("java", "-Xms", minMem + "M", "-Xmx", maxMem + "M", "-jar", "game.jar", "game.Server",
|
||||||
|
"-p", "" + port, "-d", "" + distance, "-t", sb.toString()).directory(dir).redirectErrorStream(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
this.builder.directory().mkdirs();
|
||||||
|
try {
|
||||||
|
this.process = this.builder.start();
|
||||||
|
}
|
||||||
|
catch(IOException e) {
|
||||||
|
Log.SYSTEM.error(e, "Konnte Server nicht starten");
|
||||||
|
this.process = null;
|
||||||
|
}
|
||||||
|
// this.builder = null;
|
||||||
|
if(this.process == null)
|
||||||
|
return;
|
||||||
|
Thread con = new Thread(new Runnable() {
|
||||||
|
private final BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(ServerProcess.this.process.getInputStream())));
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
while(true) {
|
||||||
|
String line;
|
||||||
|
try {
|
||||||
|
line = this.reader.readLine();
|
||||||
|
}
|
||||||
|
catch(IOException e) {
|
||||||
|
line = null;
|
||||||
|
}
|
||||||
|
if(line == null)
|
||||||
|
break;
|
||||||
|
if(line.startsWith("#")) {
|
||||||
|
line = line.substring(1);
|
||||||
|
Tuple<String, String> data = Util.getKeyValue(line);
|
||||||
|
if(data.first.equals("running"))
|
||||||
|
ServerProcess.this.running = Boolean.parseBoolean(data.second);
|
||||||
|
if(data.first.equals("message"))
|
||||||
|
ServerProcess.this.message = data.second;
|
||||||
|
if(data.first.equals("total"))
|
||||||
|
ServerProcess.this.total = Integer.parseInt(data.second);
|
||||||
|
if(data.first.equals("progress"))
|
||||||
|
ServerProcess.this.progress = Integer.parseInt(data.second);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Log.SYSTEM.info("==SERVER== %s", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "Server console listener");
|
||||||
|
con.setDaemon(true);
|
||||||
|
con.start();
|
||||||
|
this.writer = new BufferedWriter(new OutputStreamWriter(new BufferedOutputStream(this.process.getOutputStream())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFolder() {
|
||||||
|
return this.builder.directory();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStarted() {
|
||||||
|
return this.running;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStopped() {
|
||||||
|
return !this.running;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getProgress() {
|
||||||
|
return this.progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotal() {
|
||||||
|
return this.total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown() {
|
||||||
|
try {
|
||||||
|
this.writer.write("end\n");
|
||||||
|
}
|
||||||
|
catch(IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package game.gui;
|
package game.gui;
|
||||||
|
|
||||||
import game.Game;
|
import game.Game;
|
||||||
import game.Server;
|
import game.ServerProcess;
|
||||||
import game.gui.element.Bar;
|
import game.gui.element.Bar;
|
||||||
import game.gui.element.Label;
|
import game.gui.element.Label;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ public class GuiLoading extends Gui {
|
||||||
private Bar progressBar1;
|
private Bar progressBar1;
|
||||||
private Bar progressBar2;
|
private Bar progressBar2;
|
||||||
|
|
||||||
public static GuiLoading makeLoadTask(final Server server, final String user) {
|
public static GuiLoading makeLoadTask(final ServerProcess server, final String user, final byte[] key) {
|
||||||
return new GuiLoading("Lade Welt ...", new Callback() {
|
return new GuiLoading("Lade Welt ...", new Callback() {
|
||||||
boolean started = false;
|
boolean started = false;
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ public class GuiLoading extends Gui {
|
||||||
if(!this.started && server.isStarted()) {
|
if(!this.started && server.isStarted()) {
|
||||||
this.started = true;
|
this.started = true;
|
||||||
// gm.displayGuiScreen(null);
|
// gm.displayGuiScreen(null);
|
||||||
server.setVar("viewDistance", "" + gm.renderDistance);
|
gm.debugWorld = server.getFolder() == null;
|
||||||
gm.connectToIntegrated(server, user);
|
gm.connect(null, gm.port, user, "", "", key);
|
||||||
// return;
|
// return;
|
||||||
}
|
}
|
||||||
int progress = server.getProgress();
|
int progress = server.getProgress();
|
||||||
|
@ -43,7 +43,7 @@ public class GuiLoading extends Gui {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GuiLoading makeIntermittentTask(final Server server) {
|
public static GuiLoading makeIntermittentTask(final ServerProcess server) {
|
||||||
return new GuiLoading("Lade Welt ...", new Callback() {
|
return new GuiLoading("Lade Welt ...", new Callback() {
|
||||||
public void poll(Game gm, GuiLoading gui) {
|
public void poll(Game gm, GuiLoading gui) {
|
||||||
int progress = server.getProgress();
|
int progress = server.getProgress();
|
||||||
|
@ -63,7 +63,7 @@ public class GuiLoading extends Gui {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GuiLoading makeSaveTask(final Server server) {
|
public static GuiLoading makeSaveTask(final ServerProcess server) {
|
||||||
return new GuiLoading("Speichere Welt ...", new Callback() {
|
return new GuiLoading("Speichere Welt ...", new Callback() {
|
||||||
public void poll(Game gm, GuiLoading gui) {
|
public void poll(Game gm, GuiLoading gui) {
|
||||||
if(server.isStopped()) {
|
if(server.isStopped()) {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import game.gui.element.ActButton.Mode;
|
||||||
import game.gui.element.Label;
|
import game.gui.element.Label;
|
||||||
import game.gui.element.NavButton;
|
import game.gui.element.NavButton;
|
||||||
import game.gui.element.Textbox;
|
import game.gui.element.Textbox;
|
||||||
import game.gui.element.Textbox.Action;
|
|
||||||
import game.gui.options.GuiOptions;
|
import game.gui.options.GuiOptions;
|
||||||
import game.gui.server.GuiConnect;
|
import game.gui.server.GuiConnect;
|
||||||
import game.gui.world.GuiWorlds;
|
import game.gui.world.GuiWorlds;
|
||||||
|
@ -114,32 +113,6 @@ public class GuiMenu extends Gui {
|
||||||
this.add(new NavButton(0, 28, this.gm.charEditor ? 400 : 198, 24, GuiOptions.getPage(), "Einstellungen"));
|
this.add(new NavButton(0, 28, this.gm.charEditor ? 400 : 198, 24, GuiOptions.getPage(), "Einstellungen"));
|
||||||
if(!this.gm.charEditor)
|
if(!this.gm.charEditor)
|
||||||
this.add(new NavButton(202, 28, 198, 24, GuiCharacters.INSTANCE, "Charakter"));
|
this.add(new NavButton(202, 28, 198, 24, GuiCharacters.INSTANCE, "Charakter"));
|
||||||
if(!this.gm.isRemote() && !this.gm.debugWorld) {
|
|
||||||
final Textbox portBox = this.add(new Textbox(0, 56, 96, 24, 5, true, new Textbox.Callback() {
|
|
||||||
public void use(Textbox elem, Action value) {
|
|
||||||
if(value == Action.SEND || value == Action.UNFOCUS) {
|
|
||||||
int port = -1;
|
|
||||||
try {
|
|
||||||
port = Integer.parseInt(elem.getText());
|
|
||||||
}
|
|
||||||
catch(NumberFormatException e) {
|
|
||||||
}
|
|
||||||
if(port < 0 || port > 65535)
|
|
||||||
elem.setText("" + GuiMenu.this.gm.port);
|
|
||||||
else
|
|
||||||
GuiMenu.this.gm.port = port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, "" + this.gm.port)); // "srv_port"
|
|
||||||
portBox.enabled = this.gm.bind == -1;
|
|
||||||
this.add(new ActButton(100, 56, 300, 24, new ActButton.Callback() {
|
|
||||||
public void use(ActButton elem, ActButton.Mode action) {
|
|
||||||
GuiMenu.this.gm.bind(GuiMenu.this.gm.bind = (GuiMenu.this.gm.bind != -1 ? -1 : GuiMenu.this.gm.port));
|
|
||||||
elem.setText(GuiMenu.this.gm.bind != -1 ? "LAN-Welt schließen" : "LAN-Welt öffnen");
|
|
||||||
portBox.enabled = GuiMenu.this.gm.bind == -1;
|
|
||||||
}
|
|
||||||
}, this.gm.bind != -1 ? "LAN-Welt schließen" : "LAN-Welt öffnen"));
|
|
||||||
}
|
|
||||||
this.add(new ActButton(0, 102, 400, 24, new ActButton.Callback() {
|
this.add(new ActButton(0, 102, 400, 24, new ActButton.Callback() {
|
||||||
public void use(ActButton elem, ActButton.Mode action) {
|
public void use(ActButton elem, ActButton.Mode action) {
|
||||||
GuiMenu.this.gm.unload(true);
|
GuiMenu.this.gm.unload(true);
|
||||||
|
|
38
java/src/game/gui/options/GuiNetwork.java
Normal file
38
java/src/game/gui/options/GuiNetwork.java
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package game.gui.options;
|
||||||
|
|
||||||
|
import game.gui.element.Textbox;
|
||||||
|
import game.gui.element.Label;
|
||||||
|
import game.gui.element.Textbox.Action;
|
||||||
|
|
||||||
|
public class GuiNetwork extends GuiOptions {
|
||||||
|
protected GuiNetwork() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(int width, int height) {
|
||||||
|
this.add(new Label(30, 360, 440, 20, "Server-Port für lokale Welten", true));
|
||||||
|
final Textbox portBox = this.add(new Textbox(30, 380, 440, 24, 5, true, new Textbox.Callback() {
|
||||||
|
public void use(Textbox elem, Action value) {
|
||||||
|
if(value == Action.SEND || value == Action.UNFOCUS) {
|
||||||
|
int port = -1;
|
||||||
|
try {
|
||||||
|
port = Integer.parseInt(elem.getText());
|
||||||
|
}
|
||||||
|
catch(NumberFormatException e) {
|
||||||
|
}
|
||||||
|
if(port < 0 || port > 65535) {
|
||||||
|
elem.setText("" + GuiNetwork.this.gm.port);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GuiNetwork.this.gm.port = port;
|
||||||
|
GuiNetwork.this.gm.setDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "" + this.gm.port));
|
||||||
|
super.init(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return "Server und Netzwerk";
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import game.gui.GuiMenu;
|
||||||
import game.gui.element.NavButton;
|
import game.gui.element.NavButton;
|
||||||
|
|
||||||
public abstract class GuiOptions extends Gui {
|
public abstract class GuiOptions extends Gui {
|
||||||
private static final GuiOptions[] PAGES = {lastPage = new GuiBinds(), new GuiStyle(), new GuiDisplay(), new GuiSound()};
|
private static final GuiOptions[] PAGES = {lastPage = new GuiBinds(), new GuiStyle(), new GuiDisplay(), new GuiSound(), new GuiNetwork()};
|
||||||
|
|
||||||
private static GuiOptions lastPage;
|
private static GuiOptions lastPage;
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class GuiConnect extends Gui implements Textbox.Callback {
|
||||||
this.lastPass = pass;
|
this.lastPass = pass;
|
||||||
this.lastAcc = acc;
|
this.lastAcc = acc;
|
||||||
this.gm.setDirty();
|
this.gm.setDirty();
|
||||||
this.gm.connect(addr, port, user, pass, acc);
|
this.gm.connect(addr, port, user, pass, acc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void use(Textbox elem, Action value) {
|
public void use(Textbox elem, Action value) {
|
||||||
|
|
|
@ -1,7 +1,25 @@
|
||||||
package game.init;
|
package game.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;
|
||||||
|
|
||||||
|
import game.log.NettyLogger;
|
||||||
|
|
||||||
public abstract class Registry {
|
public abstract class Registry {
|
||||||
public static void register() {
|
private static boolean crashed;
|
||||||
|
|
||||||
|
private static void register() {
|
||||||
NameRegistry.register();
|
NameRegistry.register();
|
||||||
BlockRegistry.register();
|
BlockRegistry.register();
|
||||||
FlammabilityRegistry.register();
|
FlammabilityRegistry.register();
|
||||||
|
@ -17,4 +35,106 @@ public abstract class Registry {
|
||||||
RotationRegistry.register();
|
RotationRegistry.register();
|
||||||
ReorderRegistry.register();
|
ReorderRegistry.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.getId())
|
||||||
|
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");
|
||||||
|
NettyLogger.init();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,7 @@ public class ClientLoginHandler extends NetHandler {
|
||||||
|
|
||||||
public final void handleEnableCompression(RPacketEnableCompression packetIn)
|
public final void handleEnableCompression(RPacketEnableCompression packetIn)
|
||||||
{
|
{
|
||||||
if (!this.networkManager.isLocalChannel())
|
this.networkManager.setCompressionTreshold(packetIn.getValue());
|
||||||
{
|
|
||||||
this.networkManager.setCompressionTreshold(packetIn.getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void handlePasswordRequest(RPacketPasswordRequest packetIn) {
|
// public void handlePasswordRequest(RPacketPasswordRequest packetIn) {
|
||||||
|
|
|
@ -94,6 +94,7 @@ import game.packet.SPacketMessage;
|
||||||
import game.packet.SPacketMultiBlockChange;
|
import game.packet.SPacketMultiBlockChange;
|
||||||
import game.packet.SPacketPlayerPosLook;
|
import game.packet.SPacketPlayerPosLook;
|
||||||
import game.packet.SPacketRespawn;
|
import game.packet.SPacketRespawn;
|
||||||
|
import game.packet.SPacketServerTick;
|
||||||
import game.packet.SPacketSetExperience;
|
import game.packet.SPacketSetExperience;
|
||||||
import game.packet.SPacketSkin;
|
import game.packet.SPacketSkin;
|
||||||
import game.packet.SPacketSpawnMob;
|
import game.packet.SPacketSpawnMob;
|
||||||
|
@ -903,7 +904,7 @@ public class ClientPlayer extends NetHandler
|
||||||
NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
|
NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
|
||||||
// this.gameController.theWorld.getWorldInfo().setTime(packetIn.getTotalWorldTime());
|
// this.gameController.theWorld.getWorldInfo().setTime(packetIn.getTotalWorldTime());
|
||||||
this.gameController.theWorld.setDayTime(packetIn.getWorldTime());
|
this.gameController.theWorld.setDayTime(packetIn.getWorldTime());
|
||||||
this.gameController.setTicked();
|
this.gameController.setTicked(packetIn.getServerinfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void handleCompass(SPacketCompass packetIn)
|
// public void handleCompass(SPacketCompass packetIn)
|
||||||
|
@ -1882,6 +1883,11 @@ public class ClientPlayer extends NetHandler
|
||||||
this.clientWorldController.dimension.setCustomName(packetIn.getCustomName());
|
this.clientWorldController.dimension.setCustomName(packetIn.getCustomName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleServerTick(SPacketServerTick packet) {
|
||||||
|
NetHandler.checkThread(packet, this, this.gameController);
|
||||||
|
this.gameController.setLastTick(packet.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns this the NetworkManager instance registered with this NetworkHandlerPlayClient
|
* Returns this the NetworkManager instance registered with this NetworkHandlerPlayClient
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,12 +1,45 @@
|
||||||
package game.network;
|
package game.network;
|
||||||
|
|
||||||
|
import game.Server;
|
||||||
|
import game.init.Config;
|
||||||
import game.packet.HPacketHandshake;
|
import game.packet.HPacketHandshake;
|
||||||
|
import game.packet.RPacketDisconnect;
|
||||||
|
|
||||||
public abstract class HandshakeHandler extends NetHandler
|
public class HandshakeHandler extends NetHandler
|
||||||
{
|
{
|
||||||
public abstract void processHandshake(HPacketHandshake packetIn);
|
private final Server server;
|
||||||
|
private final NetConnection networkManager;
|
||||||
|
|
||||||
|
public HandshakeHandler(Server serverIn, NetConnection netManager)
|
||||||
|
{
|
||||||
|
this.server = serverIn;
|
||||||
|
this.networkManager = netManager;
|
||||||
|
}
|
||||||
|
|
||||||
public void onDisconnect(String reason)
|
public void onDisconnect(String reason)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void processHandshake(HPacketHandshake packetIn)
|
||||||
|
{
|
||||||
|
if(packetIn.getProtocolVersion() == 0) {
|
||||||
|
this.networkManager.closeChannel("Inkompatibel!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.networkManager.setConnectionState(PacketRegistry.LOGIN);
|
||||||
|
if (packetIn.getProtocolVersion() != Config.PROTOCOL)
|
||||||
|
{
|
||||||
|
String comp;
|
||||||
|
if(packetIn.getProtocolVersion() < Config.PROTOCOL)
|
||||||
|
comp = "Der Server nutzt eine neuere Version: " + Config.VERSION;
|
||||||
|
else
|
||||||
|
comp = "Der Server nutzt eine ältere Version: " + Config.VERSION;
|
||||||
|
this.networkManager.sendPacket(new RPacketDisconnect(comp));
|
||||||
|
this.networkManager.closeChannel(comp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.networkManager.setNetHandler(new LoginHandler(this.server, this.networkManager));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
package game.network;
|
|
||||||
|
|
||||||
import game.Server;
|
|
||||||
import game.packet.HPacketHandshake;
|
|
||||||
|
|
||||||
public class HandshakeHandlerMemory extends HandshakeHandler
|
|
||||||
{
|
|
||||||
private final Server gmServer;
|
|
||||||
private final NetConnection networkManager;
|
|
||||||
|
|
||||||
public HandshakeHandlerMemory(Server gmServerIn, NetConnection networkManagerIn)
|
|
||||||
{
|
|
||||||
this.gmServer = gmServerIn;
|
|
||||||
this.networkManager = networkManagerIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processHandshake(HPacketHandshake packetIn)
|
|
||||||
{
|
|
||||||
this.networkManager.setConnectionState(PacketRegistry.LOGIN);
|
|
||||||
this.networkManager.setNetHandler(new LoginHandler(this.gmServer, this.networkManager));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package game.network;
|
|
||||||
|
|
||||||
import game.Server;
|
|
||||||
import game.init.Config;
|
|
||||||
import game.packet.HPacketHandshake;
|
|
||||||
import game.packet.RPacketDisconnect;
|
|
||||||
|
|
||||||
public class HandshakeHandlerTCP extends HandshakeHandler
|
|
||||||
{
|
|
||||||
private final Server server;
|
|
||||||
private final NetConnection networkManager;
|
|
||||||
|
|
||||||
public HandshakeHandlerTCP(Server serverIn, NetConnection netManager)
|
|
||||||
{
|
|
||||||
this.server = serverIn;
|
|
||||||
this.networkManager = netManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processHandshake(HPacketHandshake packetIn)
|
|
||||||
{
|
|
||||||
if(packetIn.getProtocolVersion() == 0) {
|
|
||||||
this.networkManager.closeChannel("Inkompatibel!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.networkManager.setConnectionState(PacketRegistry.LOGIN);
|
|
||||||
if (packetIn.getProtocolVersion() != Config.PROTOCOL)
|
|
||||||
{
|
|
||||||
String comp;
|
|
||||||
if(packetIn.getProtocolVersion() < Config.PROTOCOL)
|
|
||||||
comp = "Der Server nutzt eine neuere Version: " + Config.VERSION;
|
|
||||||
else
|
|
||||||
comp = "Der Server nutzt eine ältere Version: " + Config.VERSION;
|
|
||||||
this.networkManager.sendPacket(new RPacketDisconnect(comp));
|
|
||||||
this.networkManager.closeChannel(comp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.networkManager.setNetHandler(new LoginHandler(this.server, this.networkManager));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -72,23 +72,10 @@ public class LoginHandler extends NetHandler
|
||||||
|
|
||||||
private void tryAcceptPlayer()
|
private void tryAcceptPlayer()
|
||||||
{
|
{
|
||||||
if(!this.netManager.isLocalChannel()) {
|
if(this.server.getPlayer(this.loginUser) != null) {
|
||||||
// SocketAddress address = this.netManager.getRemoteAddress();
|
this.closeConnection("Nutzername '" + this.loginUser + "' ist bereits vergeben.");
|
||||||
// if(this.server.isBanned(address)) {
|
return;
|
||||||
//// Ban ban = this.server.getBanEntryIp(address);
|
}
|
||||||
// this.closeConnection("Deine IP-Adresse ist von diesem Server gebannt");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if(this.server.isBanned(this.loginUser)) {
|
|
||||||
// Ban ban = this.server.getBanEntry(this.loginUser);
|
|
||||||
// this.closeConnection(ban.format(true, 0L));
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
if(this.server.getPlayer(this.loginUser) != null) {
|
|
||||||
this.closeConnection("Nutzername '" + this.loginUser + "' ist bereits vergeben.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if (this.server.getPlayer(this.loginUser) != null)
|
// if (this.server.getPlayer(this.loginUser) != null)
|
||||||
// {
|
// {
|
||||||
// this.closeConnection("Nutzername '" + this.loginUser + "' ist bereits vergeben.");
|
// this.closeConnection("Nutzername '" + this.loginUser + "' ist bereits vergeben.");
|
||||||
|
@ -118,7 +105,9 @@ public class LoginHandler extends NetHandler
|
||||||
if(this.state != LoginState.PASSWORD)
|
if(this.state != LoginState.PASSWORD)
|
||||||
throw new IllegalStateException("Unerwartetes Passwort-Paket");
|
throw new IllegalStateException("Unerwartetes Passwort-Paket");
|
||||||
this.loginUser = packetIn.getUser();
|
this.loginUser = packetIn.getUser();
|
||||||
if(this.netManager.isLocalChannel()) {
|
if(packetIn.getLocal() != null) {
|
||||||
|
// TODO: key verification
|
||||||
|
this.netManager.setLocal();
|
||||||
this.loginPass = "";
|
this.loginPass = "";
|
||||||
// this.loginUser = Config.localUser;
|
// this.loginUser = Config.localUser;
|
||||||
if(this.loginUser.length() > Player.MAX_USER_LENGTH || (!this.loginUser.isEmpty() && !Player.isValidUser(this.loginUser))) {
|
if(this.loginUser.length() > Player.MAX_USER_LENGTH || (!this.loginUser.isEmpty() && !Player.isValidUser(this.loginUser))) {
|
||||||
|
|
|
@ -22,9 +22,6 @@ import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.EventLoopGroup;
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.channel.local.LocalChannel;
|
|
||||||
import io.netty.channel.local.LocalEventLoopGroup;
|
|
||||||
import io.netty.channel.local.LocalServerChannel;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.SocketChannel;
|
import io.netty.channel.socket.SocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
@ -45,21 +42,6 @@ public class NetConnection extends SimpleChannelInboundHandler<Packet>
|
||||||
return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).build());
|
return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).build());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// public static final LazyLoadBase<EpollEventLoopGroup> CLIENT_EPOLL_EVENTLOOP = new LazyLoadBase<EpollEventLoopGroup>()
|
|
||||||
// {
|
|
||||||
// protected EpollEventLoopGroup load()
|
|
||||||
// {
|
|
||||||
// return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Client IO #%d").setDaemon(true).build());
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
public static final LazyLoadBase<LocalEventLoopGroup> CLIENT_LOCAL_EVENTLOOP = new LazyLoadBase<LocalEventLoopGroup>()
|
|
||||||
{
|
|
||||||
protected LocalEventLoopGroup load()
|
|
||||||
{
|
|
||||||
return new LocalEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).build());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// private final PacketDirection direction;
|
|
||||||
private final Queue<NetConnection.InboundHandlerTuplePacketListener> outboundPacketsQueue = new ConcurrentLinkedQueue<InboundHandlerTuplePacketListener>();
|
private final Queue<NetConnection.InboundHandlerTuplePacketListener> outboundPacketsQueue = new ConcurrentLinkedQueue<InboundHandlerTuplePacketListener>();
|
||||||
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
|
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
|
@ -70,16 +52,11 @@ public class NetConnection extends SimpleChannelInboundHandler<Packet>
|
||||||
private boolean disconnected;
|
private boolean disconnected;
|
||||||
private boolean local;
|
private boolean local;
|
||||||
|
|
||||||
// public NetConnection(PacketDirection packetDirection)
|
|
||||||
// {
|
|
||||||
// this.direction = packetDirection;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void channelActive(ChannelHandlerContext p_channelActive_1_) throws Exception
|
public void channelActive(ChannelHandlerContext p_channelActive_1_) throws Exception
|
||||||
{
|
{
|
||||||
super.channelActive(p_channelActive_1_);
|
super.channelActive(p_channelActive_1_);
|
||||||
this.channel = p_channelActive_1_.channel();
|
this.channel = p_channelActive_1_.channel();
|
||||||
this.local = this.channel instanceof LocalChannel || this.channel instanceof LocalServerChannel;
|
this.local = false; // this.channel instanceof LocalChannel || this.channel instanceof LocalServerChannel;
|
||||||
this.socketAddress = this.channel.remoteAddress();
|
this.socketAddress = this.channel.remoteAddress();
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -324,6 +301,11 @@ public class NetConnection extends SimpleChannelInboundHandler<Packet>
|
||||||
return this.local;
|
return this.local;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLocal()
|
||||||
|
{
|
||||||
|
this.local = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new NetworkManager from the server host and connect it to the server
|
* Create a new NetworkManager from the server host and connect it to the server
|
||||||
*
|
*
|
||||||
|
@ -366,26 +348,6 @@ public class NetConnection extends SimpleChannelInboundHandler<Packet>
|
||||||
return networkmanager;
|
return networkmanager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepares a clientside NetworkManager: establishes a connection to the socket supplied and configures the channel
|
|
||||||
* pipeline. Returns the newly created instance.
|
|
||||||
*/
|
|
||||||
public static NetConnection provideLocalClient(SocketAddress address)
|
|
||||||
{
|
|
||||||
final NetConnection networkmanager = new NetConnection();
|
|
||||||
((Bootstrap)((Bootstrap)((Bootstrap)(new Bootstrap()).group((EventLoopGroup)CLIENT_LOCAL_EVENTLOOP.getValue())).handler(new ChannelInitializer<Channel>()
|
|
||||||
{
|
|
||||||
protected void initChannel(Channel p_initChannel_1_) throws Exception
|
|
||||||
{
|
|
||||||
p_initChannel_1_.pipeline().addLast((String)"packet_handler", (ChannelHandler)networkmanager);
|
|
||||||
}
|
|
||||||
})).channel(LocalChannel.class)).connect(address).syncUninterruptibly();
|
|
||||||
return networkmanager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this NetworkManager has an active channel, false otherwise
|
|
||||||
*/
|
|
||||||
public boolean isChannelOpen()
|
public boolean isChannelOpen()
|
||||||
{
|
{
|
||||||
return this.channel != null && this.channel.isOpen();
|
return this.channel != null && this.channel.isOpen();
|
||||||
|
|
|
@ -74,6 +74,7 @@ import game.packet.SPacketMessage;
|
||||||
import game.packet.SPacketMultiBlockChange;
|
import game.packet.SPacketMultiBlockChange;
|
||||||
import game.packet.SPacketPlayerPosLook;
|
import game.packet.SPacketPlayerPosLook;
|
||||||
import game.packet.SPacketRespawn;
|
import game.packet.SPacketRespawn;
|
||||||
|
import game.packet.SPacketServerTick;
|
||||||
import game.packet.SPacketSetExperience;
|
import game.packet.SPacketSetExperience;
|
||||||
import game.packet.SPacketSkin;
|
import game.packet.SPacketSkin;
|
||||||
import game.packet.SPacketSpawnMob;
|
import game.packet.SPacketSpawnMob;
|
||||||
|
@ -178,6 +179,7 @@ public enum PacketRegistry
|
||||||
// this.server(SPacketNotify.class);
|
// this.server(SPacketNotify.class);
|
||||||
this.server(SPacketDimensionName.class);
|
this.server(SPacketDimensionName.class);
|
||||||
this.server(SPacketCharacterList.class);
|
this.server(SPacketCharacterList.class);
|
||||||
|
this.server(SPacketServerTick.class);
|
||||||
|
|
||||||
this.client(CPacketKeepAlive.class);
|
this.client(CPacketKeepAlive.class);
|
||||||
this.client(CPacketMessage.class);
|
this.client(CPacketMessage.class);
|
||||||
|
|
|
@ -274,6 +274,8 @@ public class Player extends NetHandler implements ICrafting, Executor
|
||||||
this.pingKey = (int)this.lastPingTime;
|
this.pingKey = (int)this.lastPingTime;
|
||||||
this.sendPacket(new SPacketKeepAlive(this.pingKey));
|
this.sendPacket(new SPacketKeepAlive(this.pingKey));
|
||||||
}
|
}
|
||||||
|
if(this.local)
|
||||||
|
|
||||||
if(this.respawnTimer > 0) {
|
if(this.respawnTimer > 0) {
|
||||||
if(--this.respawnTimer == 0) {
|
if(--this.respawnTimer == 0) {
|
||||||
this.respawnPlayer();
|
this.respawnPlayer();
|
||||||
|
@ -2511,7 +2513,7 @@ public class Player extends NetHandler implements ICrafting, Executor
|
||||||
NetHandler.checkThread(packetIn, this, this.server);
|
NetHandler.checkThread(packetIn, this, this.server);
|
||||||
|
|
||||||
CPacketAction.Action action = packetIn.getAction();
|
CPacketAction.Action action = packetIn.getAction();
|
||||||
if(this.charEditor != (action == Action.SET_ALIGN || action == Action.SET_SPECIES || action == Action.SET_CLASS || action == Action.SET_HEIGHT || action == Action.CLOSE_EDITOR)) // {
|
if(action != Action.SET_VIEWDIST && action != Action.SHUTDOWN && (this.charEditor != (action == Action.SET_ALIGN || action == Action.SET_SPECIES || action == Action.SET_CLASS || action == Action.SET_HEIGHT || action == Action.CLOSE_EDITOR))) // {
|
||||||
// if(this.local && action == Action.CLOSE_EDITOR)
|
// if(this.local && action == Action.CLOSE_EDITOR)
|
||||||
// this.server.setDone();
|
// this.server.setDone();
|
||||||
return;
|
return;
|
||||||
|
@ -2874,6 +2876,26 @@ public class Player extends NetHandler implements ICrafting, Executor
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WARP_MODE:
|
||||||
|
if(this.isLocal()) {
|
||||||
|
this.server.schedule(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
Player.this.server.setTpsTarget(Player.this.server.getTpsTarget() < 10000.0f ? 10000.0f : 20.0f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SET_VIEWDIST:
|
||||||
|
if(this.isLocal())
|
||||||
|
this.server.setVar("viewDistance", "" + packetIn.getAuxData());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHUTDOWN:
|
||||||
|
if(this.isLocal())
|
||||||
|
this.server.shutdown();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Ungültige Aktion!");
|
throw new IllegalArgumentException("Ungültige Aktion!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,9 @@ public class CPacketAction implements Packet<Player>
|
||||||
HEAL,
|
HEAL,
|
||||||
REPAIR,
|
REPAIR,
|
||||||
PERF,
|
PERF,
|
||||||
MAGNET;
|
MAGNET,
|
||||||
|
SET_VIEWDIST,
|
||||||
|
WARP_MODE,
|
||||||
|
SHUTDOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,18 @@ public class LPacketPasswordResponse implements Packet<LoginHandler>
|
||||||
private String user;
|
private String user;
|
||||||
private String access;
|
private String access;
|
||||||
private String password;
|
private String password;
|
||||||
|
private byte[] local;
|
||||||
|
|
||||||
public LPacketPasswordResponse()
|
public LPacketPasswordResponse()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public LPacketPasswordResponse(String userIn, String accessIn, String passwordIn)
|
public LPacketPasswordResponse(String userIn, String accessIn, String passwordIn, byte[] local)
|
||||||
{
|
{
|
||||||
this.user = userIn;
|
this.user = userIn;
|
||||||
this.access = accessIn;
|
this.access = accessIn;
|
||||||
this.password = passwordIn;
|
this.password = passwordIn;
|
||||||
|
this.local = local;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +34,8 @@ public class LPacketPasswordResponse implements Packet<LoginHandler>
|
||||||
this.user = buf.readStringFromBuffer(Player.MAX_USER_LENGTH);
|
this.user = buf.readStringFromBuffer(Player.MAX_USER_LENGTH);
|
||||||
this.access = buf.readStringFromBuffer(Player.MAX_PASS_LENGTH);
|
this.access = buf.readStringFromBuffer(Player.MAX_PASS_LENGTH);
|
||||||
this.password = buf.readStringFromBuffer(Player.MAX_PASS_LENGTH);
|
this.password = buf.readStringFromBuffer(Player.MAX_PASS_LENGTH);
|
||||||
|
this.local = buf.readByteArray();
|
||||||
|
this.local = this.local.length == 0 ? null : this.local;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +46,7 @@ public class LPacketPasswordResponse implements Packet<LoginHandler>
|
||||||
buf.writeString(this.user);
|
buf.writeString(this.user);
|
||||||
buf.writeString(this.access);
|
buf.writeString(this.access);
|
||||||
buf.writeString(this.password);
|
buf.writeString(this.password);
|
||||||
|
buf.writeByteArray(this.local == null ? new byte[0] : this.local);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,4 +71,9 @@ public class LPacketPasswordResponse implements Packet<LoginHandler>
|
||||||
{
|
{
|
||||||
return this.password;
|
return this.password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getLocal()
|
||||||
|
{
|
||||||
|
return this.local;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
34
java/src/game/packet/SPacketServerTick.java
Normal file
34
java/src/game/packet/SPacketServerTick.java
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package game.packet;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import game.network.ClientPlayer;
|
||||||
|
import game.network.Packet;
|
||||||
|
import game.network.PacketBuffer;
|
||||||
|
|
||||||
|
public class SPacketServerTick implements Packet<ClientPlayer> {
|
||||||
|
private int time;
|
||||||
|
|
||||||
|
public SPacketServerTick() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SPacketServerTick(int time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readPacketData(PacketBuffer buf) throws IOException {
|
||||||
|
this.time = buf.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writePacketData(PacketBuffer buf) throws IOException {
|
||||||
|
buf.writeInt(this.time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processPacket(ClientPlayer handler) {
|
||||||
|
handler.handleServerTick(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTime() {
|
||||||
|
return this.time;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,36 +7,36 @@ import game.network.Packet;
|
||||||
import game.network.PacketBuffer;
|
import game.network.PacketBuffer;
|
||||||
|
|
||||||
public class SPacketTimeUpdate implements Packet<ClientPlayer> {
|
public class SPacketTimeUpdate implements Packet<ClientPlayer> {
|
||||||
// private long totalWorldTime;
|
|
||||||
private long worldTime;
|
private long worldTime;
|
||||||
|
private String serverInfo;
|
||||||
|
|
||||||
public SPacketTimeUpdate() {
|
public SPacketTimeUpdate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SPacketTimeUpdate(long totalTimeIn) {
|
public SPacketTimeUpdate(long time, String info) {
|
||||||
// this.totalWorldTime = totalWorldTimeIn;
|
this.worldTime = time;
|
||||||
this.worldTime = totalTimeIn;
|
this.serverInfo = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readPacketData(PacketBuffer buf) throws IOException {
|
public void readPacketData(PacketBuffer buf) throws IOException {
|
||||||
// this.totalWorldTime = buf.readLong();
|
|
||||||
this.worldTime = buf.readLong();
|
this.worldTime = buf.readLong();
|
||||||
|
this.serverInfo = buf.readStringFromBuffer(512);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writePacketData(PacketBuffer buf) throws IOException {
|
public void writePacketData(PacketBuffer buf) throws IOException {
|
||||||
// buf.writeLong(this.totalWorldTime);
|
|
||||||
buf.writeLong(this.worldTime);
|
buf.writeLong(this.worldTime);
|
||||||
|
buf.writeString(this.serverInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processPacket(ClientPlayer handler) {
|
public void processPacket(ClientPlayer handler) {
|
||||||
handler.handleTimeUpdate(this);
|
handler.handleTimeUpdate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public long getTotalWorldTime() {
|
|
||||||
// return this.totalWorldTime;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public long getWorldTime() {
|
public long getWorldTime() {
|
||||||
return this.worldTime;
|
return this.worldTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getServerinfo() {
|
||||||
|
return this.serverInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
11
java/src/game/util/Tuple.java
Normal file
11
java/src/game/util/Tuple.java
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package game.util;
|
||||||
|
|
||||||
|
public class Tuple<S, T> {
|
||||||
|
public final S first;
|
||||||
|
public final T second;
|
||||||
|
|
||||||
|
public Tuple(S first, T second) {
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,10 @@
|
||||||
package game.util;
|
package game.util;
|
||||||
|
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
import game.log.Log;
|
import game.log.Log;
|
||||||
import game.properties.IStringSerializable;
|
import game.properties.IStringSerializable;
|
||||||
|
|
||||||
|
@ -293,4 +296,30 @@ int utf_len(const char *str) {
|
||||||
return (color & 0xff000000) | ((((color >> 16 & 255) * mul) / 255) << 16) | ((((color >> 8 & 255) * mul) / 255) << 8) |
|
return (color & 0xff000000) | ((((color >> 16 & 255) * mul) / 255) << 16) | ((((color >> 8 & 255) * mul) / 255) << 8) |
|
||||||
(((color & 255) * mul) / 255);
|
(((color & 255) * mul) / 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void checkOs() {
|
||||||
|
if(System.getProperty("os.name").startsWith("Windows") || System.getProperty("os.name").startsWith("Mac")) {
|
||||||
|
String info = "Inkompatibles Betriebssystem";
|
||||||
|
String msg = "Linux oder *BSD ist erforderlich, um dieses Programm auszuführen.\n" +
|
||||||
|
"Alle Versionen von Windows und Mac OS (X) sind nicht kompatibel.";
|
||||||
|
System.err.println("#################################################################");
|
||||||
|
System.err.println("*** " + info + " ***");
|
||||||
|
System.err.println(msg);
|
||||||
|
System.err.println("#################################################################");
|
||||||
|
if(!GraphicsEnvironment.isHeadless())
|
||||||
|
JOptionPane.showMessageDialog(null, msg, info, JOptionPane.ERROR_MESSAGE);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tuple<String, String> getKeyValue(String text, char separator) {
|
||||||
|
int index = text.indexOf(separator);
|
||||||
|
if(index == -1)
|
||||||
|
return new Tuple<String, String>(text, null);
|
||||||
|
return new Tuple<String, String>(text.substring(0, index), text.substring(index + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tuple<String, String> getKeyValue(String text) {
|
||||||
|
return getKeyValue(text, ' ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,6 @@ public final class WorldServer extends World {
|
||||||
private static final int[][] XZ_DIRS = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
|
private static final int[][] XZ_DIRS = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
|
||||||
|
|
||||||
private final Server server;
|
private final Server server;
|
||||||
private final File dir;
|
|
||||||
private final File chunkDir;
|
private final File chunkDir;
|
||||||
private final Random grng;
|
private final Random grng;
|
||||||
private final Set<NextTickListEntry> ticks = Sets.<NextTickListEntry>newHashSet();
|
private final Set<NextTickListEntry> ticks = Sets.<NextTickListEntry>newHashSet();
|
||||||
|
@ -156,14 +155,13 @@ public final class WorldServer extends World {
|
||||||
private long prevUpdate;
|
private long prevUpdate;
|
||||||
private long time;
|
private long time;
|
||||||
|
|
||||||
public WorldServer(Server server, File dir, long dtime, Dimension dim, boolean debug) {
|
public WorldServer(Server server, long dtime, Dimension dim, boolean debug) {
|
||||||
super(dim, false, debug);
|
super(dim, false, debug);
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.dir = dir;
|
|
||||||
// this.time = time;
|
// this.time = time;
|
||||||
this.daytime = dtime;
|
this.daytime = dtime;
|
||||||
this.updateViewRadius();
|
this.updateViewRadius();
|
||||||
this.chunkDir = new File(new File(this.dir, "chunk"), dim.getDimensionName());
|
this.chunkDir = new File(new File("chunk"), dim.getDimensionName());
|
||||||
if(!debug) {
|
if(!debug) {
|
||||||
this.chunkDir.mkdirs();
|
this.chunkDir.mkdirs();
|
||||||
this.seed = this.rand.longv();
|
this.seed = this.rand.longv();
|
||||||
|
@ -800,10 +798,10 @@ public final class WorldServer extends World {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean needsLoading(File dir, Dimension dim) {
|
public static boolean needsLoading(Dimension dim) {
|
||||||
NBTTagCompound tag = null;
|
NBTTagCompound tag = null;
|
||||||
try {
|
try {
|
||||||
File dat = new File(new File(new File(dir, "chunk"), dim.getDimensionName()), "loaders.nbt");
|
File dat = new File(new File(new File("chunk"), dim.getDimensionName()), "loaders.nbt");
|
||||||
if(dat.exists() && dat.isFile())
|
if(dat.exists() && dat.isFile())
|
||||||
tag = NBTLoader.readGZip(dat);
|
tag = NBTLoader.readGZip(dat);
|
||||||
}
|
}
|
||||||
|
@ -813,10 +811,10 @@ public final class WorldServer extends World {
|
||||||
return tag != null && tag.hasKey("Loaders", 9) && !tag.getTagList("Loaders", 10).hasNoTags();
|
return tag != null && tag.hasKey("Loaders", 9) && !tag.getTagList("Loaders", 10).hasNoTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadWarps(File dir, Dimension dim, Map<String, Position> warps) {
|
public static void loadWarps(Dimension dim, Map<String, Position> warps) {
|
||||||
NBTTagCompound tag = null;
|
NBTTagCompound tag = null;
|
||||||
try {
|
try {
|
||||||
File dat = new File(new File(new File(dir, "chunk"), dim.getDimensionName()), "warps.nbt");
|
File dat = new File(new File(new File("chunk"), dim.getDimensionName()), "warps.nbt");
|
||||||
if(dat.exists() && dat.isFile())
|
if(dat.exists() && dat.isFile())
|
||||||
tag = NBTLoader.readGZip(dat);
|
tag = NBTLoader.readGZip(dat);
|
||||||
}
|
}
|
||||||
|
@ -834,7 +832,7 @@ public final class WorldServer extends World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveWarps(File dir, Map<String, Position> warps) {
|
public static void saveWarps(Map<String, Position> warps) {
|
||||||
Map<Integer, NBTTagList> map = Maps.newHashMap();
|
Map<Integer, NBTTagList> map = Maps.newHashMap();
|
||||||
for(Entry<String, Position> pos : warps.entrySet()) {
|
for(Entry<String, Position> pos : warps.entrySet()) {
|
||||||
Dimension dim = UniverseRegistry.getDimension(pos.getValue().dim);
|
Dimension dim = UniverseRegistry.getDimension(pos.getValue().dim);
|
||||||
|
@ -854,7 +852,7 @@ public final class WorldServer extends World {
|
||||||
}
|
}
|
||||||
for(Dimension dim : UniverseRegistry.getDimensions()) {
|
for(Dimension dim : UniverseRegistry.getDimensions()) {
|
||||||
NBTTagList list = map.get(dim.getDimensionId());
|
NBTTagList list = map.get(dim.getDimensionId());
|
||||||
File file = new File(new File(new File(dir, "chunk"), dim.getDimensionName()), "warps.nbt");
|
File file = new File(new File(new File("chunk"), dim.getDimensionName()), "warps.nbt");
|
||||||
if(list == null) {
|
if(list == null) {
|
||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue