login + network changes, add forms

This commit is contained in:
Sen 2025-05-14 14:58:06 +02:00
parent 111226fe28
commit eba8f6ea98
44 changed files with 894 additions and 224 deletions

View file

@ -765,6 +765,7 @@ public class Client implements IThreadListener {
else if (this.connection != null)
{
this.connection.processReceivedPackets();
this.connection.checkDisconnected();
}
}
@ -2388,11 +2389,9 @@ public class Client implements IThreadListener {
}
public void unload(boolean loading) {
if(this.world != null) {
if(this.getNetHandler() != null)
this.getNetHandler().getNetworkManager().closeChannel("Quitting");
this.unloadWorld();
}
if(this.world != null && this.getNetHandler() != null)
this.getNetHandler().getNetworkManager().closeChannel("Quitting");
this.unloadWorld();
this.displayGuiScreen(GuiMenu.INSTANCE);
}

View file

@ -0,0 +1,118 @@
package client.gui.ingame;
import client.gui.Gui;
import client.gui.element.ActButton;
import client.gui.element.ActButton.Mode;
import client.gui.element.Element;
import client.gui.element.Label;
import client.gui.element.NavButton;
import client.gui.element.Switch;
import client.gui.element.Textbox;
import client.gui.element.Textbox.Action;
import client.gui.element.Toggle;
import client.network.ClientPlayer;
import common.color.TextColor;
import common.packet.CPacketForm;
import common.util.ExtMath;
import common.util.Triplet;
public class GuiForm extends Gui implements ActButton.Callback {
private final int id;
private final String title;
private final Element[] inputs;
private final Label[] labels;
private final Triplet<String, Object, Integer>[] inputData;
private final Object[] outputData;
private boolean sent;
public void init(int width, int height) {
this.add(new Label(0, -100, 300, 20, this.title));
for(int z = 0; z < this.inputs.length; z++) {
final int index = z;
final String name = this.inputData[z].first;
Object obj = this.inputData[z].second;
int param = this.inputData[z].third;
if(obj instanceof Boolean) {
this.inputs[z] = this.add(new Toggle(0, 50 * z, 300, 24, (Boolean)obj, (Boolean)obj, new Toggle.Callback() {
public void use(Toggle elem, boolean value) {
GuiForm.this.outputData[index] = value;
}
}, name));
}
else if(obj instanceof String[]) {
final String[] strs = (String[])obj;
param = ExtMath.clampi(param, 0, strs.length - 1);
this.inputs[z] = this.add(new Switch<String>(0, 50 * z, 300, 24, strs, strs[param], strs[param], new Switch.Callback<String>() {
public void use(Switch<String> elem, String value) {
for(int n = 0; n < strs.length; n++) {
if(value == strs[n]) {
GuiForm.this.outputData[index] = n;
break;
}
}
}
}, name));
}
else {
this.labels[z] = this.add(new Label(0, 50 * z - 20, 300, 20, name, true));
this.inputs[z] = this.add(new Textbox(0, 50 * z, 300, 24, Math.min(param & 0xffff, 256), true, new Textbox.Callback() {
public void use(Textbox elem, Action value) {
if(value == Action.FOCUS)
GuiForm.this.labels[index].setText(name);
}
}, (String)obj));
}
}
this.add(new NavButton(0, 50 * (this.inputs.length + 1), 148, 24, null, "Abbrechen"));
this.add(new ActButton(152, 50 * (this.inputs.length + 1), 148, 24, this, "Senden"));
this.shift();
}
public String getTitle() {
return this.title;
}
public void onGuiClosed() {
if(!this.sent) {
ClientPlayer nethandler = this.gm.getNetHandler();
if(nethandler != null) {
nethandler.addToSendQueue(new CPacketForm(this.id, null));
}
}
}
public GuiForm(int id, String title, Triplet<String, Object, Integer>[] data) {
this.id = id;
this.title = title;
this.inputs = new Element[data.length];
this.labels = new Label[data.length];
this.inputData = data;
this.outputData = new Object[data.length];
for(int z = 0; z < data.length; z++) {
Object obj = data[z].second;
this.outputData[z] = obj instanceof String[] ? data[z].third : obj;
}
}
public void use(ActButton elem, Mode action) {
for(int z = 0; z < this.inputs.length; z++) {
if(this.inputs[z] instanceof Textbox) {
int min = this.inputData[z].third >> 16;
String text = this.inputs[z].getText();
if(text.length() < min) {
if(!GuiForm.this.labels[z].getText().startsWith("" + TextColor.RED))
GuiForm.this.labels[z].setText(TextColor.RED + GuiForm.this.labels[z].getText());
return;
}
this.outputData[z] = text;
}
}
this.sent = true;
ClientPlayer nethandler = this.gm.getNetHandler();
if(nethandler != null) {
nethandler.addToSendQueue(new CPacketForm(this.id, this.outputData));
}
this.gm.displayGuiScreen(null);
}
}

View file

@ -1,6 +1,7 @@
package client.gui.ingame;
import client.gui.Gui;
import client.gui.element.Label;
import client.gui.element.NavButton;
import client.gui.element.Textbox;
import client.gui.element.Textbox.Action;
@ -10,11 +11,14 @@ import common.util.BlockPos;
public class GuiSign extends Gui implements Textbox.Callback {
private final BlockPos position;
private final Textbox[] lines = new Textbox[4];
private final String[] tempLines = new String[this.lines.length];
private final Textbox[] lines;
private final String[] tempLines;
public void init(int width, int height) {
this.add(new Label(0, -140, 300, 20, "Bearbeite Schild"));
this.add(new Label(0, -80, 300, 20, String.format("%d, %d, %d", this.position.getX(), this.position.getY(), this.position.getZ())));
this.add(new Label(0, -50, 300, 20, this.gm.world == null ? "<?>" : this.gm.world.dimension.getFormattedName(false)));
for(int z = 0; z < this.lines.length; z++) {
this.lines[z] = this.add(new Textbox(0, 40 * z, 300, 24, 50, true, this, this.tempLines[z] == null ? "" : this.tempLines[z]));
}
@ -26,7 +30,6 @@ public class GuiSign extends Gui implements Textbox.Callback {
return "Schild bearbeiten";
}
public void onGuiClosed() {
ClientPlayer nethandler = this.gm.getNetHandler();
if(nethandler != null) {
@ -39,7 +42,9 @@ public class GuiSign extends Gui implements Textbox.Callback {
public GuiSign(BlockPos sign, String[] lines) {
this.position = sign;
System.arraycopy(lines, 0, this.tempLines, 0, this.lines.length);
this.lines = new Textbox[lines.length];
this.tempLines = new String[lines.length];
System.arraycopy(lines, 0, this.tempLines, 0, lines.length);
}
public void use(Textbox elem, Action value) {

View file

@ -25,6 +25,7 @@ import client.gui.container.GuiMachine;
import client.gui.container.GuiMerchant;
import client.gui.container.GuiRepair;
import client.gui.ingame.GuiSign;
import client.gui.ingame.GuiForm;
import client.renderer.particle.EntityPickupFX;
import client.renderer.texture.EntityTexManager;
import client.world.WorldClient;
@ -104,6 +105,7 @@ import common.packet.SPacketCollectItem;
import common.packet.SPacketDestroyEntities;
import common.packet.SPacketDimensionName;
import common.packet.SPacketDisconnect;
import common.packet.SPacketDisplayForm;
import common.packet.SPacketEntityEquipment;
import common.packet.SPacketEntityVelocity;
import common.packet.SPacketHeldItemChange;
@ -795,7 +797,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer
*/
public void handleDisconnect(SPacketDisconnect packetIn)
{
this.netManager.closeChannel("Getrennt");
this.netManager.closeChannel(packetIn.getMessage());
}
public void onDisconnect(String reason)
@ -1285,6 +1287,11 @@ public class ClientPlayer extends NetHandler implements IClientPlayer
this.gameController.player.openEditSign((TileEntitySign)tileentity);
}
public void handleForm(SPacketDisplayForm packet) {
NetHandler.checkThread(packet, this, this.gameController, this.clientWorldController);
this.gameController.displayGuiScreen(new GuiForm(packet.getId(), packet.getTitle(), packet.getData()));
}
/**
* Updates a specified sign with the specified text lines
*/
@ -2061,8 +2068,8 @@ public class ClientPlayer extends NetHandler implements IClientPlayer
this.gameController.displayGuiScreen(new GuiMerchant(inventory, title, worldObj));
}
public void displayGuiSign(BlockPos pos, String[] signText) {
this.gameController.displayGuiScreen(new GuiSign(pos, signText));
public void displayGuiSign(BlockPos pos, String[] text) {
this.gameController.displayGuiScreen(new GuiSign(pos, text));
}
public void closeGui() {

View file

@ -28,7 +28,7 @@ public enum BaseBiome {
ICEPLAINS(12, "icePlains", "Eisebene", 0xffffff, -20.0f),
ICEMOUNTAINS(13, "iceMountains", "Vereistes Bergland", 0xa0a0a0, -20.0f),
MUSHROOMPLAINS(14, "mushroomPlains", "Pilzland", 0xff00ff, 16.0f, 100.0f),
BLACKENED(15, "blackened", "Schwarz", 0x000000, 0.0f, 0.0f),
BLACKENED(15, "blackened", "Schwarz", 0x000000, 0.0f, 0.0f, 0x000000, 0x303030, 0x303030),
BEACH(16, "beach", "Strand", 0xfade55, 12.0f, 40.0f),
DESERTHILLS(17, "desertHills", "Wüsten-Bergland", 0xd25f12, 60.0f, 0.0f),
FORESTHILLS(18, "forestHills", "Wald-Bergland", 0x22551c, 8.0f, 80.0f),

View file

@ -1,5 +1,7 @@
package common.block;
import common.entity.npc.EntityNPC;
import common.init.Config;
import common.init.Items;
import common.item.Item;
import common.material.Material;
@ -8,6 +10,7 @@ import common.tileentity.TileEntity;
import common.tileentity.TileEntitySign;
import common.util.BlockPos;
import common.util.BoundingBox;
import common.util.Facing;
import common.world.IBlockAccess;
import common.world.State;
import common.world.World;
@ -22,6 +25,20 @@ public class BlockSign extends BlockContainer
this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f);
}
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
{
if (!worldIn.client && Config.editSigns)
{
TileEntity tileentity = worldIn.getTileEntity(pos);
if (tileentity instanceof TileEntitySign)
{
playerIn.openEditSign((TileEntitySign)tileentity);
}
}
return true;
}
public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
{
return null;

View file

@ -333,8 +333,12 @@ public abstract class Config {
public static boolean itemFallDamage = true;
@Var(name = "registration")
public static boolean register = true;
@Var(name = "authentication")
public static boolean auth = true;
@Var(name = "preload_chunks")
public static boolean preload = true;
@Var(name = "signEditing")
public static boolean editSigns = true;
@Var(name = "keepInventory")
public static boolean keepInventory = false;
@ -348,8 +352,6 @@ public abstract class Config {
public static boolean rabidRabbits = false;
@Var(name = "snowStacking")
public static boolean snowStack = false;
@Var(name = "authentication")
public static boolean auth = false;
// @Var(name = "teleportForAll")
// public static boolean teleportAllowed = false;
// @Var(name = "preload_chunks_all") // Vorsicht Lag!!
@ -454,6 +456,8 @@ public abstract class Config {
public static int eggTimer = 6000;
@Var(name = "connectionTimeout", min = 10, max = 300)
public static int timeout = 30;
@Var(name = "passwordMinLength", min = 1, max = 32)
public static int minPassLength = 8;
// @Var(name = "spawnX", min = -World.MAX_SIZE + 1, max = World.MAX_SIZE - 1)
// public static int spawnX = 0;

View file

@ -45,6 +45,7 @@ import common.packet.SPacketCollectItem;
import common.packet.SPacketDestroyEntities;
import common.packet.SPacketDimensionName;
import common.packet.SPacketDisconnect;
import common.packet.SPacketDisplayForm;
import common.packet.SPacketEntityEquipment;
import common.packet.SPacketEntityVelocity;
import common.packet.SPacketHeldItemChange;
@ -146,11 +147,12 @@ public interface IClientPlayer {
void handleTrades(SPacketTrades packetIn);
void handleWorld(SPacketWorld packetIn);
void handleDimName(SPacketDimensionName packetIn);
void handleForm(SPacketDisplayForm packet);
void displayGUIChest(IInventory chestInventory, InventoryPlayer inventory);
void displayGui(IInteractionObject guiOwner, InventoryPlayer inventory, World worldObj);
void displayGuiHorse(EntityHorse horse, InventoryPlayer inventory, IInventory horseInventory);
void displayGuiMerchant(String title, InventoryPlayer inventory, World worldObj);
void displayGuiSign(BlockPos pos, String[] signText);
void displayGuiSign(BlockPos pos, String[] text);
void closeGui();
}

View file

@ -16,6 +16,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;
@ -167,6 +168,8 @@ public interface IPlayer {
void processBook(CPacketBook packetIn);
void processForm(CPacketForm packet);
List<ChunkPos> getLoadedChunkList();
double getManagedX();
double getManagedZ();

View file

@ -11,6 +11,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;
@ -63,6 +64,7 @@ import common.packet.SPacketCollectItem;
import common.packet.SPacketDestroyEntities;
import common.packet.SPacketDimensionName;
import common.packet.SPacketDisconnect;
import common.packet.SPacketDisplayForm;
import common.packet.SPacketEntityEquipment;
import common.packet.SPacketEntityVelocity;
import common.packet.SPacketHeldItemChange;
@ -181,6 +183,7 @@ public enum PacketRegistry
this.server(SPacketCharacterList.class);
this.server(SPacketServerTick.class);
this.server(SPacketLoading.class);
this.server(SPacketDisplayForm.class);
this.client(CPacketKeepAlive.class);
this.client(CPacketMessage.class);
@ -198,7 +201,7 @@ public enum PacketRegistry
this.client(CPacketSkin.class);
this.client(CPacketSign.class);
this.client(CPacketBook.class);
// this.client(CPacketCmdBlock.class);
this.client(CPacketForm.class);
}
};

View file

@ -0,0 +1,86 @@
package common.packet;
import java.io.IOException;
import common.network.IPlayer;
import common.network.Packet;
import common.network.PacketBuffer;
public class CPacketForm implements Packet<IPlayer>
{
private int id;
private Object[] data;
public CPacketForm()
{
}
public CPacketForm(int id, Object[] data)
{
this.id = id;
this.data = data;
}
public void readPacketData(PacketBuffer buf) throws IOException
{
this.id = buf.readVarIntFromBuffer();
if(!buf.readBoolean()) {
this.data = null;
return;
}
this.data = new Object[buf.readVarIntFromBuffer()];
for(int z = 0; z < this.data.length; z++) {
Object obj;
switch(buf.readByte()) {
case 0:
obj = buf.readBoolean();
break;
case 1:
obj = buf.readVarIntFromBuffer();
break;
default:
obj = buf.readStringFromBuffer(256);
break;
}
this.data[z] = obj;
}
}
public void writePacketData(PacketBuffer buf) throws IOException
{
buf.writeVarIntToBuffer(this.id);
buf.writeBoolean(this.data != null);
if(this.data == null)
return;
buf.writeVarIntToBuffer(this.data.length);
for(int z = 0; z < this.data.length; z++) {
Object obj = this.data[z];
if(obj instanceof Boolean) {
buf.writeByte(0);
buf.writeBoolean((Boolean)obj);
}
else if(obj instanceof Integer) {
buf.writeByte(1);
buf.writeVarIntToBuffer((Integer)obj);
}
else {
buf.writeByte(2);
buf.writeString((String)obj);
}
}
}
public void processPacket(IPlayer handler)
{
handler.processForm(this);
}
public Object[] getData()
{
return this.data;
}
public int getId() {
return this.id;
}
}

View file

@ -6,22 +6,29 @@ import common.network.IClientPlayer;
import common.network.Packet;
import common.network.PacketBuffer;
public class SPacketDisconnect implements Packet<IClientPlayer>
{
public SPacketDisconnect()
{
}
public class SPacketDisconnect implements Packet<IClientPlayer> {
private String message;
public void readPacketData(PacketBuffer buf) throws IOException
{
}
public SPacketDisconnect() {
}
public void writePacketData(PacketBuffer buf) throws IOException
{
}
public SPacketDisconnect(String message) {
this.message = message;
}
public void processPacket(IClientPlayer handler)
{
handler.handleDisconnect(this);
}
public void readPacketData(PacketBuffer buf) throws IOException {
this.message = buf.readStringFromBuffer(2048);
}
public void writePacketData(PacketBuffer buf) throws IOException {
buf.writeString(this.message);
}
public void processPacket(IClientPlayer handler) {
handler.handleDisconnect(this);
}
public String getMessage() {
return this.message;
}
}

View file

@ -0,0 +1,99 @@
package common.packet;
import java.io.IOException;
import common.network.IClientPlayer;
import common.network.Packet;
import common.network.PacketBuffer;
import common.util.Triplet;
public class SPacketDisplayForm implements Packet<IClientPlayer>
{
private int id;
private String title;
private Triplet<String, Object, Integer>[] data;
public SPacketDisplayForm()
{
}
public SPacketDisplayForm(int id, String title, Triplet<String, Object, Integer>[] data)
{
this.id = id;
this.title = title;
this.data = data;
}
public void processPacket(IClientPlayer handler)
{
handler.handleForm(this);
}
public void readPacketData(PacketBuffer buf) throws IOException
{
this.id = buf.readVarIntFromBuffer();
this.title = buf.readStringFromBuffer(256);
this.data = new Triplet[buf.readVarIntFromBuffer()];
for(int z = 0; z < this.data.length; z++) {
String name = buf.readStringFromBuffer(64);
Object obj;
switch(buf.readByte()) {
case 0:
obj = buf.readBoolean();
break;
case 1:
String[] strs = new String[buf.readVarIntFromBuffer()];
obj = strs;
for(int n = 0; n < strs.length; n++) {
strs[n] = buf.readStringFromBuffer(128);
}
break;
default:
obj = buf.readStringFromBuffer(256);
break;
}
this.data[z] = new Triplet<String, Object, Integer>(name, obj, buf.readVarIntFromBuffer());
}
}
public void writePacketData(PacketBuffer buf) throws IOException
{
buf.writeVarIntToBuffer(this.id);
buf.writeString(this.title);
buf.writeVarIntToBuffer(this.data.length);
for(int z = 0; z < this.data.length; z++) {
buf.writeString(this.data[z].first);
Object obj = this.data[z].second;
if(obj instanceof Boolean) {
buf.writeByte(0);
buf.writeBoolean((Boolean)obj);
}
else if(obj instanceof String[]) {
buf.writeByte(1);
String[] strs = (String[])obj;
buf.writeVarIntToBuffer(strs.length);
for(int n = 0; n < strs.length; n++) {
buf.writeString(strs[n]);
}
}
else {
buf.writeByte(2);
buf.writeString((String)obj);
}
buf.writeVarIntToBuffer(this.data[z].third);
}
}
public Triplet<String, Object, Integer>[] getData()
{
return this.data;
}
public String getTitle() {
return this.title;
}
public int getId() {
return this.id;
}
}

View file

@ -0,0 +1,10 @@
package common.util;
public class Triplet<S, T, U> extends Tuple<S, T> {
public final U third;
public Triplet(S first, T second, U third) {
super(first, second);
this.third = third;
}
}

View file

@ -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;
@ -125,6 +127,7 @@ public final class Server implements IThreadListener {
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");
}
@ -1136,41 +1218,11 @@ public final class Server implements IThreadListener {
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() {

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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;

View file

@ -193,6 +193,14 @@ public abstract class Command implements Executable {
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;
}

View file

@ -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));
}

View file

@ -43,7 +43,7 @@ public class DimensionParser extends CompletingParser {
return UniverseRegistry.getWorldNames();
}
public Class<?> getTypeClass() {
public Class<?> getTypeClass(boolean required) {
return Dimension.class;
}
}

View file

@ -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) {

View file

@ -129,7 +129,7 @@ public class EntityListParser extends EntityParser {
return comp;
}
public Class<?> getTypeClass() {
public Class<?> getTypeClass(boolean required) {
return List.class;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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));
}

View file

@ -50,4 +50,8 @@ public class FixedExecutor implements Executor {
public BlockPos getPointedPosition() {
return null;
}
public boolean isConsole() {
return true;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -46,7 +46,7 @@ public class PlayerEntityListParser extends PlayerEntityParser {
return comp;
}
public Class<?> getTypeClass() {
public Class<?> getTypeClass(boolean required) {
return List.class;
}
}

View file

@ -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;
}
}

View file

@ -39,7 +39,7 @@ public class PlayerListParser extends PlayerParser {
return comp;
}
public Class<?> getTypeClass() {
public Class<?> getTypeClass(boolean required) {
return List.class;
}
}

View file

@ -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;
}
}

View file

@ -53,7 +53,7 @@ public class StringParser extends DefaultingParser {
return input;
}
public Class<?> getTypeClass() {
public Class<?> getTypeClass(boolean required) {
return String.class;
}

View file

@ -20,7 +20,7 @@ public class TagParser extends DefaultingParser {
return value;
}
public Class<?> getTypeClass() {
public Class<?> getTypeClass(boolean required) {
return NBTTagCompound.class;
}
}

View file

@ -42,7 +42,7 @@ public class WorldParser extends DimensionParser {
return super.getCompletions(env);
}
public Class<?> getTypeClass() {
public Class<?> getTypeClass(boolean required) {
return WorldServer.class;
}
}

View file

@ -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());
}
}

View 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());
}
}
}

View 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);
}
}

View file

@ -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");

View 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);
}
}

View file

@ -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;

View file

@ -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;
@ -411,6 +415,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)
{
this.getNextWindowId();
@ -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);
}
@ -3148,6 +3079,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;
}

View 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();
}
}