login + network changes, add forms
This commit is contained in:
parent
111226fe28
commit
eba8f6ea98
44 changed files with 894 additions and 224 deletions
|
@ -15,6 +15,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
|
@ -36,6 +37,7 @@ import common.init.Config;
|
|||
import common.init.EntityRegistry;
|
||||
import common.init.Registry;
|
||||
import common.init.UniverseRegistry;
|
||||
import common.init.Config.ValueType;
|
||||
import common.log.Log;
|
||||
import common.nbt.NBTLoader;
|
||||
import common.nbt.NBTTagCompound;
|
||||
|
@ -69,7 +71,6 @@ import common.util.ExtMath;
|
|||
import common.util.LazyLoadBase;
|
||||
import common.util.PortalType;
|
||||
import common.util.Position;
|
||||
import common.util.Tuple;
|
||||
import common.util.Util;
|
||||
import common.util.WorldPos;
|
||||
import common.world.World;
|
||||
|
@ -90,6 +91,7 @@ import server.biome.Biome;
|
|||
import server.clipboard.ReorderRegistry;
|
||||
import server.clipboard.RotationRegistry;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.FixedExecutor;
|
||||
import server.network.HandshakeHandler;
|
||||
import server.network.Player;
|
||||
|
@ -121,10 +123,11 @@ public final class Server implements IThreadListener {
|
|||
|
||||
private WorldServer space;
|
||||
private ChannelFuture endpoint;
|
||||
|
||||
|
||||
private boolean running = true;
|
||||
private boolean stopped;
|
||||
private boolean started;
|
||||
private String endMessage = "Server beendet";
|
||||
|
||||
private long currentTime = System.nanoTime() / 1000L;
|
||||
private long tpsTarget;
|
||||
|
@ -333,6 +336,90 @@ public final class Server implements IThreadListener {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean setVar(Executor exec, String line) {
|
||||
if(line.length() < 1) {
|
||||
for(Entry<String, Config.Value> entry : Config.VARS.entrySet()) {
|
||||
Config.Value cvar = entry.getValue();
|
||||
String v = cvar.getValue();
|
||||
String comp = TextColor.YELLOW + entry.getKey() + TextColor.GRAY + " = ";
|
||||
if(entry.getKey().equals("password") && !v.isEmpty())
|
||||
comp += TextColor.NEON + "'****'";
|
||||
else if(cvar.type == ValueType.STRING)
|
||||
comp += TextColor.NEON + "'" + v + "'";
|
||||
else
|
||||
comp += ((cvar.type == ValueType.BOOLEAN ? (v.equals("true") ? TextColor.GREEN : TextColor.RED) : TextColor.BLUE)) + v;
|
||||
if(!cvar.def.equals(v)) {
|
||||
comp += TextColor.GRAY + " (" + TextColor.BROWN + cvar.def + TextColor.GRAY + ")";
|
||||
}
|
||||
exec.logConsole(comp);
|
||||
}
|
||||
exec.logConsole(TextColor.GREEN + "SVARs insgesamt registriert: %d", Config.VARS.size());
|
||||
return true;
|
||||
}
|
||||
line = line.trim();
|
||||
String[] args = /* line.isEmpty() ? new String[0] : */ line.split(" ", -1);
|
||||
if(args.length == 1) {
|
||||
// case 0:
|
||||
// break;
|
||||
// case 1:
|
||||
Config.Value cfg = Config.VARS.get(args[0]);
|
||||
if(cfg == null)
|
||||
return false;
|
||||
String v = cfg.getValue();
|
||||
String comp = TextColor.YELLOW + args[0] + TextColor.GRAY + " = ";
|
||||
if(cfg.type == ValueType.STRING)
|
||||
comp += TextColor.NEON + "'" + v + "'";
|
||||
else
|
||||
comp += ((cfg.type == ValueType.BOOLEAN ? (v.equals("true") ? TextColor.GREEN : TextColor.RED) : TextColor.BLUE)) + v;
|
||||
if(!cfg.def.equals(v))
|
||||
comp += TextColor.GRAY + " (" + TextColor.BROWN + cfg.def + TextColor.GRAY + ")";
|
||||
exec.logConsole(comp);
|
||||
// break;
|
||||
// default:
|
||||
}
|
||||
else {
|
||||
Config.Value cv = Config.VARS.get(args[0]);
|
||||
if(cv == null)
|
||||
return false;
|
||||
String value = args[1];
|
||||
if(cv.type == ValueType.STRING && "\"\"".equals(value)) {
|
||||
value = "";
|
||||
}
|
||||
// else if(cv.type == ValueType.BOOLEAN && "toggle".equalsIgnoreCase(value)) {
|
||||
// value = "" + !Boolean.parseBoolean(cv.getValue());
|
||||
// }
|
||||
// else
|
||||
if(cv.type == ValueType.BOOLEAN && !"true".equals(value) && !"false".equals(value)) {
|
||||
if(!value.equalsIgnoreCase("true") && !value.equalsIgnoreCase("false")) {
|
||||
exec.logConsole(TextColor.DRED + "'%s' ist nicht 'true' oder 'false'", value);
|
||||
return true;
|
||||
}
|
||||
value = value.toLowerCase();
|
||||
}
|
||||
if(cv.type == ValueType.INTEGER) {
|
||||
try {
|
||||
Integer.parseInt(value);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
exec.logConsole(TextColor.DRED + "'%s' ist keine gültige Zahl", value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(cv.type == ValueType.FLOAT) {
|
||||
try {
|
||||
Float.parseFloat(value);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
exec.logConsole(TextColor.DRED + "'%s' ist keine gültige Zahl", value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Config.set(args[0], value, true);
|
||||
exec.logConsole(TextColor.YELLOW + "%s" + TextColor.GRAY + " -> " + ((cv.type == ValueType.BOOLEAN ? (cv.getValue().equals("true") ? TextColor.GREEN : TextColor.RED) : (cv.type == ValueType.STRING ? TextColor.NEON : TextColor.BLUE))) + "%s", args[0], cv.type == ValueType.STRING ? ("'" + cv.getValue() + "'") : cv.getValue());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void run(int port) {
|
||||
long time = System.currentTimeMillis();
|
||||
Log.JNI.info("Starte " + Config.NAME + " Server Version " + Config.VERSION);
|
||||
|
@ -407,17 +494,12 @@ public final class Server implements IThreadListener {
|
|||
}
|
||||
if(line == null)
|
||||
break;
|
||||
if(line.startsWith("#")) {
|
||||
line = line.substring(1);
|
||||
Tuple<String, String> data = Util.getKeyValue(line);
|
||||
if(data.first.equals("end"))
|
||||
Server.this.shutdown();
|
||||
continue;
|
||||
}
|
||||
final String cmd = line;
|
||||
Server.this.schedule(new Runnable() {
|
||||
public void run() {
|
||||
Server.this.scriptEnv.execute(cmd, new FixedExecutor(Server.this, "#con", "KONSOLE", null));
|
||||
FixedExecutor exec = new FixedExecutor(Server.this, "#con", "KONSOLE", null);
|
||||
if(!Server.this.setVar(exec, cmd))
|
||||
Server.this.scriptEnv.execute(cmd, exec);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -770,9 +852,9 @@ public final class Server implements IThreadListener {
|
|||
if(!Config.register)
|
||||
return "Anmeldung neuer Accounts ist auf diesem Server deaktiviert (Whitelisted)";
|
||||
if(loginPass.length() == 0)
|
||||
return "Ein neues Passwort ist erforderlich um diesen Server zu betreten (mindestens 8 Zeichen)";
|
||||
if(loginPass.length() < 8)
|
||||
return "Passwort ist zu kurz, mindestens 8 Zeichen";
|
||||
return "Ein neues Passwort ist erforderlich um diesen Server zu betreten (mindestens " + Config.minPassLength + " Zeichen)";
|
||||
if(loginPass.length() < Config.minPassLength)
|
||||
return "Passwort ist zu kurz, mindestens " + Config.minPassLength + " Zeichen";
|
||||
conn.setPassword(loginPass);
|
||||
Log.JNI.info(loginUser + " registrierte sich mit Passwort");
|
||||
}
|
||||
|
@ -1135,42 +1217,12 @@ public final class Server implements IThreadListener {
|
|||
player.connection.setPlayerHealthUpdated();
|
||||
player.connection.sendPacket(new SPacketHeldItemChange(player.inventory.currentItem));
|
||||
}
|
||||
|
||||
private void setLanEndpoint(int port) throws IOException {
|
||||
synchronized(this.serverThread) {
|
||||
if(this.endpoint != null)
|
||||
this.unsetLanEndpoint();
|
||||
// throw new IllegalStateException("Eingangspunkt bereits gesetzt");
|
||||
Log.JNI.info("Öffne Port %d auf 0.0.0.0 (Timeout %ds)", port, Config.timeout);
|
||||
this.endpoint = ((ServerBootstrap)((ServerBootstrap)(new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ChannelInitializer<Channel>() {
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
try {
|
||||
channel.config().setOption(ChannelOption.TCP_NODELAY, Boolean.valueOf(true));
|
||||
}
|
||||
catch(ChannelException e) {
|
||||
}
|
||||
channel.pipeline().addLast((String)"timeout", (ChannelHandler)(new ReadTimeoutHandler(Config.timeout)))
|
||||
.addLast((String)"splitter", (ChannelHandler)(new PacketSplitter()))
|
||||
.addLast((String)"decoder", (ChannelHandler)(new PacketDecoder(true)))
|
||||
.addLast((String)"prepender", (ChannelHandler)(new PacketPrepender()))
|
||||
.addLast((String)"encoder", (ChannelHandler)(new PacketEncoder(false)));
|
||||
NetConnection manager = new NetConnection();
|
||||
Server.this.clients.add(manager);
|
||||
channel.pipeline().addLast((String)"packet_handler", (ChannelHandler)manager);
|
||||
manager.setNetHandler(new HandshakeHandler(Server.this, manager));
|
||||
}
|
||||
}).group(SERVER_NIO_EVENTLOOP.getValue()).localAddress((InetAddress)null, port)).bind().syncUninterruptibly();
|
||||
}
|
||||
}
|
||||
|
||||
private void unsetLanEndpoint() {
|
||||
for(Player conn : Lists.newArrayList(this.players)) {
|
||||
conn.disconnect();
|
||||
}
|
||||
this.terminateEndpoint();
|
||||
}
|
||||
|
||||
private void terminateEndpoint() {
|
||||
private void terminateEndpoint(String message) {
|
||||
if(this.started)
|
||||
for(Player conn : Lists.newArrayList(this.players)) {
|
||||
conn.disconnect(message);
|
||||
}
|
||||
synchronized(this.serverThread) {
|
||||
if(this.endpoint != null) {
|
||||
Log.JNI.info("Schließe Port");
|
||||
|
@ -1201,7 +1253,7 @@ public final class Server implements IThreadListener {
|
|||
}
|
||||
catch(Exception e) {
|
||||
Log.JNI.error(e, "Konnte Paket von " + manager.getCutAddress() + " nicht verarbeiten");
|
||||
manager.sendPacket(new SPacketDisconnect(), new GenericFutureListener<Future<? super Void>>() {
|
||||
manager.sendPacket(new SPacketDisconnect(e.getMessage()), new GenericFutureListener<Future<? super Void>>() {
|
||||
public void operationComplete(Future<? super Void> future) throws Exception {
|
||||
manager.closeChannel("Fehlerhaftes Datenpaket");
|
||||
}
|
||||
|
@ -1227,11 +1279,7 @@ public final class Server implements IThreadListener {
|
|||
this.setProgress(-1);
|
||||
this.setMessage("Stoppe server");
|
||||
Log.JNI.info("Beende Server");
|
||||
if(this.started)
|
||||
for(Player conn : Lists.newArrayList(this.players)) {
|
||||
conn.disconnect();
|
||||
}
|
||||
this.terminateEndpoint();
|
||||
this.terminateEndpoint(this.endMessage);
|
||||
if(this.started) {
|
||||
Log.JNI.info("Speichere Spieler");
|
||||
this.saveAllPlayerData(true);
|
||||
|
@ -1243,34 +1291,46 @@ public final class Server implements IThreadListener {
|
|||
}
|
||||
|
||||
public void bind(int port) {
|
||||
// this.schedule(new Runnable() {
|
||||
// public void run() {
|
||||
if(port >= 0) {
|
||||
try {
|
||||
Server.this.setLanEndpoint(port);
|
||||
synchronized(this.serverThread) {
|
||||
if(port >= 0) {
|
||||
try {
|
||||
if(this.endpoint != null)
|
||||
this.terminateEndpoint("Wechsele auf Port " + port);
|
||||
// throw new IllegalStateException("Eingangspunkt bereits gesetzt");
|
||||
Log.JNI.info("Öffne Port %d auf 0.0.0.0 (Timeout %ds)", port, Config.timeout);
|
||||
this.endpoint = ((ServerBootstrap)((ServerBootstrap)(new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ChannelInitializer<Channel>() {
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
try {
|
||||
channel.config().setOption(ChannelOption.TCP_NODELAY, Boolean.valueOf(true));
|
||||
}
|
||||
catch(ChannelException e) {
|
||||
}
|
||||
channel.pipeline().addLast((String)"timeout", (ChannelHandler)(new ReadTimeoutHandler(Config.timeout)))
|
||||
.addLast((String)"splitter", (ChannelHandler)(new PacketSplitter()))
|
||||
.addLast((String)"decoder", (ChannelHandler)(new PacketDecoder(true)))
|
||||
.addLast((String)"prepender", (ChannelHandler)(new PacketPrepender()))
|
||||
.addLast((String)"encoder", (ChannelHandler)(new PacketEncoder(false)));
|
||||
NetConnection manager = new NetConnection();
|
||||
Server.this.clients.add(manager);
|
||||
channel.pipeline().addLast((String)"packet_handler", (ChannelHandler)manager);
|
||||
manager.setNetHandler(new HandshakeHandler(Server.this, manager));
|
||||
}
|
||||
}).group(SERVER_NIO_EVENTLOOP.getValue()).localAddress((InetAddress)null, port)).bind().syncUninterruptibly();
|
||||
}
|
||||
catch(Throwable e) {
|
||||
Log.JNI.error(e, "**** KONNTE NICHT AN PORT " + port + " ANBINDEN!");
|
||||
}
|
||||
}
|
||||
catch(IOException e) {
|
||||
Log.JNI.error(e, "**** KONNTE NICHT AN PORT " + port + " ANBINDEN!");
|
||||
else {
|
||||
if(this.endpoint != null)
|
||||
this.terminateEndpoint("Trenne Verbindung");
|
||||
}
|
||||
}
|
||||
else {
|
||||
Server.this.unsetLanEndpoint();
|
||||
}
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
// Futures.getUnchecked(this.schedule(new Runnable() {
|
||||
// public void run() {
|
||||
// for(Player conn : Lists.newArrayList(Server.this.players)) { // = Server.this.getPlayer(Server.this.owner);
|
||||
// // if(conn != null)
|
||||
// if(conn.isLocal())
|
||||
// Server.this.removePlayer(conn);
|
||||
// }
|
||||
// }
|
||||
// }));
|
||||
public void shutdown(String message) {
|
||||
this.running = false;
|
||||
this.endMessage = message;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
|
|
|
@ -88,7 +88,7 @@ public abstract class ArgumentParser {
|
|||
public abstract Object parse(CommandEnvironment env, String input);
|
||||
public abstract Object getDefault(CommandEnvironment env);
|
||||
public abstract Collection<String> getCompletions(CommandEnvironment env);
|
||||
public abstract Class<?> getTypeClass();
|
||||
public abstract Class<?> getTypeClass(boolean required);
|
||||
|
||||
public final String getName() {
|
||||
return this.name;
|
||||
|
|
|
@ -5,7 +5,7 @@ public class BooleanParser extends EnumParser<Boolean> {
|
|||
super(name, Boolean.class, def, true, false);
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
return this.hasDefault() ? boolean.class : Boolean.class;
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.hasDefault() || required ? boolean.class : Boolean.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class CachedExecutable {
|
|||
continue;
|
||||
}
|
||||
for(ArgumentParser parser : param.getParsers()) {
|
||||
classes.add(parser.getTypeClass());
|
||||
classes.add(parser.getTypeClass(param.isRequired()));
|
||||
}
|
||||
}
|
||||
Method method;
|
||||
|
|
|
@ -192,6 +192,14 @@ public abstract class Command implements Executable {
|
|||
protected Command addString(String name, boolean allowEmpty, StringCompleter completer) {
|
||||
return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completer));
|
||||
}
|
||||
|
||||
protected Command addString(String name, String def, boolean allowEmpty, Object ... completions) {
|
||||
return this.addParameter(new StringParser(name, def, allowEmpty, null, null, null, completions));
|
||||
}
|
||||
|
||||
protected Command addString(String name, String def, boolean allowEmpty, StringCompleter completer) {
|
||||
return this.addParameter(new StringParser(name, def, allowEmpty, null, null, null, completer));
|
||||
}
|
||||
|
||||
public Map<String, Parameter> getParameters() {
|
||||
return this.parameters;
|
||||
|
|
|
@ -19,9 +19,12 @@ import server.command.commands.CommandKick;
|
|||
import server.command.commands.CommandMessage;
|
||||
import server.command.commands.CommandMilk;
|
||||
import server.command.commands.CommandOfflinetp;
|
||||
import server.command.commands.CommandPasswd;
|
||||
import server.command.commands.CommandPotion;
|
||||
import server.command.commands.CommandRebind;
|
||||
import server.command.commands.CommandRemove;
|
||||
import server.command.commands.CommandRevoke;
|
||||
import server.command.commands.CommandShutdown;
|
||||
import server.command.commands.CommandSpawn;
|
||||
import server.command.commands.CommandTele;
|
||||
import server.command.commands.CommandTime;
|
||||
|
@ -269,6 +272,9 @@ public class CommandEnvironment {
|
|||
this.registerExecutable(new CommandWeather());
|
||||
this.registerExecutable(new CommandKick());
|
||||
this.registerExecutable(new CommandMessage());
|
||||
this.registerExecutable(new CommandShutdown());
|
||||
this.registerExecutable(new CommandRebind());
|
||||
this.registerExecutable(new CommandPasswd());
|
||||
|
||||
this.registerExecutable(new CommandHelp(this));
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public class DimensionParser extends CompletingParser {
|
|||
return UniverseRegistry.getWorldNames();
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return Dimension.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,8 +75,8 @@ public class DoubleParser extends DefaultingParser {
|
|||
return (Double)super.getDefault(env);
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
return this.hasDefault() ? double.class : Double.class;
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.hasDefault() || required ? double.class : Double.class;
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
|
|
|
@ -129,7 +129,7 @@ public class EntityListParser extends EntityParser {
|
|||
return comp;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return List.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class EntityParser extends PlayerEntityParser {
|
|||
return comp;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.livingOnly ? EntityLiving.class : Entity.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class EnumParser<T> extends DefaultingParser {
|
|||
return this.selections[id];
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.clazz;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package server.command;
|
|||
import common.entity.Entity;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Position;
|
||||
import server.network.Player;
|
||||
|
||||
public interface Executor {
|
||||
void logConsole(String msg);
|
||||
|
@ -12,6 +13,14 @@ public interface Executor {
|
|||
Entity getPointedEntity();
|
||||
BlockPos getPointedPosition();
|
||||
|
||||
default boolean isConsole() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isPlayer() {
|
||||
return this instanceof Player;
|
||||
}
|
||||
|
||||
default void logConsole(String fmt, Object ... args) {
|
||||
this.logConsole(String.format(fmt, args));
|
||||
}
|
||||
|
|
|
@ -50,4 +50,8 @@ public class FixedExecutor implements Executor {
|
|||
public BlockPos getPointedPosition() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isConsole() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class IntParser extends DefaultingParser {
|
|||
return value;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
return this.hasDefault() ? int.class : Integer.class;
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.hasDefault() || required ? int.class : Integer.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class LongParser extends DefaultingParser {
|
|||
return value;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
return this.hasDefault() ? long.class : Long.class;
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.hasDefault() || required ? long.class : Long.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public class PlayerEntityListParser extends PlayerEntityParser {
|
|||
return comp;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return List.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public class PlayerEntityParser extends PlayerParser {
|
|||
return net == null ? null : net.getPresentEntity();
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return EntityNPC.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class PlayerListParser extends PlayerParser {
|
|||
return comp;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return List.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,14 +20,14 @@ public class PlayerParser extends CompletingParser {
|
|||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
return this.useSender && env.getExecutor() instanceof Player ? (Player)env.getExecutor() : null;
|
||||
return this.useSender && env.getExecutor().isPlayer() ? (Player)env.getExecutor() : null;
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
return env.getServer().getAllUsernames();
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return Player.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public class StringParser extends DefaultingParser {
|
|||
return input;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public class TagParser extends DefaultingParser {
|
|||
return value;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return NBTTagCompound.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class WorldParser extends DimensionParser {
|
|||
return super.getCompletions(env);
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return WorldServer.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,16 +11,16 @@ public class CommandKick extends Command {
|
|||
super("kick");
|
||||
|
||||
this.addPlayer("player", false);
|
||||
this.setParamsOptional();
|
||||
this.addString("message", "Du wurdest vom Server geworfen", false);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, Player player) {
|
||||
if(!(exec instanceof Player))
|
||||
throw new RunException("Dieser Befehl kann nur von Spielern ausgeführt werden");
|
||||
else if(player == exec)
|
||||
public void exec(CommandEnvironment env, Executor exec, Player player, String message) {
|
||||
if(player == exec)
|
||||
throw new RunException("Du kannst nicht dich nicht selbst vom Server werfen");
|
||||
else if(player.getAdmin())
|
||||
throw new RunException("%s ist ein Admin", player.getUser());
|
||||
player.disconnect();
|
||||
player.disconnect(message);
|
||||
exec.logConsole("%s wurde vom Server geworfen", player.getUser());
|
||||
}
|
||||
}
|
||||
|
|
64
server/src/server/command/commands/CommandPasswd.java
Normal file
64
server/src/server/command/commands/CommandPasswd.java
Normal file
|
@ -0,0 +1,64 @@
|
|||
package server.command.commands;
|
||||
|
||||
import common.color.TextColor;
|
||||
import common.init.Config;
|
||||
import common.network.IPlayer;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.network.Player;
|
||||
import server.util.Form;
|
||||
|
||||
public class CommandPasswd extends Command {
|
||||
public CommandPasswd() {
|
||||
super("passwd");
|
||||
|
||||
this.addPlayer("player", true);
|
||||
this.setParamsOptional();
|
||||
this.addString("password", false);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, Player player, String password) {
|
||||
if(exec.isPlayer()) {
|
||||
if(password != null)
|
||||
throw new RunException("Bei Verwendung als Spieler darf kein Passwort angegeben werden");
|
||||
if(player.getAdmin() && player != exec)
|
||||
throw new RunException("%s ist ein Admin", player.getUser());
|
||||
((Player)exec).displayForm(new Form() {
|
||||
private Field checkField;
|
||||
private Field passwordField;
|
||||
private Field confirmField;
|
||||
|
||||
protected void init() {
|
||||
this.checkField = player != exec ? null : this.addField("Aktuelles Passwort", 0, IPlayer.MAX_PASS_LENGTH, "");
|
||||
this.passwordField = this.addField("Neues Passwort", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
|
||||
this.confirmField = this.addField("Passwort bestätigen", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return "Passwort für " + player.getUser() + " ändern";
|
||||
}
|
||||
|
||||
protected void accept() {
|
||||
if(this.checkField != null && !this.checkField.get().equals(player.getPassword())) {
|
||||
exec.logConsole(TextColor.RED + "Falsches Passwort eingegeben");
|
||||
return;
|
||||
}
|
||||
if(!this.passwordField.get().equals(this.confirmField.get())) {
|
||||
exec.logConsole(TextColor.RED + "Passwörter stimmen nicht überein");
|
||||
return;
|
||||
}
|
||||
player.setPassword(this.passwordField.get());
|
||||
exec.logConsole(TextColor.GREEN + "Passwort" + (player != exec ? " für %s" : "") + " gesetzt", player.getUser());
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(exec.isConsole()) {
|
||||
if(password == null)
|
||||
throw new RunException("Bei Verwendung in der Konsole muss ein Passwort angegeben werden");
|
||||
player.setPassword(password);
|
||||
exec.logConsole(TextColor.GREEN + "Passwort für %s gesetzt", player.getUser());
|
||||
}
|
||||
}
|
||||
}
|
17
server/src/server/command/commands/CommandRebind.java
Normal file
17
server/src/server/command/commands/CommandRebind.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package server.command.commands;
|
||||
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
|
||||
public class CommandRebind extends Command {
|
||||
public CommandRebind() {
|
||||
super("rebind");
|
||||
|
||||
this.addInt("port", 1024, 65535);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, int port) {
|
||||
env.getServer().bind(port);
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ public class CommandRevoke extends Command {
|
|||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, Player player) {
|
||||
if(exec instanceof Player)
|
||||
if(!exec.isConsole())
|
||||
throw new RunException("Dieser Befehl kann nur der Konsole ausgeführt werden");
|
||||
// else if(player == exec)
|
||||
// throw new RunException("Du kannst nicht deinen eigenen Admin-Status entfernen");
|
||||
|
|
18
server/src/server/command/commands/CommandShutdown.java
Normal file
18
server/src/server/command/commands/CommandShutdown.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package server.command.commands;
|
||||
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
|
||||
public class CommandShutdown extends Command {
|
||||
public CommandShutdown() {
|
||||
super("shutdown");
|
||||
|
||||
this.setParamsOptional();
|
||||
this.addString("message", "Server beendet", false);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, String message) {
|
||||
env.getServer().shutdown(message);
|
||||
}
|
||||
}
|
|
@ -53,7 +53,7 @@ public class CommandSpawn extends Command {
|
|||
}
|
||||
world.strikeLightning(pos.xCoord, pos.yCoord, pos.zCoord, color,
|
||||
tag != null && tag.hasKey("damage", 3) ? tag.getInteger("damage") : 0, tag != null && tag.hasKey("fire", 1) && tag.getBoolean("fire"),
|
||||
exec instanceof Player && tag != null && tag.hasKey("summoned", 1) && tag.getBoolean("summoned") ? ((Player)exec).getPresentEntity() : null);
|
||||
exec.isPlayer() && tag != null && tag.hasKey("summoned", 1) && tag.getBoolean("summoned") ? ((Player)exec).getPresentEntity() : null);
|
||||
}
|
||||
exec.logConsole("%sBlitz bei %d, %d, %d in %s erschaffen", count == 1 ? "" : (count + "x "), (int)pos.xCoord, (int)pos.yCoord, (int)pos.zCoord, world.dimension.getFormattedName(false));
|
||||
return null;
|
||||
|
|
|
@ -4,7 +4,6 @@ import java.util.Collections;
|
|||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
@ -60,6 +59,7 @@ import common.packet.CPacketBreak;
|
|||
import common.packet.CPacketCheat;
|
||||
import common.packet.CPacketClick;
|
||||
import common.packet.CPacketComplete;
|
||||
import common.packet.CPacketForm;
|
||||
import common.packet.CPacketInput;
|
||||
import common.packet.CPacketKeepAlive;
|
||||
import common.packet.CPacketMessage;
|
||||
|
@ -88,6 +88,7 @@ import common.packet.SPacketCharacterList;
|
|||
import common.packet.SPacketChunkData;
|
||||
import common.packet.SPacketDestroyEntities;
|
||||
import common.packet.SPacketDisconnect;
|
||||
import common.packet.SPacketDisplayForm;
|
||||
import common.packet.SPacketKeepAlive;
|
||||
import common.packet.SPacketLoading;
|
||||
import common.packet.SPacketMapChunkBulk;
|
||||
|
@ -132,6 +133,7 @@ import server.clipboard.RotationRegistry;
|
|||
import server.clipboard.RotationValue;
|
||||
import server.clipboard.Vector;
|
||||
import server.command.Executor;
|
||||
import server.util.Form;
|
||||
import server.world.Region;
|
||||
import server.world.WorldServer;
|
||||
|
||||
|
@ -165,6 +167,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
|
|||
private double lastPosZ;
|
||||
private boolean hasMoved = true;
|
||||
private boolean charEditor = true;
|
||||
private Form form;
|
||||
|
||||
private boolean admin;
|
||||
private int ping;
|
||||
|
@ -200,6 +203,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
|
|||
private float lastHealth = -1.0E8F;
|
||||
private int lastExperience = -99999999;
|
||||
private int currentWindowId;
|
||||
private int currentFormId;
|
||||
|
||||
private int pointedEntity;
|
||||
private BlockPos pointedPosition;
|
||||
|
@ -410,6 +414,11 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
|
|||
{
|
||||
this.currentWindowId = this.currentWindowId % 100 + 1;
|
||||
}
|
||||
|
||||
private void getNextFormId()
|
||||
{
|
||||
this.currentFormId = this.currentFormId % 100 + 1;
|
||||
}
|
||||
|
||||
public void displayTradeGui(EntityNPC npc)
|
||||
{
|
||||
|
@ -1520,9 +1529,10 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
|
|||
this.characters.set(this.selected, tag);
|
||||
}
|
||||
|
||||
public void disconnect()
|
||||
public void disconnect(String message)
|
||||
{
|
||||
this.connection.sendPacket(new SPacketDisconnect(), new GenericFutureListener < Future <? super Void >> ()
|
||||
Log.JNI.info("Trenne %s: %s", this.user, message);
|
||||
this.connection.sendPacket(new SPacketDisconnect(message), new GenericFutureListener < Future <? super Void >> ()
|
||||
{
|
||||
public void operationComplete(Future <? super Void > p_operationComplete_1_) throws Exception
|
||||
{
|
||||
|
@ -1676,87 +1686,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
|
|||
private boolean setVar(String line) {
|
||||
if(!this.isAdmin())
|
||||
return false;
|
||||
if(line.length() < 1) {
|
||||
for(Entry<String, Config.Value> entry : Config.VARS.entrySet()) {
|
||||
Config.Value cvar = entry.getValue();
|
||||
String v = cvar.getValue();
|
||||
String comp = TextColor.YELLOW + entry.getKey() + TextColor.GRAY + " = ";
|
||||
if(entry.getKey().equals("password") && !v.isEmpty())
|
||||
comp += TextColor.NEON + "'****'";
|
||||
else if(cvar.type == ValueType.STRING)
|
||||
comp += TextColor.NEON + "'" + v + "'";
|
||||
else
|
||||
comp += ((cvar.type == ValueType.BOOLEAN ? (v.equals("true") ? TextColor.GREEN : TextColor.RED) : TextColor.BLUE)) + v;
|
||||
if(!cvar.def.equals(v)) {
|
||||
comp += TextColor.GRAY + " (" + TextColor.BROWN + cvar.def + TextColor.GRAY + ")";
|
||||
}
|
||||
this.addConsole(comp);
|
||||
}
|
||||
this.addConsole(TextColor.GREEN + "SVARs insgesamt registriert: %d", Config.VARS.size());
|
||||
return true;
|
||||
}
|
||||
line = line.trim();
|
||||
String[] args = /* line.isEmpty() ? new String[0] : */ line.split(" ", -1);
|
||||
if(args.length == 1) {
|
||||
// case 0:
|
||||
// break;
|
||||
// case 1:
|
||||
Config.Value cfg = Config.VARS.get(args[0]);
|
||||
if(cfg == null)
|
||||
return false;
|
||||
String v = cfg.getValue();
|
||||
String comp = TextColor.YELLOW + args[0] + TextColor.GRAY + " = ";
|
||||
if(cfg.type == ValueType.STRING)
|
||||
comp += TextColor.NEON + "'" + v + "'";
|
||||
else
|
||||
comp += ((cfg.type == ValueType.BOOLEAN ? (v.equals("true") ? TextColor.GREEN : TextColor.RED) : TextColor.BLUE)) + v;
|
||||
if(!cfg.def.equals(v))
|
||||
comp += TextColor.GRAY + " (" + TextColor.BROWN + cfg.def + TextColor.GRAY + ")";
|
||||
this.addConsole(comp);
|
||||
// break;
|
||||
// default:
|
||||
}
|
||||
else {
|
||||
Config.Value cv = Config.VARS.get(args[0]);
|
||||
if(cv == null)
|
||||
return false;
|
||||
String value = args[1];
|
||||
if(cv.type == ValueType.STRING && "\"\"".equals(value)) {
|
||||
value = "";
|
||||
}
|
||||
// else if(cv.type == ValueType.BOOLEAN && "toggle".equalsIgnoreCase(value)) {
|
||||
// value = "" + !Boolean.parseBoolean(cv.getValue());
|
||||
// }
|
||||
// else
|
||||
if(cv.type == ValueType.BOOLEAN && !"true".equals(value) && !"false".equals(value)) {
|
||||
if(!value.equalsIgnoreCase("true") && !value.equalsIgnoreCase("false")) {
|
||||
this.addConsole(TextColor.DRED + "'%s' ist nicht 'true' oder 'false'", value);
|
||||
return true;
|
||||
}
|
||||
value = value.toLowerCase();
|
||||
}
|
||||
if(cv.type == ValueType.INTEGER) {
|
||||
try {
|
||||
Integer.parseInt(value);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
this.addConsole(TextColor.DRED + "'%s' ist keine gültige Zahl", value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(cv.type == ValueType.FLOAT) {
|
||||
try {
|
||||
Float.parseFloat(value);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
this.addConsole(TextColor.DRED + "'%s' ist keine gültige Zahl", value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Config.set(args[0], value, true);
|
||||
this.addConsole(TextColor.YELLOW + "%s" + TextColor.GRAY + " -> " + ((cv.type == ValueType.BOOLEAN ? (cv.getValue().equals("true") ? TextColor.GREEN : TextColor.RED) : (cv.type == ValueType.STRING ? TextColor.NEON : TextColor.BLUE))) + "%s", args[0], cv.type == ValueType.STRING ? ("'" + cv.getValue() + "'") : cv.getValue());
|
||||
}
|
||||
return true;
|
||||
return this.server.setVar(this, line);
|
||||
}
|
||||
|
||||
public void setAdmin(boolean admin) {
|
||||
|
@ -3082,6 +3012,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
|
|||
// this.signCommand = null;
|
||||
// }
|
||||
|
||||
tileentitysign.setPlayer(null);
|
||||
tileentitysign.markDirty();
|
||||
worldserver.markBlockForUpdate(blockpos);
|
||||
}
|
||||
|
@ -3147,6 +3078,20 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void processForm(CPacketForm packet) {
|
||||
NetHandler.checkThread(packet, this, this.server);
|
||||
if(this.charEditor || this.form == null || packet.getId() != this.currentFormId)
|
||||
return;
|
||||
this.form.accept(packet.getData());
|
||||
this.form = null;
|
||||
}
|
||||
|
||||
public void displayForm(Form form) {
|
||||
this.form = form;
|
||||
this.getNextFormId();
|
||||
this.sendPacket(new SPacketDisplayForm(this.currentFormId, form.getTitle(), form.getInputList()));
|
||||
}
|
||||
|
||||
public Entity getPointedEntity() {
|
||||
return this.pointedEntity != -1 && this.entity != null ? this.entity.worldObj.getEntityByID(this.pointedEntity) : null;
|
||||
|
|
179
server/src/server/util/Form.java
Normal file
179
server/src/server/util/Form.java
Normal file
|
@ -0,0 +1,179 @@
|
|||
package server.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.util.Displayable;
|
||||
import common.util.Triplet;
|
||||
|
||||
public abstract class Form {
|
||||
private abstract class FormElement {
|
||||
protected final String name;
|
||||
|
||||
protected FormElement(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
protected abstract Object getInputData();
|
||||
protected abstract int getInputParameter();
|
||||
protected abstract boolean acceptValue(Object obj);
|
||||
}
|
||||
|
||||
protected class Toggle extends FormElement {
|
||||
private boolean value;
|
||||
|
||||
protected Toggle(String name, boolean value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
protected Object getInputData() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
protected int getInputParameter() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected boolean acceptValue(Object obj) {
|
||||
if(obj instanceof Boolean)
|
||||
this.value = (Boolean)obj;
|
||||
return obj instanceof Boolean;
|
||||
}
|
||||
|
||||
public boolean get() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
protected class Switch<T> extends FormElement {
|
||||
private final T[] values;
|
||||
private final int def;
|
||||
|
||||
private T value;
|
||||
|
||||
protected Switch(String name, T[] values, T value) {
|
||||
super(name);
|
||||
this.values = values;
|
||||
this.value = value;
|
||||
int def = 0;
|
||||
for(int z = 0; z < values.length; z++) {
|
||||
if(values[z] == value) {
|
||||
def = z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
protected Object getInputData() {
|
||||
String[] strs = new String[this.values.length];
|
||||
for(int z = 0; z < strs.length; z++) {
|
||||
strs[z] = this.values[z] instanceof Displayable ? ((Displayable)this.values[z]).getDisplay() : String.valueOf(this.values[z]);
|
||||
}
|
||||
return strs;
|
||||
}
|
||||
|
||||
protected int getInputParameter() {
|
||||
return this.def;
|
||||
}
|
||||
|
||||
protected boolean acceptValue(Object obj) {
|
||||
if(obj instanceof Integer && (Integer)obj >= 0 && (Integer)obj < this.values.length) {
|
||||
this.value = this.values[(Integer)obj];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
protected class Field extends FormElement {
|
||||
private final int minLength;
|
||||
private final int maxLength;
|
||||
|
||||
private String value;
|
||||
|
||||
protected Field(String name, String value, int min, int max) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
this.minLength = min;
|
||||
this.maxLength = max;
|
||||
}
|
||||
|
||||
protected Object getInputData() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
protected int getInputParameter() {
|
||||
return (this.minLength << 16) | this.maxLength;
|
||||
}
|
||||
|
||||
protected boolean acceptValue(Object obj) {
|
||||
if(obj instanceof String && ((String)obj).length() >= this.minLength && ((String)obj).length() <= this.maxLength) {
|
||||
this.value = (String)obj;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String get() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
private final List<FormElement> inputs = Lists.newArrayList();
|
||||
|
||||
public Form() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
private <T extends FormElement> T add(T elem) {
|
||||
this.inputs.add(elem);
|
||||
return elem;
|
||||
}
|
||||
|
||||
protected Toggle addToggle(String name, boolean def) {
|
||||
return this.add(new Toggle(name, def));
|
||||
}
|
||||
|
||||
protected <T> Switch<T> addSwitch(String name, T def, T ... values) {
|
||||
return this.add(new Switch<T>(name, values, def));
|
||||
}
|
||||
|
||||
protected Field addField(String name, int minLength, int maxLength, String def) {
|
||||
return this.add(new Field(name, def, minLength, maxLength));
|
||||
}
|
||||
|
||||
public abstract String getTitle();
|
||||
protected abstract void init();
|
||||
protected abstract void accept();
|
||||
|
||||
protected void cancel() {
|
||||
}
|
||||
|
||||
public final Triplet<String, Object, Integer>[] getInputList() {
|
||||
Triplet<String, Object, Integer>[] data = new Triplet[this.inputs.size()];
|
||||
for(int z = 0; z < data.length; z++) {
|
||||
data[z] = new Triplet<String, Object, Integer>(this.inputs.get(z).name, this.inputs.get(z).getInputData(), this.inputs.get(z).getInputParameter());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public final void accept(Object[] data) {
|
||||
if(data == null || data.length != this.inputs.size()) {
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
for(int z = 0; z < data.length; z++) {
|
||||
if(!this.inputs.get(z).acceptValue(data[z])) {
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.accept();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue