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;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
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.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.IDN;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.security.SecureRandom;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Queue;
|
||||
|
@ -40,8 +31,6 @@ import java.util.concurrent.FutureTask;
|
|||
import java.util.function.Function;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
|
||||
|
@ -92,7 +81,6 @@ import game.item.ItemStack;
|
|||
import game.log.Log;
|
||||
import game.log.LogLevel;
|
||||
import game.log.Message;
|
||||
import game.log.NettyLogger;
|
||||
import game.material.Material;
|
||||
import game.model.ModelManager;
|
||||
import game.network.IThreadListener;
|
||||
|
@ -167,7 +155,6 @@ import game.world.Region;
|
|||
import game.world.State;
|
||||
import game.world.World;
|
||||
import game.world.WorldClient;
|
||||
import game.world.WorldServer;
|
||||
|
||||
/*
|
||||
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")
|
||||
public int port = Config.PORT;
|
||||
public int bind = -1;
|
||||
|
||||
@Variable(name = "snd_enabled", category = CVarCategory.SOUND, display = "Tonausgabe")
|
||||
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")
|
||||
public int soundFrameSize = 32;
|
||||
|
||||
private Server server;
|
||||
private ServerProcess server;
|
||||
private String serverInfo;
|
||||
private int lastServerTick;
|
||||
private AudioInterface audio;
|
||||
private long start;
|
||||
private boolean cfgDirty;
|
||||
private String buffer = "";
|
||||
private boolean crashed;
|
||||
private boolean waitingForFile;
|
||||
private boolean refreshing;
|
||||
|
||||
|
@ -450,20 +437,20 @@ public class Game implements IThreadListener {
|
|||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void connect(String address, int port, String user, String pass, String access) {
|
||||
Log.JNI.info("Verbinde zu " + address + ":" + port);
|
||||
public void connect(String address, int port, String user, String pass, String access, byte[] local) {
|
||||
Log.JNI.info("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port);
|
||||
NetConnection connection = null;
|
||||
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.sendPacket(new HPacketHandshake(Config.PROTOCOL));
|
||||
connection.sendPacket(new LPacketPasswordResponse(user, access, pass));
|
||||
connection.sendPacket(new LPacketPasswordResponse(user, access, pass, local));
|
||||
}
|
||||
catch (UnknownHostException u)
|
||||
{
|
||||
Log.JNI.error(u, "Konnte nicht zu Server verbinden");
|
||||
this.disconnected("Unbekannter Hostname: " + address);
|
||||
this.disconnected("Unbekannter Hostname: " + (address == null ? "localhost" : address));
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -475,17 +462,6 @@ public class Game implements IThreadListener {
|
|||
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() {
|
||||
ClientPlayer netHandler = this.getNetHandler();
|
||||
if(netHandler != null)
|
||||
|
@ -496,6 +472,7 @@ public class Game implements IThreadListener {
|
|||
this.connection = null;
|
||||
this.theWorld = null;
|
||||
this.thePlayer = null;
|
||||
this.serverInfo = null;
|
||||
this.soundManager.stopSounds();
|
||||
}
|
||||
|
||||
|
@ -1013,7 +990,7 @@ public class Game implements IThreadListener {
|
|||
int y1 = 0;
|
||||
int y2 = this.fb_y;
|
||||
// int pos = 0;
|
||||
String str = this.getLeft(this.server);
|
||||
String str = this.getLeft();
|
||||
// if(jstr)
|
||||
// str = (*jsys.env)->GetStringUTFChars(jsys.env, jstr, NULL);
|
||||
// elem->r_dirty = 1;
|
||||
|
@ -1624,8 +1601,14 @@ public class Game implements IThreadListener {
|
|||
return this.itemRenderer;
|
||||
}
|
||||
|
||||
public void setTicked() {
|
||||
public void setTicked(String info) {
|
||||
this.lastTicked = System.currentTimeMillis();
|
||||
this.serverInfo = info;
|
||||
}
|
||||
|
||||
public void setLastTick(int tick) {
|
||||
this.lastTicked = System.currentTimeMillis();
|
||||
this.lastServerTick = tick;
|
||||
}
|
||||
|
||||
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 totalMem = Runtime.getRuntime().totalMemory();
|
||||
long freeMem = Runtime.getRuntime().freeMemory();
|
||||
|
@ -1767,13 +1750,8 @@ public class Game implements IThreadListener {
|
|||
) + "\n" +
|
||||
String.format("Letzte Zeitsynch.: + %d.%d s",
|
||||
ticked / 1000L, (ticked / 100L) % 10L
|
||||
) + "\n" +
|
||||
(server != null ?
|
||||
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: <?>")
|
||||
) +
|
||||
(this.serverInfo != null ? "\n" + this.serverInfo : "")
|
||||
// WorldServer world = this.server.getWorld(this.theWorld.dimension.getDimensionId());
|
||||
// if(world != null)
|
||||
// list.add("Seed: " + world.getSeed());
|
||||
|
@ -2100,7 +2078,7 @@ public class Game implements IThreadListener {
|
|||
return;
|
||||
this.frameWait = 50000000L - ((n - (this.frameLast + this.frameWait)) < 50000000L ? (n - (this.frameLast + this.frameWait)) : 0L);
|
||||
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) {
|
||||
this.tickIndex = 0;
|
||||
}
|
||||
|
@ -2369,11 +2347,13 @@ public class Game implements IThreadListener {
|
|||
|
||||
public void unload(boolean loading) {
|
||||
if(this.theWorld != null) {
|
||||
if(server != null)
|
||||
this.performAction(Action.SHUTDOWN);
|
||||
if(server == null && this.getNetHandler() != null)
|
||||
this.getNetHandler().getNetworkManager().closeChannel("Quitting");
|
||||
this.unloadWorld();
|
||||
if(server != null)
|
||||
server.shutdown();
|
||||
// if(server != null)
|
||||
// server.shutdown();
|
||||
}
|
||||
if(server != null) {
|
||||
if(loading) {
|
||||
|
@ -2396,9 +2376,11 @@ public class Game implements IThreadListener {
|
|||
}
|
||||
|
||||
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();
|
||||
this.displayGuiScreen(GuiLoading.makeLoadTask(server, user));
|
||||
this.displayGuiScreen(GuiLoading.makeLoadTask(server, user, key));
|
||||
// while(server != null && !server.isStarted()) {
|
||||
// try {
|
||||
// Thread.sleep(10L);
|
||||
|
@ -2451,16 +2433,11 @@ public class Game implements IThreadListener {
|
|||
return ((double)rtime()) / 1000000.0;
|
||||
}
|
||||
|
||||
public void bind(int port) {
|
||||
if(server != null)
|
||||
server.bind(port);
|
||||
}
|
||||
|
||||
public void distance(int distance) {
|
||||
if(this.renderGlobal != null)
|
||||
this.renderGlobal.setDisplayListEntitiesDirty();
|
||||
if(this.server != null)
|
||||
this.server.setVar("viewDistance", "" + distance);
|
||||
if(this.server != null && this.thePlayer != null)
|
||||
this.thePlayer.sendQueue.addToSendQueue(new CPacketAction(Action.SET_VIEWDIST, distance));
|
||||
}
|
||||
|
||||
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() {
|
||||
public void execute(Keysym key) {
|
||||
if(server != null) {
|
||||
server.schedule(new Runnable() {
|
||||
public void run() {
|
||||
server.setTpsTarget(server.getTpsTarget() < 10000.0f ? 10000.0f : 20.0f);
|
||||
}
|
||||
});
|
||||
}
|
||||
Game.this.performAction(Action.WARP_MODE);
|
||||
}
|
||||
});
|
||||
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) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
Util.checkOs();
|
||||
Window.init();
|
||||
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(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");
|
||||
Registry.setup("Render thread");
|
||||
INSTANCE.run();
|
||||
Window.end();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package game;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -32,6 +31,7 @@ import game.entity.npc.EntityHuman;
|
|||
import game.entity.npc.EntityNPC;
|
||||
import game.init.Config;
|
||||
import game.init.EntityRegistry;
|
||||
import game.init.Registry;
|
||||
import game.init.UniverseRegistry;
|
||||
import game.log.Log;
|
||||
import game.nbt.NBTLoader;
|
||||
|
@ -41,8 +41,7 @@ import game.network.IThreadListener;
|
|||
import game.network.LazyLoadBase;
|
||||
import game.network.NetConnection;
|
||||
import game.network.NetHandler.ThreadQuickExitException;
|
||||
import game.network.HandshakeHandlerMemory;
|
||||
import game.network.HandshakeHandlerTCP;
|
||||
import game.network.HandshakeHandler;
|
||||
import game.network.Player;
|
||||
import game.network.Packet;
|
||||
import game.network.PacketDecoder;
|
||||
|
@ -65,6 +64,7 @@ import game.packet.SPacketTimeUpdate;
|
|||
import game.packet.SPacketWorld;
|
||||
import game.potion.PotionEffect;
|
||||
import game.util.ExtMath;
|
||||
import game.util.Util;
|
||||
import game.world.BlockPos;
|
||||
import game.world.PortalType;
|
||||
import game.world.Position;
|
||||
|
@ -81,23 +81,20 @@ import io.netty.channel.ChannelFutureListener;
|
|||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
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.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
import io.netty.util.concurrent.Future;
|
||||
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>() {
|
||||
protected NioEventLoopGroup load() {
|
||||
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<Player> players = Lists.<Player>newArrayList();
|
||||
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 Map<String, Position> warps = Maps.<String, Position>newTreeMap();
|
||||
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 WorldServer space;
|
||||
private ChannelFuture endpoint;
|
||||
private ChannelFuture localEndpoint;
|
||||
private String localUser;
|
||||
private String message;
|
||||
|
||||
private boolean running = true;
|
||||
private boolean stopped;
|
||||
|
@ -140,28 +131,29 @@ public final class Server implements Runnable, IThreadListener {
|
|||
private int pingTimer;
|
||||
private int syncTimer;
|
||||
private int perfTimer;
|
||||
private int progress = -1;
|
||||
private int total = 0;
|
||||
|
||||
Server(File dir) {
|
||||
// this.owner = owner;
|
||||
this.serverThread = new Thread(this, "Server thread");
|
||||
this.baseDir = dir; // dir != null ? new File(dir) : null;
|
||||
this.playerDir = new File(this.baseDir, "players");
|
||||
this.debug = this.baseDir == null;
|
||||
// this.port = port;
|
||||
public static void main(String[] args) {
|
||||
Util.checkOs();
|
||||
Registry.setup("Server thread");
|
||||
final Server server = new Server(false);
|
||||
Registry.addShutdownHook(new Runnable() {
|
||||
public void run() {
|
||||
server.stopServer();
|
||||
}
|
||||
});
|
||||
server.run();
|
||||
}
|
||||
|
||||
private Server(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
public CommandEnvironment getScriptEnvironment() {
|
||||
return this.scriptEnv;
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return this.started;
|
||||
}
|
||||
|
||||
public String[] getUsers() {
|
||||
String[] list = this.debug ? null : this.playerDir.list();
|
||||
String[] list = this.debug ? null : new File("players").list();
|
||||
if(list == null) {
|
||||
list = new String[0];
|
||||
}
|
||||
|
@ -182,8 +174,8 @@ public final class Server implements Runnable, IThreadListener {
|
|||
|
||||
public void saveWorldInfo() {
|
||||
if(!this.debug) {
|
||||
Region.saveWorldInfo(this.baseDir, this.space.getDayTime(), this.localUser);
|
||||
WorldServer.saveWarps(this.baseDir, this.warps);
|
||||
Region.saveWorldInfo(null, this.space.getDayTime(), this.localUser);
|
||||
WorldServer.saveWarps(this.warps);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,7 +184,7 @@ public final class Server implements Runnable, IThreadListener {
|
|||
return null;
|
||||
NBTTagCompound tag = null;
|
||||
try {
|
||||
File dat = new File(this.playerDir, user + ".nbt");
|
||||
File dat = new File(new File("players"), user + ".nbt");
|
||||
|
||||
if(dat.exists() && dat.isFile()) {
|
||||
tag = NBTLoader.readGZip(dat);
|
||||
|
@ -235,7 +227,7 @@ public final class Server implements Runnable, IThreadListener {
|
|||
private void startProgress(boolean save, int amount) {
|
||||
this.setTotal(amount);
|
||||
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) {
|
||||
|
@ -258,15 +250,15 @@ public final class Server implements Runnable, IThreadListener {
|
|||
Log.JNI.info("Starte Server Version " + Config.VERSION);
|
||||
if(!this.debug) {
|
||||
this.setMessage("Welt wird erstellt und geladen");
|
||||
FolderInfo info = Region.loadWorldInfo(this.baseDir);
|
||||
FolderInfo info = Region.loadWorldInfo(null);
|
||||
// if(dtime == -1L) // {
|
||||
// dtime = World.START_TIME;
|
||||
//// 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));
|
||||
this.dimensions.put(this.space.dimension.getDimensionId(), this.space);
|
||||
this.playerDir.mkdirs();
|
||||
new File("players").mkdirs();
|
||||
// if(Config.spawnY < 0) {
|
||||
// WorldServer world = this.getWorld(Config.spawnDim);
|
||||
// world = world == null ? this.space : world;
|
||||
|
@ -297,17 +289,17 @@ public final class Server implements Runnable, IThreadListener {
|
|||
Config.set("weatherChanges", "false", null);
|
||||
Config.set("mobSpawning", "false", 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));
|
||||
this.dimensions.put(this.space.dimension.getDimensionId(), this.space);
|
||||
}
|
||||
this.setTpsTarget(20.0f);
|
||||
if(!this.debug) {
|
||||
for(Dimension dim : UniverseRegistry.getDimensions()) {
|
||||
if(WorldServer.needsLoading(this.baseDir, dim)) {
|
||||
if(WorldServer.needsLoading(dim)) {
|
||||
this.getWorld(dim.getDimensionId()).loadForcedChunks();
|
||||
}
|
||||
WorldServer.loadWarps(this.baseDir, dim, this.warps);
|
||||
WorldServer.loadWarps(dim, this.warps);
|
||||
}
|
||||
// this.openLAN();
|
||||
}
|
||||
|
@ -339,17 +331,22 @@ public final class Server implements Runnable, IThreadListener {
|
|||
this.lastPoll = this.currentTime;
|
||||
this.ticksDone = 0L;
|
||||
}
|
||||
if(!this.started) {
|
||||
this.started = true;
|
||||
this.sendPipeIPC("running", true);
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.stopServer();
|
||||
this.stopped = true;
|
||||
this.sendPipeIPC("running", false);
|
||||
}
|
||||
catch(Throwable e) {
|
||||
Log.JNI.error(e, "Fehler beim Beenden des Servers");
|
||||
}
|
||||
finally {
|
||||
this.stopped = true;
|
||||
this.sendPipeIPC("running", false);
|
||||
Log.JNI.info("Server wurde beendet");
|
||||
}
|
||||
}
|
||||
|
@ -365,8 +362,8 @@ public final class Server implements Runnable, IThreadListener {
|
|||
bx = bx >> 4;
|
||||
bz = bz >> 4;
|
||||
long last = System.currentTimeMillis();
|
||||
for(int x = -Config.distance; x <= Config.distance && this.running; x++) {
|
||||
for(int z = -Config.distance; z <= Config.distance && this.running; z++) {
|
||||
for(int x = -Config.distance; x <= Config.distance; x++) {
|
||||
for(int z = -Config.distance; z <= Config.distance; z++) {
|
||||
long time = System.currentTimeMillis();
|
||||
if(time - last >= 10L) {
|
||||
this.setProgress(done);
|
||||
|
@ -436,7 +433,7 @@ public final class Server implements Runnable, IThreadListener {
|
|||
}
|
||||
}
|
||||
if(++this.syncTimer == 20) {
|
||||
this.sendPacket(new SPacketTimeUpdate(this.space.getDayTime()));
|
||||
this.sendPacket(new SPacketTimeUpdate(this.space.getDayTime(), this.getInfo()));
|
||||
this.syncTimer = 0;
|
||||
}
|
||||
this.ticked.clear();
|
||||
|
@ -477,7 +474,7 @@ public final class Server implements Runnable, IThreadListener {
|
|||
Dimension dim = UniverseRegistry.getDimension(dimension);
|
||||
if(dim == null)
|
||||
return null;
|
||||
world = new WorldServer(this, this.baseDir, this.space.getDayTime(),
|
||||
world = new WorldServer(this, this.space.getDayTime(),
|
||||
dim, this.debug);
|
||||
this.worlds.add(world);
|
||||
this.dimensions.put(dimension, world);
|
||||
|
@ -498,10 +495,6 @@ public final class Server implements Runnable, IThreadListener {
|
|||
return this.worlds;
|
||||
}
|
||||
|
||||
public boolean isStopped() {
|
||||
return this.stopped;
|
||||
}
|
||||
|
||||
public long[] getTickTimes() {
|
||||
return this.tickTimes;
|
||||
}
|
||||
|
@ -548,40 +541,16 @@ public final class Server implements Runnable, IThreadListener {
|
|||
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) {
|
||||
synchronized(this) {
|
||||
this.message = message;
|
||||
}
|
||||
this.sendPipeIPC("message", message);
|
||||
}
|
||||
|
||||
private void setProgress(int progress) {
|
||||
synchronized(this) {
|
||||
this.progress = progress;
|
||||
}
|
||||
this.sendPipeIPC("progress", progress);
|
||||
}
|
||||
|
||||
private void setTotal(int total) {
|
||||
synchronized(this) {
|
||||
this.total = total;
|
||||
}
|
||||
this.sendPipeIPC("total", total);
|
||||
}
|
||||
|
||||
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) {
|
||||
if(!this.isMainThread() && !this.stopped) {
|
||||
ListenableFutureTask<V> task = ListenableFutureTask.<V>create(callable);
|
||||
|
@ -661,10 +626,9 @@ public final class Server implements Runnable, IThreadListener {
|
|||
Player conn = new Player(this, connection, loginUser);
|
||||
if(tag != null)
|
||||
conn.readFromNBT(tag);
|
||||
if(!connection.isLocalChannel()) {
|
||||
if(Config.playerLimit > 0 && this.players.size() >= Config.playerLimit && !conn.getAdmin())
|
||||
if(Config.playerLimit > 0 && this.players.size() >= Config.playerLimit && !conn.isAdmin())
|
||||
return String.format("Der Server ist voll (%d/%d)!", this.players.size(), Config.playerLimit);
|
||||
if(Config.auth) {
|
||||
if(!connection.isLocalChannel() && Config.auth) {
|
||||
if(conn.getPassword() == null) {
|
||||
if(!Config.register)
|
||||
return "Anmeldung neuer Accounts ist auf diesem Server deaktiviert (Whitelisted)";
|
||||
|
@ -689,7 +653,6 @@ public final class Server implements Runnable, IThreadListener {
|
|||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
connection.sendPacket(new RPacketLoginSuccess());
|
||||
connection.setNetHandler(conn);
|
||||
this.players.add(conn);
|
||||
|
@ -766,7 +729,7 @@ public final class Server implements Runnable, IThreadListener {
|
|||
return null;
|
||||
NBTTagCompound tag = null;
|
||||
try {
|
||||
File dat = new File(this.playerDir, user + ".nbt");
|
||||
File dat = new File(new File("players"), user + ".nbt");
|
||||
|
||||
if(dat.exists() && dat.isFile()) {
|
||||
tag = NBTLoader.readGZip(dat);
|
||||
|
@ -794,8 +757,8 @@ public final class Server implements Runnable, IThreadListener {
|
|||
// else
|
||||
// etag = new NBTTagCompound();
|
||||
conn.writeToNBT(tag);
|
||||
File tmp = new File(this.playerDir, conn.getUser() + ".nbt.tmp");
|
||||
File dat = new File(this.playerDir, conn.getUser() + ".nbt");
|
||||
File tmp = new File(new File("players"), conn.getUser() + ".nbt.tmp");
|
||||
File dat = new File(new File("players"), conn.getUser() + ".nbt");
|
||||
NBTLoader.writeGZip(tag, tmp);
|
||||
if(dat.exists()) {
|
||||
dat.delete();
|
||||
|
@ -1020,7 +983,7 @@ public final class Server implements Runnable, IThreadListener {
|
|||
}
|
||||
|
||||
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.RAIN_STRENGTH, world.getRainStrength()));
|
||||
conn.sendPacket(new S2BPacketChangeGameState(S2BPacketChangeGameState.Action.DARKNESS, world.getDarkness()));
|
||||
|
@ -1055,41 +1018,21 @@ public final class Server implements Runnable, IThreadListener {
|
|||
NetConnection manager = new NetConnection();
|
||||
Server.this.clients.add(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();
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
for(Player conn : Lists.newArrayList(this.players)) {
|
||||
if(!conn.isLocal())
|
||||
conn.disconnect();
|
||||
}
|
||||
this.terminateEndpoints(false);
|
||||
this.terminateEndpoint();
|
||||
}
|
||||
|
||||
private void terminateEndpoints(boolean local) {
|
||||
private void terminateEndpoint() {
|
||||
synchronized(this.serverThread) {
|
||||
if(this.endpoint != null) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
catch(Exception e) {
|
||||
if(manager.isLocalChannel()) {
|
||||
throw e;
|
||||
}
|
||||
Log.JNI.error(e, "Konnte Paket von " + manager.getCutAddress() + " nicht verarbeiten");
|
||||
manager.sendPacket(new SPacketDisconnect(), new GenericFutureListener<Future<? super Void>>() {
|
||||
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() {
|
||||
return this.warps;
|
||||
}
|
||||
//
|
||||
// public void start() {
|
||||
// this.serverThread.start();
|
||||
// }
|
||||
|
||||
public void start() {
|
||||
this.serverThread.start();
|
||||
}
|
||||
|
||||
void stopServer() {
|
||||
private void stopServer() {
|
||||
if(!this.stopped) {
|
||||
this.setProgress(-1);
|
||||
this.setMessage("Stoppe server");
|
||||
|
@ -1162,7 +1093,7 @@ public final class Server implements Runnable, IThreadListener {
|
|||
for(Player conn : Lists.newArrayList(this.players)) {
|
||||
conn.disconnect();
|
||||
}
|
||||
this.terminateEndpoints(true);
|
||||
this.terminateEndpoint();
|
||||
if(this.started) {
|
||||
Log.JNI.info("Speichere Spieler");
|
||||
this.saveAllPlayerData(true);
|
||||
|
@ -1203,4 +1134,14 @@ public final class Server implements Runnable, IThreadListener {
|
|||
}));
|
||||
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;
|
||||
|
||||
import game.Game;
|
||||
import game.Server;
|
||||
import game.ServerProcess;
|
||||
import game.gui.element.Bar;
|
||||
import game.gui.element.Label;
|
||||
|
||||
|
@ -18,7 +18,7 @@ public class GuiLoading extends Gui {
|
|||
private Bar progressBar1;
|
||||
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() {
|
||||
boolean started = false;
|
||||
|
||||
|
@ -26,8 +26,8 @@ public class GuiLoading extends Gui {
|
|||
if(!this.started && server.isStarted()) {
|
||||
this.started = true;
|
||||
// gm.displayGuiScreen(null);
|
||||
server.setVar("viewDistance", "" + gm.renderDistance);
|
||||
gm.connectToIntegrated(server, user);
|
||||
gm.debugWorld = server.getFolder() == null;
|
||||
gm.connect(null, gm.port, user, "", "", key);
|
||||
// return;
|
||||
}
|
||||
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() {
|
||||
public void poll(Game gm, GuiLoading gui) {
|
||||
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() {
|
||||
public void poll(Game gm, GuiLoading gui) {
|
||||
if(server.isStopped()) {
|
||||
|
|
|
@ -8,7 +8,6 @@ import game.gui.element.ActButton.Mode;
|
|||
import game.gui.element.Label;
|
||||
import game.gui.element.NavButton;
|
||||
import game.gui.element.Textbox;
|
||||
import game.gui.element.Textbox.Action;
|
||||
import game.gui.options.GuiOptions;
|
||||
import game.gui.server.GuiConnect;
|
||||
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"));
|
||||
if(!this.gm.charEditor)
|
||||
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() {
|
||||
public void use(ActButton elem, ActButton.Mode action) {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ public class GuiConnect extends Gui implements Textbox.Callback {
|
|||
this.lastPass = pass;
|
||||
this.lastAcc = acc;
|
||||
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) {
|
||||
|
|
|
@ -1,7 +1,25 @@
|
|||
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 static void register() {
|
||||
private static boolean crashed;
|
||||
|
||||
private static void register() {
|
||||
NameRegistry.register();
|
||||
BlockRegistry.register();
|
||||
FlammabilityRegistry.register();
|
||||
|
@ -17,4 +35,106 @@ public abstract class Registry {
|
|||
RotationRegistry.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,12 +31,9 @@ public class ClientLoginHandler extends NetHandler {
|
|||
}
|
||||
|
||||
public final void handleEnableCompression(RPacketEnableCompression packetIn)
|
||||
{
|
||||
if (!this.networkManager.isLocalChannel())
|
||||
{
|
||||
this.networkManager.setCompressionTreshold(packetIn.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// public void handlePasswordRequest(RPacketPasswordRequest packetIn) {
|
||||
// if(this.server == null) {
|
||||
|
|
|
@ -94,6 +94,7 @@ import game.packet.SPacketMessage;
|
|||
import game.packet.SPacketMultiBlockChange;
|
||||
import game.packet.SPacketPlayerPosLook;
|
||||
import game.packet.SPacketRespawn;
|
||||
import game.packet.SPacketServerTick;
|
||||
import game.packet.SPacketSetExperience;
|
||||
import game.packet.SPacketSkin;
|
||||
import game.packet.SPacketSpawnMob;
|
||||
|
@ -903,7 +904,7 @@ public class ClientPlayer extends NetHandler
|
|||
NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
|
||||
// this.gameController.theWorld.getWorldInfo().setTime(packetIn.getTotalWorldTime());
|
||||
this.gameController.theWorld.setDayTime(packetIn.getWorldTime());
|
||||
this.gameController.setTicked();
|
||||
this.gameController.setTicked(packetIn.getServerinfo());
|
||||
}
|
||||
|
||||
// public void handleCompass(SPacketCompass packetIn)
|
||||
|
@ -1882,6 +1883,11 @@ public class ClientPlayer extends NetHandler
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -1,12 +1,45 @@
|
|||
package game.network;
|
||||
|
||||
import game.Server;
|
||||
import game.init.Config;
|
||||
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 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()
|
||||
{
|
||||
if(!this.netManager.isLocalChannel()) {
|
||||
// SocketAddress address = this.netManager.getRemoteAddress();
|
||||
// if(this.server.isBanned(address)) {
|
||||
//// 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)
|
||||
// {
|
||||
// this.closeConnection("Nutzername '" + this.loginUser + "' ist bereits vergeben.");
|
||||
|
@ -118,7 +105,9 @@ public class LoginHandler extends NetHandler
|
|||
if(this.state != LoginState.PASSWORD)
|
||||
throw new IllegalStateException("Unerwartetes Passwort-Paket");
|
||||
this.loginUser = packetIn.getUser();
|
||||
if(this.netManager.isLocalChannel()) {
|
||||
if(packetIn.getLocal() != null) {
|
||||
// TODO: key verification
|
||||
this.netManager.setLocal();
|
||||
this.loginPass = "";
|
||||
// this.loginUser = Config.localUser;
|
||||
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.EventLoopGroup;
|
||||
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.socket.SocketChannel;
|
||||
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());
|
||||
}
|
||||
};
|
||||
// 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 ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
|
||||
|
||||
|
@ -70,16 +52,11 @@ public class NetConnection extends SimpleChannelInboundHandler<Packet>
|
|||
private boolean disconnected;
|
||||
private boolean local;
|
||||
|
||||
// public NetConnection(PacketDirection packetDirection)
|
||||
// {
|
||||
// this.direction = packetDirection;
|
||||
// }
|
||||
|
||||
public void channelActive(ChannelHandlerContext p_channelActive_1_) throws Exception
|
||||
{
|
||||
super.channelActive(p_channelActive_1_);
|
||||
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();
|
||||
|
||||
try
|
||||
|
@ -324,6 +301,11 @@ public class NetConnection extends SimpleChannelInboundHandler<Packet>
|
|||
return this.local;
|
||||
}
|
||||
|
||||
public void setLocal()
|
||||
{
|
||||
this.local = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
return this.channel != null && this.channel.isOpen();
|
||||
|
|
|
@ -74,6 +74,7 @@ import game.packet.SPacketMessage;
|
|||
import game.packet.SPacketMultiBlockChange;
|
||||
import game.packet.SPacketPlayerPosLook;
|
||||
import game.packet.SPacketRespawn;
|
||||
import game.packet.SPacketServerTick;
|
||||
import game.packet.SPacketSetExperience;
|
||||
import game.packet.SPacketSkin;
|
||||
import game.packet.SPacketSpawnMob;
|
||||
|
@ -178,6 +179,7 @@ public enum PacketRegistry
|
|||
// this.server(SPacketNotify.class);
|
||||
this.server(SPacketDimensionName.class);
|
||||
this.server(SPacketCharacterList.class);
|
||||
this.server(SPacketServerTick.class);
|
||||
|
||||
this.client(CPacketKeepAlive.class);
|
||||
this.client(CPacketMessage.class);
|
||||
|
|
|
@ -274,6 +274,8 @@ public class Player extends NetHandler implements ICrafting, Executor
|
|||
this.pingKey = (int)this.lastPingTime;
|
||||
this.sendPacket(new SPacketKeepAlive(this.pingKey));
|
||||
}
|
||||
if(this.local)
|
||||
|
||||
if(this.respawnTimer > 0) {
|
||||
if(--this.respawnTimer == 0) {
|
||||
this.respawnPlayer();
|
||||
|
@ -2511,7 +2513,7 @@ public class Player extends NetHandler implements ICrafting, Executor
|
|||
NetHandler.checkThread(packetIn, this, this.server);
|
||||
|
||||
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)
|
||||
// this.server.setDone();
|
||||
return;
|
||||
|
@ -2874,6 +2876,26 @@ public class Player extends NetHandler implements ICrafting, Executor
|
|||
}
|
||||
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:
|
||||
throw new IllegalArgumentException("Ungültige Aktion!");
|
||||
}
|
||||
|
|
|
@ -93,6 +93,9 @@ public class CPacketAction implements Packet<Player>
|
|||
HEAL,
|
||||
REPAIR,
|
||||
PERF,
|
||||
MAGNET;
|
||||
MAGNET,
|
||||
SET_VIEWDIST,
|
||||
WARP_MODE,
|
||||
SHUTDOWN;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,16 +12,18 @@ public class LPacketPasswordResponse implements Packet<LoginHandler>
|
|||
private String user;
|
||||
private String access;
|
||||
private String password;
|
||||
private byte[] local;
|
||||
|
||||
public LPacketPasswordResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public LPacketPasswordResponse(String userIn, String accessIn, String passwordIn)
|
||||
public LPacketPasswordResponse(String userIn, String accessIn, String passwordIn, byte[] local)
|
||||
{
|
||||
this.user = userIn;
|
||||
this.access = accessIn;
|
||||
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.access = 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.access);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
public class SPacketTimeUpdate implements Packet<ClientPlayer> {
|
||||
// private long totalWorldTime;
|
||||
private long worldTime;
|
||||
private String serverInfo;
|
||||
|
||||
public SPacketTimeUpdate() {
|
||||
}
|
||||
|
||||
public SPacketTimeUpdate(long totalTimeIn) {
|
||||
// this.totalWorldTime = totalWorldTimeIn;
|
||||
this.worldTime = totalTimeIn;
|
||||
public SPacketTimeUpdate(long time, String info) {
|
||||
this.worldTime = time;
|
||||
this.serverInfo = info;
|
||||
}
|
||||
|
||||
public void readPacketData(PacketBuffer buf) throws IOException {
|
||||
// this.totalWorldTime = buf.readLong();
|
||||
this.worldTime = buf.readLong();
|
||||
this.serverInfo = buf.readStringFromBuffer(512);
|
||||
}
|
||||
|
||||
public void writePacketData(PacketBuffer buf) throws IOException {
|
||||
// buf.writeLong(this.totalWorldTime);
|
||||
buf.writeLong(this.worldTime);
|
||||
buf.writeString(this.serverInfo);
|
||||
}
|
||||
|
||||
public void processPacket(ClientPlayer handler) {
|
||||
handler.handleTimeUpdate(this);
|
||||
}
|
||||
|
||||
// public long getTotalWorldTime() {
|
||||
// return this.totalWorldTime;
|
||||
// }
|
||||
|
||||
public long getWorldTime() {
|
||||
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;
|
||||
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import game.log.Log;
|
||||
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) |
|
||||
(((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 final Server server;
|
||||
private final File dir;
|
||||
private final File chunkDir;
|
||||
private final Random grng;
|
||||
private final Set<NextTickListEntry> ticks = Sets.<NextTickListEntry>newHashSet();
|
||||
|
@ -156,14 +155,13 @@ public final class WorldServer extends World {
|
|||
private long prevUpdate;
|
||||
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);
|
||||
this.server = server;
|
||||
this.dir = dir;
|
||||
// this.time = time;
|
||||
this.daytime = dtime;
|
||||
this.updateViewRadius();
|
||||
this.chunkDir = new File(new File(this.dir, "chunk"), dim.getDimensionName());
|
||||
this.chunkDir = new File(new File("chunk"), dim.getDimensionName());
|
||||
if(!debug) {
|
||||
this.chunkDir.mkdirs();
|
||||
this.seed = this.rand.longv();
|
||||
|
@ -800,10 +798,10 @@ public final class WorldServer extends World {
|
|||
return list;
|
||||
}
|
||||
|
||||
public static boolean needsLoading(File dir, Dimension dim) {
|
||||
public static boolean needsLoading(Dimension dim) {
|
||||
NBTTagCompound tag = null;
|
||||
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())
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
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())
|
||||
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();
|
||||
for(Entry<String, Position> pos : warps.entrySet()) {
|
||||
Dimension dim = UniverseRegistry.getDimension(pos.getValue().dim);
|
||||
|
@ -854,7 +852,7 @@ public final class WorldServer extends World {
|
|||
}
|
||||
for(Dimension dim : UniverseRegistry.getDimensions()) {
|
||||
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) {
|
||||
file.delete();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue