2025-03-11 00:23:54 +01:00
|
|
|
package game.network;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
import game.Server;
|
|
|
|
import game.block.Block;
|
|
|
|
import game.block.BlockFence;
|
|
|
|
import game.block.BlockFenceGate;
|
|
|
|
import game.block.BlockWall;
|
|
|
|
import game.clipboard.BlockTransform;
|
|
|
|
import game.clipboard.ClipboardBlock;
|
|
|
|
import game.clipboard.ClipboardPlacer;
|
|
|
|
import game.clipboard.Rotation;
|
|
|
|
import game.clipboard.RotationValue;
|
|
|
|
import game.clipboard.Vector;
|
|
|
|
import game.collect.Lists;
|
|
|
|
import game.color.TextColor;
|
|
|
|
import game.dimension.Dimension;
|
|
|
|
import game.entity.Entity;
|
|
|
|
import game.entity.animal.EntityHorse;
|
|
|
|
import game.entity.item.EntityItem;
|
|
|
|
import game.entity.item.EntityXp;
|
|
|
|
import game.entity.npc.Alignment;
|
|
|
|
import game.entity.npc.EntityHuman;
|
|
|
|
import game.entity.npc.EntityNPC;
|
|
|
|
import game.entity.projectile.EntityArrow;
|
|
|
|
import game.entity.types.EntityLiving;
|
|
|
|
import game.future.Futures;
|
|
|
|
import game.init.BlockRegistry;
|
|
|
|
import game.init.Config;
|
|
|
|
import game.init.Config.ValueType;
|
|
|
|
import game.init.EntityRegistry;
|
|
|
|
import game.init.Items;
|
|
|
|
import game.init.RotationRegistry;
|
|
|
|
import game.init.SoundEvent;
|
|
|
|
import game.init.UniverseRegistry;
|
|
|
|
import game.inventory.Container;
|
|
|
|
import game.inventory.ContainerChest;
|
|
|
|
import game.inventory.ContainerHorseInventory;
|
|
|
|
import game.inventory.ContainerMerchant;
|
|
|
|
import game.inventory.ICrafting;
|
|
|
|
import game.inventory.IInventory;
|
|
|
|
import game.inventory.InventoryPlayer;
|
|
|
|
import game.inventory.Slot;
|
|
|
|
import game.inventory.SlotCrafting;
|
|
|
|
import game.item.ItemControl;
|
|
|
|
import game.item.ItemSpaceNavigator;
|
|
|
|
import game.item.ItemStack;
|
2025-03-11 10:26:48 +01:00
|
|
|
import game.log.Log;
|
2025-03-11 00:23:54 +01:00
|
|
|
import game.material.Material;
|
|
|
|
import game.nbt.NBTTagCompound;
|
|
|
|
import game.nbt.NBTTagList;
|
|
|
|
import game.nbt.NBTTagString;
|
|
|
|
import game.net.util.concurrent.Future;
|
|
|
|
import game.net.util.concurrent.GenericFutureListener;
|
|
|
|
import game.packet.CPacketAction;
|
|
|
|
import game.packet.CPacketBook;
|
|
|
|
import game.packet.CPacketBreak;
|
|
|
|
import game.packet.CPacketCheat;
|
|
|
|
import game.packet.CPacketClick;
|
|
|
|
import game.packet.CPacketComplete;
|
|
|
|
import game.packet.CPacketInput;
|
|
|
|
import game.packet.CPacketKeepAlive;
|
|
|
|
import game.packet.CPacketMessage;
|
|
|
|
import game.packet.CPacketPlace;
|
|
|
|
import game.packet.CPacketPlayer;
|
|
|
|
import game.packet.CPacketSign;
|
|
|
|
import game.packet.CPacketSkin;
|
|
|
|
import game.packet.S18PacketEntityTeleport;
|
|
|
|
import game.packet.S1APacketEntityStatus;
|
|
|
|
import game.packet.S1BPacketEntityAttach;
|
|
|
|
import game.packet.S1DPacketEntityEffect;
|
|
|
|
import game.packet.S1EPacketRemoveEntityEffect;
|
|
|
|
import game.packet.S29PacketSoundEffect;
|
|
|
|
import game.packet.S2DPacketOpenWindow;
|
|
|
|
import game.packet.S2EPacketCloseWindow;
|
|
|
|
import game.packet.S2FPacketSetSlot;
|
|
|
|
import game.packet.S30PacketWindowItems;
|
|
|
|
import game.packet.S31PacketWindowProperty;
|
|
|
|
import game.packet.S32PacketConfirmTransaction;
|
|
|
|
import game.packet.S36PacketSignEditorOpen;
|
|
|
|
import game.packet.S39PacketPlayerAbilities;
|
|
|
|
import game.packet.S3APacketTabComplete;
|
|
|
|
import game.packet.SPacketAnimation;
|
|
|
|
import game.packet.SPacketBlockChange;
|
|
|
|
import game.packet.SPacketChunkData;
|
|
|
|
import game.packet.SPacketDestroyEntities;
|
|
|
|
import game.packet.SPacketDisconnect;
|
|
|
|
import game.packet.SPacketKeepAlive;
|
|
|
|
import game.packet.SPacketMapChunkBulk;
|
|
|
|
import game.packet.SPacketMessage;
|
|
|
|
import game.packet.SPacketPlayerPosLook;
|
|
|
|
import game.packet.SPacketSetExperience;
|
|
|
|
import game.packet.SPacketSkin;
|
|
|
|
import game.packet.SPacketTrades;
|
|
|
|
import game.packet.SPacketUpdateHealth;
|
|
|
|
import game.potion.Potion;
|
|
|
|
import game.potion.PotionEffect;
|
|
|
|
import game.tileentity.IInteractionObject;
|
|
|
|
import game.tileentity.ILockableContainer;
|
|
|
|
import game.tileentity.TileEntity;
|
|
|
|
import game.tileentity.TileEntityMachine;
|
|
|
|
import game.tileentity.TileEntitySign;
|
2025-03-11 10:26:48 +01:00
|
|
|
import game.util.CharValidator;
|
|
|
|
import game.util.ExtMath;
|
2025-03-11 00:23:54 +01:00
|
|
|
import game.village.MerchantRecipeList;
|
|
|
|
import game.world.BlockPos;
|
|
|
|
import game.world.BoundingBox;
|
|
|
|
import game.world.Chunk;
|
|
|
|
import game.world.ChunkPos;
|
|
|
|
import game.world.Facing;
|
|
|
|
import game.world.IntHashMap;
|
|
|
|
import game.world.PortalType;
|
|
|
|
import game.world.Position;
|
|
|
|
import game.world.Region;
|
|
|
|
import game.world.State;
|
|
|
|
import game.world.Vec3i;
|
|
|
|
import game.world.World;
|
|
|
|
import game.world.WorldServer;
|
|
|
|
|
|
|
|
public class NetHandlerPlayServer extends NetHandler implements ICrafting
|
|
|
|
{
|
|
|
|
private static enum EditAction {
|
|
|
|
SELECT("Auswahlmodus"), COPYPASTE("Kopiermodus"), TRANSFORM("Drehmodus");
|
|
|
|
|
|
|
|
private final String display;
|
|
|
|
|
|
|
|
private EditAction(String display) {
|
|
|
|
this.display = display;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static final int MAX_USER_LENGTH = 16;
|
|
|
|
public static final int MAX_NICK_LENGTH = 32;
|
|
|
|
public static final int MAX_PASS_LENGTH = 64;
|
|
|
|
public static final int MAX_CMD_LENGTH = 1024;
|
|
|
|
|
|
|
|
public static final CharValidator VALID_USER = new CharValidator() {
|
|
|
|
public boolean valid(char ch) {
|
|
|
|
return /* (ch >= 'A' && ch <= 'Z') || */ (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-';
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
public static final CharValidator VALID_NICK = new CharValidator() {
|
|
|
|
public boolean valid(char ch) {
|
|
|
|
return (ch <= 0xff && Character.isLetterOrDigit(ch)) || (ch >= 32 && ch < 126);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
private final NetConnection connection;
|
|
|
|
private final Server server;
|
|
|
|
private final String user;
|
|
|
|
private final boolean local;
|
|
|
|
private final IntHashMap<Short> transactions = new IntHashMap();
|
|
|
|
private final List<NBTTagCompound> characters = Lists.newArrayList();
|
|
|
|
|
|
|
|
private EntityNPC entity;
|
|
|
|
private int tickTime;
|
|
|
|
private int lastMoved;
|
|
|
|
private int pingKey;
|
|
|
|
private int selected = -1;
|
|
|
|
private long lastPingTime = System.nanoTime() / 1000000L;
|
|
|
|
private int lastSentPingPacket;
|
|
|
|
private double lastPosX;
|
|
|
|
private double lastPosY;
|
|
|
|
private double lastPosZ;
|
|
|
|
private boolean hasMoved = true;
|
|
|
|
|
|
|
|
private boolean admin;
|
|
|
|
private int ping;
|
|
|
|
private boolean deleted;
|
|
|
|
private String password;
|
|
|
|
|
|
|
|
private int selectionDim = Integer.MIN_VALUE;
|
|
|
|
private ClipboardBlock[][][] clipboard;
|
|
|
|
private int rotation;
|
|
|
|
private boolean flipX;
|
|
|
|
private boolean flipZ;
|
|
|
|
private BlockPos selPos1;
|
|
|
|
private BlockPos selPos2;
|
|
|
|
private Vec3i selOffset;
|
|
|
|
private EditAction edit = EditAction.SELECT;
|
|
|
|
|
|
|
|
private BlockPos startPos = BlockPos.ORIGIN;
|
|
|
|
private BlockPos removingPos = BlockPos.ORIGIN;
|
|
|
|
private boolean isDestroyingBlock;
|
|
|
|
private boolean receivedFinishDiggingPacket;
|
|
|
|
private int initialDamage;
|
|
|
|
private int curblockDamage;
|
|
|
|
private int initialBlockDamage;
|
|
|
|
private int durabilityRemainingOnBlock = -1;
|
|
|
|
|
|
|
|
public boolean isChangingQuantityOnly;
|
|
|
|
private int respawnTimer;
|
|
|
|
|
|
|
|
public double managedPosX;
|
|
|
|
public double managedPosZ;
|
|
|
|
private float combinedHealth = Float.MIN_VALUE;
|
|
|
|
private float lastHealth = -1.0E8F;
|
|
|
|
private int lastExperience = -99999999;
|
|
|
|
private int currentWindowId;
|
|
|
|
|
|
|
|
public final List<ChunkPos> loadedChunks = new LinkedList<ChunkPos>();
|
|
|
|
private final List<Integer> destroyedItemsNetCache = new LinkedList<Integer>();
|
|
|
|
// private final Set<StatBase> statsQueue = Sets.<StatBase>newHashSet();
|
|
|
|
// private final Map<StatBase, Integer> stats = Maps.<StatBase, Integer>newConcurrentMap();
|
|
|
|
|
|
|
|
public static boolean isValidUser(String user) {
|
|
|
|
return VALID_USER.valid(user);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isValidNick(String user) {
|
|
|
|
return VALID_NICK.valid(user);
|
|
|
|
}
|
|
|
|
|
|
|
|
public NetHandlerPlayServer(Server server, NetConnection connection, String user)
|
|
|
|
{
|
|
|
|
this.user = user;
|
|
|
|
this.server = server;
|
|
|
|
this.connection = connection;
|
|
|
|
this.local = connection.isLocalChannel();
|
|
|
|
}
|
|
|
|
|
|
|
|
public EntityNPC createPlayer(WorldServer world, String id) {
|
|
|
|
this.entity = (EntityNPC)EntityRegistry.createEntityByName(id, world);
|
|
|
|
if(this.entity == null)
|
|
|
|
this.entity = new EntityHuman(world);
|
|
|
|
this.entity.setServerPlayer(this);
|
|
|
|
this.isDestroyingBlock = false;
|
|
|
|
this.receivedFinishDiggingPacket = false;
|
|
|
|
this.initialDamage = 0;
|
|
|
|
this.curblockDamage = 0;
|
|
|
|
this.initialBlockDamage = 0;
|
|
|
|
this.durabilityRemainingOnBlock = -1;
|
|
|
|
this.managedPosX = 0.0;
|
|
|
|
this.managedPosZ = 0.0;
|
|
|
|
this.combinedHealth = Float.MIN_VALUE;
|
|
|
|
this.lastHealth = -1.0E8F;
|
|
|
|
this.lastExperience = -99999999;
|
|
|
|
this.currentWindowId = 0;
|
|
|
|
this.loadedChunks.clear();
|
|
|
|
// this.destroyedItemsNetCache.clear();
|
|
|
|
return this.entity;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void update()
|
|
|
|
{
|
|
|
|
++this.tickTime;
|
|
|
|
if (this.tickTime - this.lastSentPingPacket > 40)
|
|
|
|
{
|
|
|
|
this.lastSentPingPacket = this.tickTime;
|
|
|
|
this.lastPingTime = System.nanoTime() / 1000000L;
|
|
|
|
this.pingKey = (int)this.lastPingTime;
|
|
|
|
this.sendPacket(new SPacketKeepAlive(this.pingKey));
|
|
|
|
}
|
|
|
|
if(this.respawnTimer > 0) {
|
|
|
|
if(--this.respawnTimer == 0) {
|
|
|
|
this.respawnPlayer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onEntityDeath() {
|
|
|
|
this.entity.sendDeathMessage();
|
|
|
|
|
|
|
|
if (!Config.keepInventory && Config.playerDrop)
|
|
|
|
{
|
|
|
|
this.entity.inventory.dropAllItems();
|
|
|
|
}
|
|
|
|
if(Config.skullDrop) {
|
|
|
|
ItemStack stack = new ItemStack(Items.skull, 1, 0);
|
|
|
|
this.entity.dropItem(stack, true, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
EntityLiving entitylivingbase = this.entity.getAttackingEntity();
|
|
|
|
|
|
|
|
if (entitylivingbase != null)
|
|
|
|
{
|
|
|
|
// EntityEggInfo entitylist$entityegginfo = (EntityEggInfo)EntityRegistry.SPAWN_EGGS.get(EntityRegistry.getEntityString(entitylivingbase));
|
|
|
|
//
|
|
|
|
// if (entitylist$entityegginfo != null)
|
|
|
|
// {
|
|
|
|
// this.entity.triggerAchievement(entitylist$entityegginfo.killedByStat);
|
|
|
|
// }
|
|
|
|
|
|
|
|
if(entitylivingbase.isPlayer())
|
|
|
|
((EntityNPC)entitylivingbase).connection.addToPlayerScore(this.entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
// this.entity.triggerAchievement(StatRegistry.deathsStat);
|
|
|
|
// this.setListsDirty();
|
|
|
|
// this.removeStat(StatRegistry.timeSinceDeathStat);
|
|
|
|
this.entity.resetCombat();
|
|
|
|
|
|
|
|
if(Config.respawnTime > 0)
|
|
|
|
this.respawnTimer = ExtMath.clampi(Config.respawnTime, 2, 20);
|
|
|
|
}
|
|
|
|
|
|
|
|
public EntityNPC getEntity() {
|
|
|
|
return this.entity;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getUser() {
|
|
|
|
return this.user;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isLocal() {
|
|
|
|
return this.local;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getLatency() {
|
|
|
|
return this.ping;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isAdmin() {
|
|
|
|
return this.admin || this.local;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean getAdmin() {
|
|
|
|
return this.admin;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setAdmin(boolean admin) {
|
|
|
|
this.admin = admin;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPassword(String pass) {
|
|
|
|
this.password = pass;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getPassword() {
|
|
|
|
return this.password;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void addSelfToInternalCraftingInventory()
|
|
|
|
{
|
|
|
|
this.entity.openContainer.onCraftGuiOpened(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addToPlayerScore(EntityLiving entity)
|
|
|
|
{
|
|
|
|
// if (entity.isPlayer())
|
|
|
|
// {
|
|
|
|
// this.entity.triggerAchievement(StatRegistry.playerKillsStat);
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// this.entity.triggerAchievement(StatRegistry.killsStat);
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
private void sendTileEntityUpdate(TileEntity p_147097_1_)
|
|
|
|
{
|
|
|
|
if (p_147097_1_ != null)
|
|
|
|
{
|
|
|
|
Packet packet = p_147097_1_.getDescriptionPacket();
|
|
|
|
|
|
|
|
if (packet != null)
|
|
|
|
{
|
|
|
|
this.sendPacket(packet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void handleFalling(double p_71122_1_, boolean p_71122_3_)
|
|
|
|
{
|
|
|
|
int i = ExtMath.floord(this.entity.posX);
|
|
|
|
int j = ExtMath.floord(this.entity.posY - 0.20000000298023224D);
|
|
|
|
int k = ExtMath.floord(this.entity.posZ);
|
|
|
|
BlockPos blockpos = new BlockPos(i, j, k);
|
|
|
|
Block block = this.entity.worldObj.getState(blockpos).getBlock();
|
|
|
|
|
|
|
|
if (block.getMaterial() == Material.air)
|
|
|
|
{
|
|
|
|
Block block1 = this.entity.worldObj.getState(blockpos.down()).getBlock();
|
|
|
|
|
|
|
|
if (block1 instanceof BlockFence || block1 instanceof BlockWall || block1 instanceof BlockFenceGate)
|
|
|
|
{
|
|
|
|
blockpos = blockpos.down();
|
|
|
|
block = this.entity.worldObj.getState(blockpos).getBlock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.updateEntityFall(p_71122_1_, p_71122_3_, block, blockpos);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void getNextWindowId()
|
|
|
|
{
|
|
|
|
this.currentWindowId = this.currentWindowId % 100 + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void displayTradeGui(EntityNPC npc)
|
|
|
|
{
|
|
|
|
this.getNextWindowId();
|
|
|
|
this.entity.openContainer = new ContainerMerchant(this.entity.inventory, npc, this.entity.worldObj);
|
|
|
|
this.entity.openContainer.windowId = this.currentWindowId;
|
|
|
|
this.entity.openContainer.onCraftGuiOpened(this);
|
|
|
|
IInventory iinventory = ((ContainerMerchant)this.entity.openContainer).getMerchantInventory();
|
|
|
|
String ichatcomponent = npc.getName();
|
|
|
|
this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, "trade", ichatcomponent, iinventory.getSizeInventory()));
|
|
|
|
MerchantRecipeList merchantrecipelist = npc.getTrades(this.entity);
|
|
|
|
|
|
|
|
if (merchantrecipelist != null)
|
|
|
|
{
|
|
|
|
// PacketBuffer packetbuffer = new PacketBuffer(Unpooled.buffer());
|
|
|
|
// packetbuffer.writeInt(this.currentWindowId);
|
|
|
|
// merchantrecipelist.writeToBuf(packetbuffer);
|
|
|
|
this.sendPacket(new SPacketTrades(merchantrecipelist, this.currentWindowId));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateHeldItem()
|
|
|
|
{
|
|
|
|
if (!this.isChangingQuantityOnly)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S2FPacketSetSlot(-1, -1, this.entity.inventory.getItemStack()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void closeContainer()
|
|
|
|
{
|
|
|
|
this.entity.openContainer.onContainerClosed(this.entity);
|
|
|
|
this.entity.openContainer = this.entity.inventoryContainer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setEntityActionState(float p_110430_1_, float p_110430_2_, boolean p_110430_3_, boolean sneaking)
|
|
|
|
{
|
|
|
|
if (this.entity.vehicle != null)
|
|
|
|
{
|
|
|
|
if (p_110430_1_ >= -1.0F && p_110430_1_ <= 1.0F)
|
|
|
|
{
|
|
|
|
this.entity.moveStrafe = p_110430_1_;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p_110430_2_ >= -1.0F && p_110430_2_ <= 1.0F)
|
|
|
|
{
|
|
|
|
this.entity.moveForward = p_110430_2_;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.setJumping(p_110430_3_);
|
|
|
|
this.entity.setSneaking(sneaking);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPlayerHealthUpdated()
|
|
|
|
{
|
|
|
|
this.lastHealth = -1.0E8F;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void clonePlayer(EntityNPC oldPlayer)
|
|
|
|
{
|
|
|
|
if(Config.keepInventory)
|
|
|
|
this.entity.inventory.copyInventory(oldPlayer.inventory);
|
|
|
|
this.entity.experienceLevel = oldPlayer.experienceLevel;
|
|
|
|
this.entity.experienceTotal = oldPlayer.experienceTotal;
|
|
|
|
this.entity.experience = oldPlayer.experience;
|
|
|
|
this.entity.setXPSeed(oldPlayer.getXPSeed());
|
|
|
|
this.entity.setWarpChest(oldPlayer.getWarpChest());
|
|
|
|
// this.entity.getDataWatcher().updateObject(10, Integer.valueOf(oldPlayer.getDataWatcher().getWatchableObjectInt(10)));
|
|
|
|
this.lastExperience = -1;
|
|
|
|
this.lastHealth = -1.0F;
|
|
|
|
// this.destroyedItemsNetCache.addAll(oldPlayer.connection.destroyedItemsNetCache);
|
|
|
|
this.entity.setSkin(oldPlayer.getSkin());
|
|
|
|
this.entity.getDataWatcher().updateObject(29, oldPlayer.getDataWatcher().getWatchableObjectFloat(29));
|
|
|
|
// this.entity.getDataWatcher().updateObject(11, oldPlayer.getDataWatcher().getWatchableObjectByte(11));
|
|
|
|
this.entity.getDataWatcher().updateObject(1, oldPlayer.getDataWatcher().getWatchableObjectString(1));
|
|
|
|
this.entity.getDataWatcher().updateObject(18, oldPlayer.getDataWatcher().getWatchableObjectByte(18));
|
|
|
|
this.entity.setAlignment(oldPlayer.getAlignment());
|
|
|
|
// this.stats.putAll(oldPlayer.stats);
|
|
|
|
// this.statsQueue.addAll(oldPlayer.statsQueue);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeEntity(Entity p_152339_1_)
|
|
|
|
{
|
|
|
|
if (p_152339_1_.isPlayer())
|
|
|
|
{
|
|
|
|
this.sendPacket(new SPacketDestroyEntities(p_152339_1_.getId()));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.destroyedItemsNetCache.add(Integer.valueOf(p_152339_1_.getId()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void sendStats() {
|
|
|
|
// long upd = this.server.getTickCounter();
|
|
|
|
// Map<StatBase, Integer> map = Maps.<StatBase, Integer>newHashMap();
|
|
|
|
//// if(upd - this.lastStatsUpdate > 300) {
|
|
|
|
//// this.lastStatsUpdate = upd;
|
|
|
|
// for(StatBase stat : this.statsQueue) {
|
|
|
|
// map.put(stat, this.getStat(stat));
|
|
|
|
// }
|
|
|
|
// this.statsQueue.clear();
|
|
|
|
//// }
|
|
|
|
// this.sendPacket(new S37PacketStatistics(map));
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public void initializeStats() {
|
|
|
|
// for(StatBase stat : this.stats.keySet()) {
|
|
|
|
// this.statsQueue.add(stat);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// private void setStat(StatBase stat, int value) {
|
|
|
|
// this.stats.put(stat, value);
|
|
|
|
// this.statsQueue.add(stat);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// private int getStat(StatBase stat) {
|
|
|
|
// Integer i = this.stats.get(stat);
|
|
|
|
// return i == null ? 0 : i.intValue();
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void sendPlayerAbilities()
|
|
|
|
{
|
|
|
|
if (this.entity != null)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S39PacketPlayerAbilities(this.entity));
|
|
|
|
this.entity.updateEffectMeta();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addFeed(String msg) {
|
|
|
|
this.sendPacket(new SPacketMessage(msg));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addFeed(String format, Object... args) {
|
|
|
|
this.sendPacket(new SPacketMessage(String.format(format, args)));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendPickupMessage(Entity entity, int amount) {
|
|
|
|
if(entity instanceof EntityItem)
|
|
|
|
if(amount == 1)
|
|
|
|
this.addFeed(TextColor.DGREEN + "* %s aufgelesen",
|
|
|
|
((EntityItem)entity).getEntityItem().getColoredName(TextColor.DGREEN));
|
|
|
|
else
|
|
|
|
this.addFeed(TextColor.DGREEN + "* %d %s aufgelesen", amount,
|
|
|
|
((EntityItem)entity).getEntityItem().getColoredName(TextColor.DGREEN));
|
|
|
|
else if(entity instanceof EntityArrow)
|
|
|
|
this.addFeed(TextColor.DGREEN + "* Pfeil aufgelesen", amount);
|
|
|
|
else if(entity instanceof EntityXp)
|
|
|
|
this.addFeed(TextColor.GREEN + "* %d Erfahrung gesammelt", amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendThrowMessage(ItemStack stack) {
|
|
|
|
if(stack.stackSize == 1)
|
|
|
|
this.addFeed(TextColor.DRED + "* %s weg geworfen",
|
|
|
|
stack.getColoredName(TextColor.DRED));
|
|
|
|
else
|
|
|
|
this.addFeed(TextColor.DRED + "* %d %s weg geworfen", stack.stackSize,
|
|
|
|
stack.getColoredName(TextColor.DRED));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void readFromNBT(NBTTagCompound tag) {
|
|
|
|
this.admin = tag.getBoolean("admin");
|
|
|
|
if(tag.hasKey("password", 8))
|
|
|
|
this.password = tag.getString("password");
|
|
|
|
this.selected = tag.getInteger("selected");
|
|
|
|
NBTTagList list = tag.getTagList("characters", 10);
|
|
|
|
for(int z = 0; z < list.tagCount(); z++) {
|
|
|
|
this.characters.add(list.getCompoundTagAt(z));
|
|
|
|
}
|
|
|
|
this.selected = Math.min(this.selected, this.characters.size() - 1);
|
|
|
|
// this.stats.clear();
|
|
|
|
// if(tag.hasKey("Stats", 10)) {
|
|
|
|
// NBTTagCompound stats = tag.getCompoundTag("Stats");
|
|
|
|
// for(String key : stats.getKeySet()) {
|
|
|
|
// StatBase stat = StatRegistry.getStat(key);
|
|
|
|
// if(stat == null) {
|
|
|
|
// Log.warn("Ungültige Statistik: Statistik '" + key + "' ist unbekannt");
|
|
|
|
// continue;
|
|
|
|
// }
|
|
|
|
// this.stats.put(stat, stats.getInteger(key));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
public void writeToNBT(NBTTagCompound tag) {
|
|
|
|
if(this.admin)
|
|
|
|
tag.setBoolean("admin", this.admin);
|
|
|
|
if(this.password != null)
|
|
|
|
tag.setString("password", this.password);
|
|
|
|
if(!this.characters.isEmpty()) {
|
|
|
|
tag.setInteger("selected", this.selected);
|
|
|
|
NBTTagList list = new NBTTagList();
|
|
|
|
for(NBTTagCompound etag : this.characters) {
|
|
|
|
list.appendTag(etag);
|
|
|
|
}
|
|
|
|
tag.setTag("characters", list);
|
|
|
|
}
|
|
|
|
// NBTTagCompound stats = new NBTTagCompound();
|
|
|
|
// for(Entry<StatBase, Integer> entry : this.stats.entrySet()) {
|
|
|
|
// stats.setInteger(entry.getKey().statId, entry.getValue());
|
|
|
|
// }
|
|
|
|
// tag.setTag("Stats", stats);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void resetLastExperience()
|
|
|
|
{
|
|
|
|
this.lastExperience = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void travelToDimension(int dimensionId, BlockPos pos, float yaw, float pitch, PortalType portal)
|
|
|
|
{
|
|
|
|
this.server.transferToDimension(this.entity, dimensionId, pos, yaw, pitch, portal);
|
|
|
|
this.lastExperience = -1;
|
|
|
|
this.lastHealth = -1.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void teleport(double x, double y, double z, float yaw, float pitch, int dimension) {
|
|
|
|
x = ExtMath.clampd(x, -World.MAX_SIZE + 1, World.MAX_SIZE - 1);
|
|
|
|
z = ExtMath.clampd(z, -World.MAX_SIZE + 1, World.MAX_SIZE - 1);
|
|
|
|
// this.setLastTeleport(this.getLocation());
|
|
|
|
this.entity.unmount();
|
|
|
|
// this.mountEntity(null);
|
|
|
|
if(this.entity.worldObj.dimension.getDimensionId() != dimension)
|
|
|
|
this.travelToDimension(dimension, new BlockPos(x, y, z), yaw, pitch, null);
|
|
|
|
this.setPlayerLocation(x, y, z, yaw, pitch);
|
|
|
|
this.entity.setRotationYawHead(yaw);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onItemPickup(Entity entity, int amount)
|
|
|
|
{
|
|
|
|
this.entity.openContainer.detectAndSendChanges();
|
|
|
|
if(!entity.dead)
|
|
|
|
this.sendPickupMessage(entity, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void mountEntity(Entity entityIn)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S1BPacketEntityAttach(0, this.entity, this.entity.vehicle));
|
|
|
|
this.setPlayerLocation(this.entity.posX, this.entity.posY, this.entity.posZ, this.entity.rotYaw, this.entity.rotPitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void openEditSign(TileEntitySign signTile)
|
|
|
|
{
|
|
|
|
signTile.setPlayer(this.entity);
|
|
|
|
this.sendPacket(new S36PacketSignEditorOpen(signTile.getPos()));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void displayGui(IInteractionObject guiOwner)
|
|
|
|
{
|
|
|
|
this.getNextWindowId();
|
|
|
|
this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, guiOwner.getGuiID(), guiOwner.getCommandName()));
|
|
|
|
this.entity.openContainer = guiOwner.createContainer(this.entity.inventory, this.entity);
|
|
|
|
this.entity.openContainer.windowId = this.currentWindowId;
|
|
|
|
this.entity.openContainer.onCraftGuiOpened(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void displayGUIChest(IInventory chestInventory)
|
|
|
|
{
|
|
|
|
if (this.entity.openContainer != this.entity.inventoryContainer)
|
|
|
|
{
|
|
|
|
this.closeScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (chestInventory instanceof ILockableContainer)
|
|
|
|
{
|
|
|
|
ILockableContainer ilockablecontainer = (ILockableContainer)chestInventory;
|
|
|
|
|
|
|
|
if (ilockablecontainer.isLocked() && !this.entity.canOpen(ilockablecontainer.getLockCode())) // && !this.isSpectator())
|
|
|
|
{
|
|
|
|
this.addFeed(TextColor.RED + "%s ist verschlossen!", chestInventory.getCommandName());
|
|
|
|
this.sendPacket(new S29PacketSoundEffect(SoundEvent.DOOR, this.entity.posX, this.entity.posY, this.entity.posZ, 1.0F, 1.0F));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.getNextWindowId();
|
|
|
|
|
|
|
|
if (chestInventory instanceof TileEntityMachine)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, "machine_" + ((IInteractionObject)chestInventory).getGuiID(), chestInventory.getCommandName(), chestInventory.getSizeInventory(),
|
|
|
|
((TileEntityMachine)chestInventory).getPos()));
|
|
|
|
this.entity.openContainer = ((IInteractionObject)chestInventory).createContainer(this.entity.inventory, this.entity);
|
|
|
|
}
|
|
|
|
else if (chestInventory instanceof IInteractionObject)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, ((IInteractionObject)chestInventory).getGuiID(), chestInventory.getCommandName(), chestInventory.getSizeInventory()));
|
|
|
|
this.entity.openContainer = ((IInteractionObject)chestInventory).createContainer(this.entity.inventory, this.entity);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, "container", chestInventory.getCommandName(), chestInventory.getSizeInventory()));
|
|
|
|
this.entity.openContainer = new ContainerChest(this.entity.inventory, chestInventory, this.entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.openContainer.windowId = this.currentWindowId;
|
|
|
|
this.entity.openContainer.onCraftGuiOpened(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void displayGUIHorse(EntityHorse horse, IInventory horseInventory)
|
|
|
|
{
|
|
|
|
if (this.entity.openContainer != this.entity.inventoryContainer)
|
|
|
|
{
|
|
|
|
this.closeScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.getNextWindowId();
|
|
|
|
this.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, "EntityHorse", horseInventory.getCommandName(), horseInventory.getSizeInventory(), horse.getId()));
|
|
|
|
this.entity.openContainer = new ContainerHorseInventory(this.entity.inventory, horseInventory, horse, this.entity);
|
|
|
|
this.entity.openContainer.windowId = this.currentWindowId;
|
|
|
|
this.entity.openContainer.onCraftGuiOpened(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void displayGUIBook(ItemStack bookStack)
|
|
|
|
// {
|
|
|
|
// Item item = bookStack.getItem();
|
|
|
|
//
|
|
|
|
// if (item == Items.writable_book)
|
|
|
|
// {
|
|
|
|
// this.sendPacket(new SPacketBook());
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
public void closeScreen()
|
|
|
|
{
|
|
|
|
this.sendPacket(new S2EPacketCloseWindow(this.entity.openContainer.windowId));
|
|
|
|
this.closeContainer();
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void addStat(int amount)
|
|
|
|
// {
|
|
|
|
// this.setStat(stat, this.getStat(stat) + amount);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public void removeStat(StatBase stat)
|
|
|
|
// {
|
|
|
|
// if (stat != null)
|
|
|
|
// {
|
|
|
|
// this.setStat(stat, 0);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
public void onItemUseFinish()
|
|
|
|
{
|
|
|
|
this.sendPacket(new S1APacketEntityStatus(this.entity, (byte)9));
|
|
|
|
}
|
|
|
|
|
|
|
|
// /**
|
|
|
|
// * sets the itemInUse when the use item button is clicked. Args: itemstack, int maxItemUseDuration
|
|
|
|
// */
|
|
|
|
// public void setItemInUse(ItemStack stack, int duration)
|
|
|
|
// {
|
|
|
|
// super.setItemInUse(stack, duration);
|
|
|
|
//
|
|
|
|
// if (stack != null && stack.getItem() != null && stack.getItem().getItemUseAction(stack) == ItemAction.EAT)
|
|
|
|
// {
|
|
|
|
// this.getServerWorld().sendToAllTrackingAndSelf(this, new SPacketAnimation(this, 3));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
public void onNewEffect(PotionEffect id)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S1DPacketEntityEffect(this.entity.getId(), id));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onChangedEffect(PotionEffect id, boolean added)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S1DPacketEntityEffect(this.entity.getId(), id));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onFinishedEffect(PotionEffect effect)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S1EPacketRemoveEntityEffect(this.entity.getId(), effect));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPositionAndUpdate(double x, double y, double z)
|
|
|
|
{
|
|
|
|
this.setPlayerLocation(x, y, z, this.entity.rotYaw, this.entity.rotPitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onCriticalHit(Entity entityHit)
|
|
|
|
{
|
|
|
|
this.entity.getServerWorld().sendToAllTrackingAndSelf(this.entity, new SPacketAnimation(entityHit, 4));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onEnchantmentCritical(Entity entityHit)
|
|
|
|
{
|
|
|
|
this.entity.getServerWorld().sendToAllTrackingAndSelf(this.entity, new SPacketAnimation(entityHit, 5));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateEffectMeta()
|
|
|
|
{
|
|
|
|
this.entity.getServerWorld().updateTrackedPlayer(this.entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void playSound(SoundEvent name, float volume, float pitch)
|
|
|
|
{
|
|
|
|
this.server.sendNearExcept(this.entity, this.entity.posX, this.entity.posY, this.entity.posZ, volume > 1.0F ? (double)(16.0F * volume) : 16.0D, this.entity.worldObj.dimension.getDimensionId(), new S29PacketSoundEffect(name, this.entity.posX, this.entity.posY, this.entity.posZ, volume, pitch));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void sendSlotContents(Container containerToSend, int slotInd, ItemStack stack)
|
|
|
|
{
|
|
|
|
if (!(containerToSend.getSlot(slotInd) instanceof SlotCrafting))
|
|
|
|
{
|
|
|
|
if (!this.isChangingQuantityOnly)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S2FPacketSetSlot(containerToSend.windowId, slotInd, stack));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendContainerToPlayer(Container container)
|
|
|
|
{
|
|
|
|
this.updateCraftingInventory(container, container.getInventory());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateCraftingInventory(Container containerToSend, List<ItemStack> itemsList)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S30PacketWindowItems(containerToSend.windowId, itemsList));
|
|
|
|
this.sendPacket(new S2FPacketSetSlot(-1, -1, this.entity.inventory.getItemStack()));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendProgressBarUpdate(Container containerIn, int varToUpdate, int newValue)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S31PacketWindowProperty(containerIn.windowId, varToUpdate, newValue));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendAllWindowProperties(Container p_175173_1_, IInventory p_175173_2_)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < p_175173_2_.getFieldCount(); ++i)
|
|
|
|
{
|
|
|
|
this.sendPacket(new S31PacketWindowProperty(p_175173_1_.windowId, i, p_175173_2_.getField(i)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void updateEntity()
|
|
|
|
{
|
|
|
|
if (this.entity.hurtResistance > 0)
|
|
|
|
{
|
|
|
|
--this.entity.hurtResistance;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.openContainer.detectAndSendChanges();
|
|
|
|
// if(!this.worldObj.client)
|
|
|
|
this.entity.inventoryContainer.detectAttributeChanges();
|
|
|
|
|
|
|
|
if (/* !this.worldObj.client && */ !this.entity.openContainer.canInteractWith(this.entity))
|
|
|
|
{
|
|
|
|
this.closeScreen();
|
|
|
|
this.entity.openContainer = this.entity.inventoryContainer;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (!this.destroyedItemsNetCache.isEmpty())
|
|
|
|
{
|
|
|
|
int i = Math.min(this.destroyedItemsNetCache.size(), Integer.MAX_VALUE);
|
|
|
|
int[] aint = new int[i];
|
|
|
|
Iterator<Integer> iterator = this.destroyedItemsNetCache.iterator();
|
|
|
|
int j = 0;
|
|
|
|
|
|
|
|
while (iterator.hasNext() && j < i)
|
|
|
|
{
|
|
|
|
aint[j++] = ((Integer)iterator.next()).intValue();
|
|
|
|
iterator.remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.sendPacket(new SPacketDestroyEntities(aint));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.loadedChunks.isEmpty())
|
|
|
|
{
|
|
|
|
List<Chunk> list = Lists.<Chunk>newArrayList();
|
|
|
|
Iterator<ChunkPos> iterator1 = this.loadedChunks.iterator();
|
|
|
|
List<TileEntity> list1 = Lists.<TileEntity>newArrayList();
|
|
|
|
|
|
|
|
int n = this.local ? 1024 : 10;
|
|
|
|
|
|
|
|
while (iterator1.hasNext() && ((List)list).size() < n)
|
|
|
|
{
|
|
|
|
ChunkPos chunkcoordintpair = (ChunkPos)iterator1.next();
|
|
|
|
|
|
|
|
if (chunkcoordintpair != null)
|
|
|
|
{
|
|
|
|
if (this.entity.worldObj.isBlockLoaded(new BlockPos(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4)))
|
|
|
|
{
|
|
|
|
Chunk chunk = this.entity.worldObj.getChunk(chunkcoordintpair.x, chunkcoordintpair.z);
|
|
|
|
|
|
|
|
if (chunk.isPopulated())
|
|
|
|
{
|
|
|
|
list.add(chunk);
|
|
|
|
list1.addAll(((WorldServer)this.entity.worldObj).getTileEntitiesIn(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, 512, chunkcoordintpair.z * 16 + 16));
|
|
|
|
iterator1.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
iterator1.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!list.isEmpty())
|
|
|
|
{
|
|
|
|
if (list.size() == 1)
|
|
|
|
{
|
|
|
|
this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, 0xffffffff));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.sendPacket(new SPacketMapChunkBulk(list));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (TileEntity tileentity : list1)
|
|
|
|
{
|
|
|
|
this.sendTileEntityUpdate(tileentity);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Chunk chunk1 : list)
|
|
|
|
{
|
|
|
|
this.entity.getServerWorld().updateChunksForPlayer(this.entity, chunk1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
++this.curblockDamage;
|
|
|
|
|
|
|
|
if (this.receivedFinishDiggingPacket)
|
|
|
|
{
|
|
|
|
int i = this.curblockDamage - this.initialBlockDamage;
|
|
|
|
Block block = this.entity.worldObj.getState(this.removingPos).getBlock();
|
|
|
|
|
|
|
|
if (block.getMaterial() == Material.air)
|
|
|
|
{
|
|
|
|
this.receivedFinishDiggingPacket = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float f = block.getPlayerRelativeBlockHardness(this.entity, this.entity.worldObj, this.removingPos) * (float)(i + 1);
|
|
|
|
int j = (int)(f * 10.0F);
|
|
|
|
|
|
|
|
if (j != this.durabilityRemainingOnBlock)
|
|
|
|
{
|
|
|
|
this.entity.worldObj.sendBlockBreakProgress(this.entity.getId(), this.removingPos, j);
|
|
|
|
this.durabilityRemainingOnBlock = j;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f >= 1.0F)
|
|
|
|
{
|
|
|
|
this.receivedFinishDiggingPacket = false;
|
|
|
|
this.tryHarvestBlock(this.removingPos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (this.isDestroyingBlock)
|
|
|
|
{
|
|
|
|
Block block1 = this.entity.worldObj.getState(this.startPos).getBlock();
|
|
|
|
|
|
|
|
if (block1.getMaterial() == Material.air)
|
|
|
|
{
|
|
|
|
this.entity.worldObj.sendBlockBreakProgress(this.entity.getId(), this.startPos, -1);
|
|
|
|
this.durabilityRemainingOnBlock = -1;
|
|
|
|
this.isDestroyingBlock = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int k = this.curblockDamage - this.initialDamage;
|
|
|
|
float f1 = block1.getPlayerRelativeBlockHardness(this.entity, this.entity.worldObj, this.removingPos) * (float)(k + 1);
|
|
|
|
int l = (int)(f1 * 10.0F);
|
|
|
|
|
|
|
|
if (l != this.durabilityRemainingOnBlock)
|
|
|
|
{
|
|
|
|
this.entity.worldObj.sendBlockBreakProgress(this.entity.getId(), this.startPos, l);
|
|
|
|
this.durabilityRemainingOnBlock = l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onBlockClicked(BlockPos pos, Facing side)
|
|
|
|
{
|
|
|
|
if(this.onPlayerInteract(true, pos)) {
|
|
|
|
this.sendPacket(new SPacketBlockChange(this.entity.worldObj, pos));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if (this.creative)
|
|
|
|
// {
|
|
|
|
// if (!this.worldObj.extinguishFire(null, pos, side))
|
|
|
|
// {
|
|
|
|
// this.tryHarvestBlock(pos);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
Block block = this.entity.worldObj.getState(pos).getBlock();
|
|
|
|
|
|
|
|
this.entity.worldObj.extinguishFire(null, pos, side);
|
|
|
|
this.initialDamage = this.curblockDamage;
|
|
|
|
float f = 1.0F;
|
|
|
|
|
|
|
|
if (block.getMaterial() != Material.air)
|
|
|
|
{
|
|
|
|
block.onBlockClicked(this.entity.worldObj, pos, this.entity);
|
|
|
|
f = block.getPlayerRelativeBlockHardness(this.entity, this.entity.worldObj, pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (block.getMaterial() != Material.air && f >= 1.0F)
|
|
|
|
{
|
|
|
|
this.tryHarvestBlock(pos);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.isDestroyingBlock = true;
|
|
|
|
this.startPos = pos;
|
|
|
|
int i = (int)(f * 10.0F);
|
|
|
|
this.entity.worldObj.sendBlockBreakProgress(this.entity.getId(), pos, i);
|
|
|
|
this.durabilityRemainingOnBlock = i;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
public void blockRemoving(BlockPos pos)
|
|
|
|
{
|
|
|
|
if (pos.equals(this.startPos))
|
|
|
|
{
|
|
|
|
int i = this.curblockDamage - this.initialDamage;
|
|
|
|
Block block = this.entity.worldObj.getState(pos).getBlock();
|
|
|
|
|
|
|
|
if (block.getMaterial() != Material.air)
|
|
|
|
{
|
|
|
|
float f = block.getPlayerRelativeBlockHardness(this.entity, this.entity.worldObj, pos) * (float)(i + 1);
|
|
|
|
|
|
|
|
if (f >= 0.7F)
|
|
|
|
{
|
|
|
|
this.isDestroyingBlock = false;
|
|
|
|
this.entity.worldObj.sendBlockBreakProgress(this.entity.getId(), pos, -1);
|
|
|
|
this.tryHarvestBlock(pos);
|
|
|
|
}
|
|
|
|
else if (!this.receivedFinishDiggingPacket)
|
|
|
|
{
|
|
|
|
this.isDestroyingBlock = false;
|
|
|
|
this.receivedFinishDiggingPacket = true;
|
|
|
|
this.removingPos = pos;
|
|
|
|
this.initialBlockDamage = this.initialDamage;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void cancelDestroyingBlock()
|
|
|
|
{
|
|
|
|
this.isDestroyingBlock = false;
|
|
|
|
this.entity.worldObj.sendBlockBreakProgress(this.entity.getId(), this.startPos, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean removeBlock(BlockPos pos)
|
|
|
|
{
|
|
|
|
State iblockstate = this.entity.worldObj.getState(pos);
|
|
|
|
iblockstate.getBlock().onBlockHarvested(this.entity.worldObj, pos, iblockstate, this.entity);
|
|
|
|
boolean flag = this.entity.worldObj.setBlockToAir(pos);
|
|
|
|
|
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
iblockstate.getBlock().onBlockDestroyedByPlayer(this.entity.worldObj, pos, iblockstate);
|
|
|
|
}
|
|
|
|
|
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean tryHarvestBlock(BlockPos pos)
|
|
|
|
{
|
|
|
|
// if (this.getHeldItem() != null && !this.getHeldItem().getItem().canBreakBlocks())
|
|
|
|
// {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
State iblockstate = this.entity.worldObj.getState(pos);
|
|
|
|
TileEntity tileentity = this.entity.worldObj.getTileEntity(pos);
|
|
|
|
|
|
|
|
this.entity.worldObj.playAuxSFX(this.entity, 2001, pos, BlockRegistry.getStateId(iblockstate));
|
|
|
|
boolean flag1 = this.removeBlock(pos);
|
|
|
|
|
|
|
|
// if (this.creative)
|
|
|
|
// {
|
|
|
|
// this.netHandler.sendPacket(new SPacketBlockChange(this.worldObj, pos));
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
ItemStack itemstack1 = this.entity.getCurrentEquippedItem();
|
|
|
|
boolean flag = this.entity.canHarvestBlock(iblockstate.getBlock());
|
|
|
|
|
|
|
|
if (itemstack1 != null)
|
|
|
|
{
|
|
|
|
itemstack1.onBlockDestroyed(this.entity.worldObj, iblockstate.getBlock(), pos, this.entity);
|
|
|
|
|
|
|
|
if (itemstack1.stackSize == 0)
|
|
|
|
{
|
|
|
|
this.entity.destroyCurrentEquippedItem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag1 && flag)
|
|
|
|
{
|
|
|
|
iblockstate.getBlock().harvestBlock(this.entity.worldObj, this.entity, pos, iblockstate, tileentity);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
return flag1;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean tryUseItem(ItemStack stack)
|
|
|
|
{
|
|
|
|
// if(this.onPlayerInteract(false, null)) {
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
int i = stack.stackSize;
|
|
|
|
int j = stack.getMetadata();
|
|
|
|
ItemStack itemstack = stack.useItemRightClick(this.entity.worldObj, this.entity);
|
|
|
|
|
|
|
|
if (itemstack != stack || itemstack != null && (itemstack.stackSize != i || itemstack.getMaxItemUseDuration() > 0 || itemstack.getMetadata() != j))
|
|
|
|
{
|
|
|
|
this.entity.inventory.mainInventory[this.entity.inventory.currentItem] = itemstack;
|
|
|
|
|
|
|
|
// if (this.creative)
|
|
|
|
// {
|
|
|
|
// itemstack.stackSize = i;
|
|
|
|
//
|
|
|
|
// if (itemstack.isItemStackDamageable())
|
|
|
|
// {
|
|
|
|
// itemstack.setItemDamage(j);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
if (itemstack.stackSize == 0)
|
|
|
|
{
|
|
|
|
this.entity.inventory.mainInventory[this.entity.inventory.currentItem] = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.entity.isUsingItem())
|
|
|
|
{
|
|
|
|
this.sendContainerToPlayer(this.entity.inventoryContainer);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean activateBlockOrUseItem(ItemStack stack, BlockPos pos, Facing side, float offsetX, float offsetY, float offsetZ)
|
|
|
|
{
|
|
|
|
if(this.onPlayerInteract(false, pos)) {
|
|
|
|
this.sendPacket(new SPacketBlockChange(this.entity.worldObj, pos));
|
|
|
|
stack.getItem().onItemUse(stack, this.entity, this.entity.worldObj, pos, side, offsetX, offsetY, offsetZ);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.entity.isSneaking() || this.entity.getHeldItem() == null) // && (stack == null || !stack.getItem().ignoresBlocks()))
|
|
|
|
{
|
|
|
|
State iblockstate = this.entity.worldObj.getState(pos);
|
|
|
|
|
|
|
|
if (iblockstate.getBlock().onBlockActivated(this.entity.worldObj, pos, iblockstate, this.entity, side, offsetX, offsetY, offsetZ))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stack == null)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// else if (this.creative)
|
|
|
|
// {
|
|
|
|
// int j = stack.getMetadata();
|
|
|
|
// int i = stack.stackSize;
|
|
|
|
// boolean flag = stack.onItemUse(this, this.worldObj, pos, side, offsetX, offsetY, offsetZ);
|
|
|
|
// stack.setItemDamage(j);
|
|
|
|
// stack.stackSize = i;
|
|
|
|
// return flag;
|
|
|
|
// }
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return stack.onItemUse(this.entity, this.entity.worldObj, pos, side, offsetX, offsetY, offsetZ);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void setSelection(boolean primary, BlockPos pos) {
|
|
|
|
switch(this.edit) {
|
|
|
|
case SELECT:
|
|
|
|
if(primary)
|
|
|
|
this.selectPos1(pos);
|
|
|
|
else
|
|
|
|
this.selectPos2(pos);
|
|
|
|
break;
|
|
|
|
case COPYPASTE:
|
|
|
|
if(primary)
|
|
|
|
this.pasteClipboard();
|
|
|
|
else
|
|
|
|
this.copyClipboard();
|
|
|
|
break;
|
|
|
|
case TRANSFORM:
|
|
|
|
if(primary)
|
|
|
|
this.rotateClipboard();
|
|
|
|
else
|
|
|
|
this.flipClipboard();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean onPlayerInteract(boolean primary, BlockPos pos) {
|
|
|
|
if(this.isAdmin() && this.entity.getCurrentEquippedItem() != null &&
|
|
|
|
this.entity.getCurrentEquippedItem().getItem().onAction(this.entity.getCurrentEquippedItem(), this.entity, this.entity.worldObj, primary ? ItemControl.PRIMARY : ItemControl.SECONDARY, pos))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void selectPos1(BlockPos pos) {
|
|
|
|
BlockPos point = pos == null ? this.entity.getPosition() : pos;
|
|
|
|
String msg = this.selectPoint(point, false);
|
|
|
|
if(msg != null)
|
|
|
|
this.addFeed(TextColor.DRED + msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void selectPos2(BlockPos pos) {
|
|
|
|
BlockPos point = pos == null ? this.entity.getPosition() : pos;
|
|
|
|
String msg = this.selectPoint(point, true);
|
|
|
|
if(msg != null)
|
|
|
|
this.addFeed(TextColor.MIDNIGHT + msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
private String selectPoint(BlockPos position, boolean second) {
|
|
|
|
if(this.selectionDim == Integer.MIN_VALUE || this.selectionDim != this.entity.worldObj.dimension.getDimensionId()) {
|
|
|
|
this.selectionDim = this.entity.worldObj.dimension.getDimensionId();
|
|
|
|
this.selPos1 = null;
|
|
|
|
this.selPos2 = null;
|
|
|
|
}
|
|
|
|
// this.setSelectionWorld();
|
|
|
|
BlockPos current = second ? this.selPos2 : this.selPos1;
|
|
|
|
if(current != null && (position.compareTo(current) == 0))
|
|
|
|
return null;
|
|
|
|
if(second)
|
|
|
|
this.selPos2 = current = position;
|
|
|
|
else
|
|
|
|
this.selPos1 = current = position;
|
|
|
|
if(this.selPos1 != null && this.selPos2 != null)
|
|
|
|
return (second ? "Zweite" : "Erste") + " Position auf " + current + " gesetzt (" + this.getSelectionArea() + ")";
|
|
|
|
else
|
|
|
|
return (second ? "Zweite" : "Erste") + " Position auf " + current + " gesetzt";
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setSelectMode() {
|
|
|
|
String msg = (this.edit = EditAction.values()[(this.edit.ordinal() + 1) % EditAction.values().length]).display;
|
|
|
|
if(this.edit == EditAction.COPYPASTE && this.clipboard != null) {
|
|
|
|
int nx = this.clipboard.length;
|
|
|
|
int ny = this.clipboard[0].length;
|
|
|
|
int nz = this.clipboard[0][0].length;
|
|
|
|
msg += String.format("; Zwischenablage: %dx%dx%d (%d)", nx, ny, nz, nx * ny * nz);
|
|
|
|
}
|
|
|
|
if(this.edit == EditAction.SELECT && this.selectionDim != Integer.MIN_VALUE && (this.selPos1 != null || this.selPos2 != null)) {
|
|
|
|
msg += "; Bereich Level " + this.selectionDim + ": ";
|
|
|
|
msg += (this.selPos1 != null ? this.selPos1 : "*") + " -> " + (this.selPos2 != null ? this.selPos2 : "*");
|
|
|
|
if(this.selPos1 != null && this.selPos2 != null) {
|
|
|
|
msg += " = " + (1 + Math.max(this.selPos1.getX(), this.selPos2.getX()) - Math.min(this.selPos1.getX(), this.selPos2.getX())) +
|
|
|
|
"x" + (1 + Math.max(this.selPos1.getY(), this.selPos2.getY()) - Math.min(this.selPos1.getY(), this.selPos2.getY())) +
|
|
|
|
"x" + (1 + Math.max(this.selPos1.getZ(), this.selPos2.getZ()) - Math.min(this.selPos1.getZ(), this.selPos2.getZ())) + " (" + this.getSelectionArea() + ")";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(this.edit == EditAction.TRANSFORM && (this.rotation != 0 || this.flipX || this.flipZ))
|
|
|
|
msg += "; " + this.getRotationInfo();
|
|
|
|
this.addFeed(TextColor.YELLOW + msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
private int getSelectionArea() {
|
|
|
|
if(this.selPos1 == null || this.selPos2 == null)
|
|
|
|
return 0;
|
|
|
|
return (1 + Math.max(this.selPos1.getX(), this.selPos2.getX()) - Math.min(this.selPos1.getX(), this.selPos2.getX())) *
|
|
|
|
(1 + Math.max(this.selPos1.getY(), this.selPos2.getY()) - Math.min(this.selPos1.getY(), this.selPos2.getY())) *
|
|
|
|
(1 + Math.max(this.selPos1.getZ(), this.selPos2.getZ()) - Math.min(this.selPos1.getZ(), this.selPos2.getZ()));
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean pasteClipboard() {
|
|
|
|
if(this.clipboard == null)
|
|
|
|
return false;
|
|
|
|
int nx = this.clipboard.length;
|
|
|
|
int ny = this.clipboard[0].length;
|
|
|
|
int nz = this.clipboard[0][0].length;
|
|
|
|
BlockPos to = this.entity.getPosition();
|
|
|
|
ClipboardPlacer placer = new ClipboardPlacer(this.entity.getServerWorld());
|
|
|
|
BlockTransform transform = null;
|
|
|
|
if(this.rotation != 0 || this.flipX || this.flipZ) {
|
|
|
|
transform = new BlockTransform();
|
|
|
|
if(this.rotation != 0)
|
|
|
|
transform = transform.rotateY(-this.rotation);
|
|
|
|
if(this.flipX || this.flipZ)
|
|
|
|
transform = transform.scale(new Vector(this.flipX ? -1.0 : 1.0, 1.0, this.flipZ ? -1.0 : 1.0));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
to = to.add(this.selOffset);
|
|
|
|
}
|
|
|
|
for(int x = 0; x < nx; x++) {
|
|
|
|
for(int y = 0; y < ny; y++) {
|
|
|
|
for(int z = 0; z < nz; z++) {
|
|
|
|
if(transform == null) {
|
|
|
|
placer.setBlock(to.add(x, y, z), this.clipboard[x][y][z]);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ClipboardBlock block = transformBlock(transform, this.clipboard[x][y][z]);
|
|
|
|
Vector tf = transform.apply(new Vector(x + this.selOffset.getX(), y + this.selOffset.getY(), z + this.selOffset.getZ()));
|
|
|
|
placer.setBlock(to.add(tf.getBlockX(), tf.getBlockY(), tf.getBlockZ()), block);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(transform != null) {
|
|
|
|
Vector tf = transform.apply(new Vector(this.selOffset.getX(), this.selOffset.getY(), this.selOffset.getZ()));
|
|
|
|
to = to.add(tf.getBlockX(), tf.getBlockY(), tf.getBlockZ());
|
|
|
|
}
|
|
|
|
placer.commit();
|
|
|
|
this.addFeed(TextColor.YELLOW + "Zwischenablage wurde bei %d, %d, %d eingefügt", to.getX(), to.getY(), to.getZ());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static ClipboardBlock transformBlock(BlockTransform transform, ClipboardBlock block) {
|
|
|
|
Rotation state = RotationRegistry.getRotation(block.getState().getBlock());
|
|
|
|
|
|
|
|
if (state == null) {
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
int meta = block.getState().getBlock().getMetaFromState(block.getState());
|
|
|
|
|
|
|
|
if (state.hasDirection(meta)) {
|
|
|
|
RotationValue value = state.getValue(meta);
|
|
|
|
if (value != null && value.getDirection() != null) {
|
|
|
|
RotationValue newValue = getNewRotation(transform, state, value.getDirection());
|
|
|
|
if (newValue != null) {
|
|
|
|
block.setState(block.getState().getBlock().getStateFromMeta(newValue.set(meta)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static RotationValue getNewRotation(BlockTransform transform, Rotation state, Vector oldDirection) {
|
|
|
|
Vector newDirection = transform.apply(oldDirection).subtract(transform.apply(Vector.ZERO)).normalize();
|
|
|
|
RotationValue newValue = null;
|
|
|
|
double closest = -2;
|
|
|
|
boolean found = false;
|
|
|
|
|
|
|
|
for (RotationValue v : state.getValues()) {
|
|
|
|
if (v.getDirection() != null) {
|
|
|
|
double dot = v.getDirection().normalize().dot(newDirection);
|
|
|
|
if (dot >= closest) {
|
|
|
|
closest = dot;
|
|
|
|
newValue = v;
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (found) {
|
|
|
|
return newValue;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean copyClipboard() {
|
|
|
|
if(this.selectionDim == Integer.MIN_VALUE || this.selectionDim != this.entity.worldObj.dimension.getDimensionId() ||
|
|
|
|
this.selPos1 == null || this.selPos2 == null)
|
|
|
|
return false;
|
|
|
|
WorldServer source = this.entity.getServerWorld();
|
|
|
|
int mx = Math.min(this.selPos1.getX(), this.selPos2.getX());
|
|
|
|
int my = Math.min(this.selPos1.getY(), this.selPos2.getY());
|
|
|
|
int mz = Math.min(this.selPos1.getZ(), this.selPos2.getZ());
|
|
|
|
int nx = Math.max(this.selPos1.getX(), this.selPos2.getX());
|
|
|
|
int ny = Math.max(this.selPos1.getY(), this.selPos2.getY());
|
|
|
|
int nz = Math.max(this.selPos1.getZ(), this.selPos2.getZ());
|
|
|
|
this.clipboard = new ClipboardBlock[1 + nx - mx][1 + ny - my][1 + nz - mz];
|
|
|
|
for(int x = mx; x <= nx; x++) {
|
|
|
|
for(int y = my; y <= ny; y++) {
|
|
|
|
for(int z = mz; z <= nz; z++) {
|
|
|
|
this.clipboard[x - mx][y - my][z - mz] = source.getBlock(new BlockPos(x, y, z));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.rotation = 0;
|
|
|
|
this.flipX = this.flipZ = false;
|
|
|
|
BlockPos pos = this.entity.getPosition();
|
|
|
|
this.selOffset = new Vec3i(mx - pos.getX(), my - pos.getY(), mz - pos.getZ());
|
|
|
|
this.addFeed(TextColor.YELLOW + "Auswahl wurde in die Zwischenablage kopiert");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getRotationInfo() {
|
|
|
|
return (this.rotation == 0 ? "" : ("Rotation " + this.rotation + "°")) +
|
|
|
|
(this.rotation == 0 || (!this.flipX && !this.flipZ) ? "" : ", ") +
|
|
|
|
(this.flipX && this.flipZ ? "X und Z gedreht" : (this.flipX ? "X gedreht" : (this.flipZ ? "Z gedreht" : "")));
|
|
|
|
}
|
|
|
|
|
|
|
|
private void flipClipboard() {
|
|
|
|
if(this.clipboard == null || this.entity.rotPitch > 67.5f || this.entity.rotPitch < -67.5f)
|
|
|
|
return;
|
|
|
|
float rot = this.entity.rotYaw % 360.0f;
|
|
|
|
if(rot < 0.0f)
|
|
|
|
rot += 360.0f;
|
|
|
|
if (0.0f <= rot && rot < 22.5f)
|
|
|
|
this.flipZ ^= true;
|
|
|
|
else if (67.5f <= rot && rot < 112.5)
|
|
|
|
this.flipX ^= true;
|
|
|
|
else if (157.5f <= rot && rot < 202.5f)
|
|
|
|
this.flipZ ^= true;
|
|
|
|
else if (247.5f <= rot && rot < 292.5f)
|
|
|
|
this.flipX ^= true;
|
|
|
|
else if (337.5f <= rot && rot < 360.0f)
|
|
|
|
this.flipZ ^= true;
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
String info = this.getRotationInfo();
|
|
|
|
this.addFeed(TextColor.YELLOW + (info.isEmpty() ? "Keine Drehung" : info));
|
|
|
|
}
|
|
|
|
|
|
|
|
private void rotateClipboard() {
|
|
|
|
if(this.clipboard == null)
|
|
|
|
return;
|
|
|
|
this.rotation = (this.rotation + 90) % 360;
|
|
|
|
String info = this.getRotationInfo();
|
|
|
|
this.addFeed(TextColor.YELLOW + (info.isEmpty() ? "Keine Drehung" : info));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public List<NBTTagCompound> getCharacters() {
|
|
|
|
return this.characters;
|
|
|
|
}
|
|
|
|
|
|
|
|
public NBTTagCompound getSelectedCharacter(boolean create) {
|
|
|
|
NBTTagCompound tag = this.characters.isEmpty() || this.selected < 0 ? null : this.characters.get(this.selected);
|
|
|
|
if(create && tag == null) {
|
|
|
|
tag = new NBTTagCompound();
|
|
|
|
this.selected = this.characters.size();
|
|
|
|
this.characters.add(tag);
|
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
else if(create) {
|
|
|
|
tag.getKeySet().clear();
|
|
|
|
}
|
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void selectCharacter(int index) {
|
|
|
|
if(index == this.selected || index >= this.characters.size())
|
|
|
|
return;
|
|
|
|
this.server.swapPlayer(this, index < 0 ? null : this.characters.get(index));
|
|
|
|
this.selected = index;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void disconnect()
|
|
|
|
{
|
|
|
|
this.connection.sendPacket(new SPacketDisconnect(), new GenericFutureListener < Future <? super Void >> ()
|
|
|
|
{
|
|
|
|
public void operationComplete(Future <? super Void > p_operationComplete_1_) throws Exception
|
|
|
|
{
|
|
|
|
NetHandlerPlayServer.this.connection.closeChannel("Getrennt");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.connection.disableAutoRead();
|
|
|
|
Futures.getUnchecked(this.server.schedule(new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
NetHandlerPlayServer.this.connection.checkDisconnected();
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onDisconnect(String reason)
|
|
|
|
{
|
|
|
|
Log.JNI.info(this.user + " wurde getrennt: " + TextColor.stripCodes(reason));
|
|
|
|
if(!this.local)
|
|
|
|
this.server.sendPacket(new SPacketMessage(String.format("%s hat das Spiel verlassen", this.user)));
|
|
|
|
this.server.removePlayer(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onConnect() {
|
|
|
|
if(!this.local)
|
|
|
|
this.server.sendPacket(new SPacketMessage(String.format("%s hat das Spiel betreten", this.user)));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendPacket(final Packet packet)
|
|
|
|
{
|
|
|
|
this.connection.sendPacket(packet);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPlayerLocation(double x, double y, double z, float yaw, float pitch)
|
|
|
|
{
|
|
|
|
this.setPlayerLocation(x, y, z, yaw, pitch, Collections.<SPacketPlayerPosLook.EnumFlags>emptySet());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPlayerLocation(double x, double y, double z, float yaw, float pitch, Set<SPacketPlayerPosLook.EnumFlags> flags)
|
|
|
|
{
|
|
|
|
this.hasMoved = false;
|
|
|
|
this.lastPosX = x;
|
|
|
|
this.lastPosY = y;
|
|
|
|
this.lastPosZ = z;
|
|
|
|
if (flags.contains(SPacketPlayerPosLook.EnumFlags.X))
|
|
|
|
{
|
|
|
|
this.lastPosX += this.entity.posX;
|
|
|
|
double nx = ExtMath.clampd(this.lastPosX, -World.MAX_SIZE + 1, World.MAX_SIZE - 1);
|
|
|
|
if(nx != this.lastPosX) {
|
|
|
|
x = (x < 0.0 ? (double)(-World.MAX_SIZE + 1) : (double)(World.MAX_SIZE - 1)) - this.entity.posX;
|
|
|
|
this.lastPosX = x + this.entity.posX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (flags.contains(SPacketPlayerPosLook.EnumFlags.Y))
|
|
|
|
{
|
|
|
|
this.lastPosY += this.entity.posY;
|
|
|
|
}
|
|
|
|
if (flags.contains(SPacketPlayerPosLook.EnumFlags.Z))
|
|
|
|
{
|
|
|
|
this.lastPosZ += this.entity.posZ;
|
|
|
|
double nz = ExtMath.clampd(this.lastPosZ, -World.MAX_SIZE + 1, World.MAX_SIZE - 1);
|
|
|
|
if(nz != this.lastPosZ) {
|
|
|
|
z = (z < 0.0 ? (double)(-World.MAX_SIZE + 1) : (double)(World.MAX_SIZE - 1)) - this.entity.posZ;
|
|
|
|
this.lastPosZ = z + this.entity.posZ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
float nyaw = yaw;
|
|
|
|
float npitch = pitch;
|
|
|
|
if (flags.contains(SPacketPlayerPosLook.EnumFlags.Y_ROT))
|
|
|
|
{
|
|
|
|
nyaw = yaw + this.entity.rotYaw;
|
|
|
|
}
|
|
|
|
if (flags.contains(SPacketPlayerPosLook.EnumFlags.X_ROT))
|
|
|
|
{
|
|
|
|
npitch = pitch + this.entity.rotPitch;
|
|
|
|
}
|
|
|
|
this.entity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, nyaw, npitch);
|
|
|
|
this.entity.connection.sendPacket(new SPacketPlayerPosLook(x, y, z, yaw, pitch, flags));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processKeepAlive(CPacketKeepAlive packetIn)
|
|
|
|
{
|
|
|
|
if (packetIn.getValue() == this.pingKey)
|
|
|
|
{
|
|
|
|
int i = (int)((System.nanoTime() / 1000000L) - this.lastPingTime);
|
|
|
|
this.ping = (this.ping * 3 + i) / 4;
|
|
|
|
this.ping = Math.max(this.ping, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// private boolean runScript(String line) {
|
|
|
|
// if(!this.isAdmin() || !line.startsWith("+") || line.length() < 2)
|
|
|
|
// return false;
|
|
|
|
// line = line.substring(1).trim();
|
|
|
|
// PythonInterpreter py = new PythonInterpreter();
|
|
|
|
// py.set("handler", this);
|
|
|
|
// py.set("entity", this.entity);
|
|
|
|
// py.set("server", this.server);
|
|
|
|
// py.set("user", this.user);
|
|
|
|
// py.execfile(NetHandlerPlayServer.class.getResourceAsStream("/scripts/" + line + ".py"), line + ".py");
|
|
|
|
// py.close();
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
|
|
|
|
private boolean sendPlayer(String line) {
|
|
|
|
if(!line.startsWith("@") || line.length() < 2)
|
|
|
|
return false;
|
|
|
|
int space = line.indexOf(' ');
|
|
|
|
// if(space < 0)
|
|
|
|
// return false;
|
|
|
|
NetHandlerPlayServer target = this.server.getPlayer(space < 0 ? line.substring(1) : line.substring(1, space));
|
|
|
|
if(target == null)
|
|
|
|
return false;
|
|
|
|
target.addFeed(this.entity.getColoredName(TextColor.LGRAY) + " -> " + target.entity.getColoredName(TextColor.LGRAY) + " " +
|
|
|
|
line);
|
|
|
|
if(target != this)
|
|
|
|
this.addFeed(target.entity.getColoredName(TextColor.LGRAY) + " -> " + this.entity.getColoredName(TextColor.LGRAY) + " " +
|
|
|
|
line);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean setVar(String line) {
|
|
|
|
if(!this.isAdmin() || !line.startsWith("#"))
|
|
|
|
return false;
|
|
|
|
if(line.length() < 2) {
|
|
|
|
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.addFeed(comp);
|
|
|
|
}
|
|
|
|
this.addFeed(TextColor.YELLOW + "time" + TextColor.GRAY + " = " + TextColor.ORANGE + ItemSpaceNavigator.formatImperialTime(this.entity.getServerWorld(), false));
|
|
|
|
this.addFeed(TextColor.GREEN + "SVARs insgesamt registriert: %d", Config.VARS.size());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
line = line.substring(1).trim();
|
|
|
|
String[] args = /* line.isEmpty() ? new String[0] : */ line.split(" ", -1);
|
|
|
|
if(args.length == 1) {
|
|
|
|
// case 0:
|
|
|
|
// break;
|
|
|
|
// case 1:
|
|
|
|
if(args[0].equals("time")) {
|
|
|
|
this.addFeed(TextColor.YELLOW + "time" + TextColor.GRAY + " = " + TextColor.ORANGE + ItemSpaceNavigator.formatImperialTime(this.entity.getServerWorld(), false));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
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.addFeed(comp);
|
|
|
|
// break;
|
|
|
|
// default:
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(args[0].equals("time")) {
|
|
|
|
long time = this.entity.getServerWorld().getDayTime();
|
|
|
|
Long fwd = parseDayTime(args[1]);
|
|
|
|
if(fwd == null)
|
|
|
|
return true;
|
|
|
|
if(fwd >= 0L) {
|
|
|
|
time -= this.entity.getServerWorld().getDayTime() % this.entity.getServerWorld().dimension.getRotationalPeriod();
|
|
|
|
time += fwd;
|
|
|
|
time += time <= this.entity.getServerWorld().getDayTime() ? this.entity.getServerWorld().dimension.getRotationalPeriod() : 0L;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Long add = parseTime(args[1]);
|
|
|
|
if(add == null)
|
|
|
|
return true;
|
|
|
|
time += add;
|
|
|
|
}
|
|
|
|
for(WorldServer dim : this.server.getWorlds()) {
|
|
|
|
dim.setDayTime(time);
|
|
|
|
dim.resetWeather();
|
|
|
|
}
|
|
|
|
this.addFeed(TextColor.YELLOW + "time" + TextColor.GRAY + " -> " + TextColor.ORANGE + "%s", ItemSpaceNavigator.formatImperialTime(this.entity.getServerWorld(), false));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
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.addFeed(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.addFeed(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.addFeed(TextColor.DRED + "'%s' ist keine gültige Zahl", value);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Config.set(args[0], value, this.server);
|
|
|
|
this.addFeed(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;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean setAdmin(String line) {
|
|
|
|
if(!this.isAdmin() || !line.startsWith("!") || line.indexOf(' ') >= 0)
|
|
|
|
return false;
|
|
|
|
line = line.substring(1).trim();
|
|
|
|
NetHandlerPlayServer conn = this.server.getPlayer(line);
|
|
|
|
if(conn == null)
|
|
|
|
return false;
|
|
|
|
if(conn.isAdmin() && (conn == this || !this.local)) {
|
|
|
|
this.addFeed(TextColor.DRED + "Kann diese Aktion nicht an einem Admin ausführen");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
conn.setAdmin(!conn.getAdmin());
|
|
|
|
EntityNPC player = conn.getEntity();
|
|
|
|
if(!conn.isAdmin() && player.noclip) {
|
|
|
|
// player.setCheat(false);
|
|
|
|
player.noclip = false;
|
|
|
|
player.flying &= player.hasEffect(Potion.flying);
|
|
|
|
player.fallDistance = 0.0F;
|
|
|
|
conn.sendPlayerAbilities();
|
|
|
|
conn.addFeed(TextColor.RED + "NoClip wurde deaktiviert");
|
|
|
|
}
|
|
|
|
this.addFeed((conn.getAdmin() ? TextColor.GREEN : TextColor.RED) + "Admin-Status von " + conn.getUser() + " wurde " +
|
|
|
|
(conn.getAdmin() ? "gesetzt" : "zurückgenommen"));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Long parseInt(String input, long max) {
|
|
|
|
long num;
|
|
|
|
try {
|
|
|
|
num = Long.parseLong(input);
|
|
|
|
}
|
|
|
|
catch(NumberFormatException e) {
|
|
|
|
this.addFeed(TextColor.DRED + "'%s' ist keine gültige Zahl", input);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(num < 0) {
|
|
|
|
this.addFeed(TextColor.DRED + "Die Zeit muss mindestens 0 betragen", num);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
else if(num > max) {
|
|
|
|
this.addFeed(TextColor.DRED + "Die Zeit darf höchstens %d betragen", num, max);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private Long parseDayTime(String arg) {
|
|
|
|
Dimension dim = this.entity.getServerWorld().dimension;
|
|
|
|
if(arg.equalsIgnoreCase("sunrise"))
|
|
|
|
return dim.getRotationalPeriod() / 6L;
|
|
|
|
else if(arg.equalsIgnoreCase("day"))
|
|
|
|
return dim.getRotationalPeriod() * 5L / 24L;
|
|
|
|
else if(arg.equalsIgnoreCase("noon"))
|
|
|
|
return dim.getRotationalPeriod() / 2L;
|
|
|
|
else if(arg.equalsIgnoreCase("sunset"))
|
|
|
|
return dim.getRotationalPeriod() * 5L / 6L;
|
|
|
|
else if(arg.equalsIgnoreCase("night"))
|
|
|
|
return dim.getRotationalPeriod() * 21L / 24L;
|
|
|
|
else if(arg.equalsIgnoreCase("midnight"))
|
|
|
|
return 0L;
|
|
|
|
else if(arg.startsWith("@"))
|
|
|
|
return this.parseInt(arg.substring(1), dim.getRotationalPeriod() - 1);
|
|
|
|
else
|
|
|
|
return -1L;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Long parseTime(String arg) {
|
|
|
|
Dimension dim = this.entity.getServerWorld().dimension;
|
|
|
|
long t;
|
|
|
|
if(arg.toLowerCase().endsWith("y"))
|
|
|
|
t = dim.getOrbitalPeriod();
|
|
|
|
else if(arg.toLowerCase().endsWith("d"))
|
|
|
|
t = dim.getRotationalPeriod();
|
|
|
|
else if(arg.toLowerCase().endsWith("h"))
|
|
|
|
t = 1000L;
|
|
|
|
else
|
|
|
|
t = -1L;
|
|
|
|
arg = t == -1L ? arg : arg.substring(0, arg.length() - 1);
|
|
|
|
t = t < 1L ? 1L : t;
|
|
|
|
Long l = this.parseInt(arg, Long.MAX_VALUE);
|
|
|
|
return l == null ? null : (t * l);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Double parseCoordinate(String str, boolean center) {
|
|
|
|
try {
|
|
|
|
return (double)Integer.parseInt(str) + (center ? 0.5 : 0.0);
|
|
|
|
}
|
|
|
|
catch(NumberFormatException e) {
|
|
|
|
this.addFeed(TextColor.DRED + "'%s' ist keine gültige Zahl", str);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean teleport(String line) {
|
|
|
|
if((!Config.teleportAllowed && !this.isAdmin()) || !line.startsWith("/"))
|
|
|
|
return false;
|
|
|
|
line = line.substring(1).trim();
|
|
|
|
String[] argv = line.split(" ", -1);
|
|
|
|
if(line.isEmpty() || argv.length == 0 || argv.length == 2) {
|
|
|
|
this.addFeed(TextColor.DRED + "Spieler, @Warp, *Dimension oder X Y Z [Dimension]");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(argv.length != 1) {
|
|
|
|
Double ax = parseCoordinate(argv[0], true);
|
|
|
|
if(ax == null)
|
|
|
|
return true;
|
|
|
|
Double ay = parseCoordinate(argv[1], false);
|
|
|
|
if(ay == null)
|
|
|
|
return true;
|
|
|
|
Double az = parseCoordinate(argv[2], true);
|
|
|
|
if(az == null)
|
|
|
|
return true;
|
|
|
|
int dimension = this.entity.worldObj.dimension.getDimensionId();
|
|
|
|
if(argv.length > 3) {
|
|
|
|
WorldServer world;
|
|
|
|
try {
|
|
|
|
world = this.server.getWorld(Integer.parseInt(argv[3]));
|
|
|
|
}
|
|
|
|
catch(NumberFormatException e) {
|
|
|
|
world = this.server.getWorld(argv[3]);
|
|
|
|
}
|
|
|
|
if(world == null) {
|
|
|
|
this.addFeed(TextColor.DRED + "Dimension '%s' existiert nicht", argv[3]);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
dimension = world.dimension.getDimensionId();
|
|
|
|
}
|
|
|
|
this.entity.teleport(ax, ay, az, this.entity.rotYaw, this.entity.rotPitch, dimension);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
String tgt = argv[0];
|
|
|
|
if(tgt.startsWith("@")) {
|
|
|
|
tgt = tgt.substring(1);
|
|
|
|
if(tgt.equals("spawn")) {
|
|
|
|
WorldServer world = this.server.getWorld(Config.spawnDim);
|
|
|
|
world = world == null ? this.server.getSpace() : world;
|
|
|
|
int y = Config.spawnY;
|
|
|
|
while(world.getState(new BlockPos(Config.spawnX, y, Config.spawnZ)).getBlock().getMaterial().blocksMovement() && y < 511)
|
|
|
|
y++;
|
|
|
|
this.entity.teleport(Config.spawnX + 0.5d, (double)y, Config.spawnZ + 0.5d,
|
|
|
|
Config.spawnYaw, Config.spawnPitch, world.dimension.getDimensionId());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Position pos = this.server.getWarps().get(tgt);
|
|
|
|
if(pos == null) {
|
|
|
|
this.addFeed(TextColor.DRED + "Warp '%s' existiert nicht", tgt);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(this.server.getWorld(pos.dim) == null) {
|
|
|
|
this.addFeed(TextColor.DRED + "Warp '%s' hat kein Level (%s)", tgt, pos.dim);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
this.entity.teleport(pos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(tgt.startsWith("*")) {
|
|
|
|
tgt = tgt.substring(1);
|
|
|
|
WorldServer world;
|
|
|
|
try {
|
|
|
|
world = this.server.getWorld(Integer.parseInt(tgt));
|
|
|
|
}
|
|
|
|
catch(NumberFormatException e) {
|
|
|
|
world = this.server.getWorld(tgt);
|
|
|
|
}
|
|
|
|
if(world == null) {
|
|
|
|
this.addFeed(TextColor.DRED + "Dimension '%s' existiert nicht", tgt);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// int dimension = world.dimension.getDimensionId();
|
|
|
|
// int dimension = parseDimension(sender, tgt);
|
|
|
|
BlockPos pos = this.entity.getPosition();
|
|
|
|
// WorldServer world = Server.getServer().getWorld(dimension);
|
|
|
|
pos = pos.getY() < 0 ? new BlockPos(pos.getX(), 0, pos.getZ()) : pos;
|
|
|
|
if(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) {
|
|
|
|
while((world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() < 511)
|
|
|
|
pos = pos.up();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
while(!(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() > 0)
|
|
|
|
pos = pos.down();
|
|
|
|
pos = pos.up();
|
|
|
|
}
|
|
|
|
this.entity.teleport(pos, world.dimension.getDimensionId());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NetHandlerPlayServer conn = this.server.getPlayer(tgt);
|
|
|
|
if(conn == null) {
|
|
|
|
Position pos = this.server.getOfflinePosition(tgt);
|
|
|
|
if(pos == null) {
|
|
|
|
this.addFeed(TextColor.DRED + "Spieler '%s' konnte nicht gefunden werden", tgt);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
this.entity.teleport(pos);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
EntityNPC dest = conn.getEntity();
|
|
|
|
if(dest != null)
|
|
|
|
this.entity.teleport(dest.posX, dest.posY, dest.posZ, dest.rotYaw, dest.rotPitch, dest.worldObj.dimension.getDimensionId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processMessage(CPacketMessage packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
|
|
|
|
String msg = packetIn.getMessage();
|
|
|
|
for(int z = 0; z < msg.length(); z++) {
|
|
|
|
char c = msg.charAt(z);
|
|
|
|
if(c < 32 || c == 127)
|
|
|
|
throw new IllegalArgumentException("Ungültige Zeichen in Nachricht");
|
|
|
|
}
|
|
|
|
switch(packetIn.getType()) {
|
|
|
|
case CHAT:
|
|
|
|
if(!this.teleport(msg) && !this.sendPlayer(msg) && !this.setVar(msg) && !this.setAdmin(msg))
|
|
|
|
this.server.sendPacket(new SPacketMessage(String.format("%s %s", this.entity.getColoredName(TextColor.LGRAY), msg)));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DISPLAY:
|
|
|
|
if(msg.isEmpty() || !isValidNick(msg) || msg.length() > MAX_NICK_LENGTH)
|
|
|
|
throw new IllegalArgumentException("Ungültiger Anzeigename");
|
|
|
|
this.entity.setCustomNameTag(msg);
|
|
|
|
break;
|
|
|
|
|
|
|
|
// case ITEM:
|
|
|
|
// if(this.entity.openContainer instanceof ContainerRepair)
|
|
|
|
// ((ContainerRepair)this.entity.openContainer).updateItemName(msg);
|
|
|
|
// break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw new IllegalArgumentException("Ungültiger Nachrichten-Typ!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean isFinite(double value) {
|
|
|
|
return Double.NEGATIVE_INFINITY < value & value < Double.POSITIVE_INFINITY;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean isFinite(float value) {
|
|
|
|
return Float.NEGATIVE_INFINITY < value & value < Float.POSITIVE_INFINITY;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processPlayer(CPacketPlayer packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
|
|
|
|
if (!isFinite(packetIn.getPositionX()) || !isFinite(packetIn.getPositionY()) || !isFinite(packetIn.getPositionZ()) || !isFinite(packetIn.getPitch()) || !isFinite(packetIn.getYaw()))
|
|
|
|
{
|
|
|
|
throw new IllegalArgumentException("Ungültige Bewegung");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension);
|
|
|
|
// this.updated = true;
|
|
|
|
|
|
|
|
double d0 = this.entity.posX;
|
|
|
|
double d1 = this.entity.posY;
|
|
|
|
double d2 = this.entity.posZ;
|
|
|
|
double d3 = 0.0D;
|
|
|
|
double d4 = packetIn.getPositionX() - this.lastPosX;
|
|
|
|
double d5 = packetIn.getPositionY() - this.lastPosY;
|
|
|
|
double d6 = packetIn.getPositionZ() - this.lastPosZ;
|
|
|
|
|
|
|
|
if (packetIn.isMoving())
|
|
|
|
{
|
|
|
|
d3 = d4 * d4 + d5 * d5 + d6 * d6;
|
|
|
|
|
|
|
|
if (!this.hasMoved && d3 < 0.25D)
|
|
|
|
{
|
|
|
|
this.hasMoved = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.hasMoved)
|
|
|
|
{
|
|
|
|
this.lastMoved = this.tickTime;
|
|
|
|
|
|
|
|
if (this.entity.vehicle != null)
|
|
|
|
{
|
|
|
|
float f4 = this.entity.rotYaw;
|
|
|
|
float f = this.entity.rotPitch;
|
|
|
|
this.entity.vehicle.updateRiderPosition();
|
|
|
|
double d16 = this.entity.posX;
|
|
|
|
double d17 = this.entity.posY;
|
|
|
|
double d18 = this.entity.posZ;
|
|
|
|
|
|
|
|
if (packetIn.getRotating())
|
|
|
|
{
|
|
|
|
f4 = packetIn.getYaw();
|
|
|
|
f = packetIn.getPitch();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.onGround = packetIn.isOnGround();
|
|
|
|
this.entity.onUpdateEntity();
|
|
|
|
this.updateSync();
|
|
|
|
this.entity.setPositionAndRotation(d16, d17, d18, f4, f);
|
|
|
|
|
|
|
|
if (this.entity.vehicle != null)
|
|
|
|
{
|
|
|
|
this.entity.vehicle.updateRiderPosition();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.getServerWorld().updateMountedMovingPlayer(this.entity);
|
|
|
|
|
|
|
|
if (this.entity.vehicle != null)
|
|
|
|
{
|
|
|
|
if (d3 > 4.0D)
|
|
|
|
{
|
|
|
|
Entity entity = this.entity.vehicle;
|
|
|
|
this.entity.connection.sendPacket(new S18PacketEntityTeleport(entity));
|
|
|
|
this.setPlayerLocation(this.entity.posX, this.entity.posY, this.entity.posZ, this.entity.rotYaw, this.entity.rotPitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.vehicle.isAirBorne = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.hasMoved)
|
|
|
|
{
|
|
|
|
this.lastPosX = this.entity.posX;
|
|
|
|
this.lastPosY = this.entity.posY;
|
|
|
|
this.lastPosZ = this.entity.posZ;
|
|
|
|
}
|
|
|
|
|
|
|
|
worldserver.updateEntity(this.entity, true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if (this.playerEntity.isPlayerSleeping())
|
|
|
|
// {
|
|
|
|
// this.playerEntity.onUpdateEntity();
|
|
|
|
// this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotYaw, this.playerEntity.rotPitch);
|
|
|
|
// worldserver.updateEntity(this.playerEntity, true);
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
double d7 = this.entity.posY;
|
|
|
|
this.lastPosX = this.entity.posX;
|
|
|
|
this.lastPosY = this.entity.posY;
|
|
|
|
this.lastPosZ = this.entity.posZ;
|
|
|
|
double d8 = this.entity.posX;
|
|
|
|
double d9 = this.entity.posY;
|
|
|
|
double d10 = this.entity.posZ;
|
|
|
|
float f1 = this.entity.rotYaw;
|
|
|
|
float f2 = this.entity.rotPitch;
|
|
|
|
|
|
|
|
if (packetIn.isMoving() && packetIn.getPositionY() == -999.0D)
|
|
|
|
{
|
|
|
|
packetIn.setMoving(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (packetIn.isMoving())
|
|
|
|
{
|
|
|
|
d8 = packetIn.getPositionX();
|
|
|
|
d9 = packetIn.getPositionY();
|
|
|
|
d10 = packetIn.getPositionZ();
|
|
|
|
|
|
|
|
if (Math.abs(packetIn.getPositionX()) > World.MAX_SIZE || Math.abs(packetIn.getPositionZ()) > World.MAX_SIZE)
|
|
|
|
{
|
|
|
|
throw new IllegalArgumentException("Ungültige Position");
|
|
|
|
// return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (packetIn.getRotating())
|
|
|
|
{
|
|
|
|
f1 = packetIn.getYaw();
|
|
|
|
f2 = packetIn.getPitch();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.onUpdateEntity();
|
|
|
|
this.updateSync();
|
|
|
|
this.entity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, f1, f2);
|
|
|
|
|
|
|
|
if (!this.hasMoved)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
double d11 = d8 - this.entity.posX;
|
|
|
|
double d12 = d9 - this.entity.posY;
|
|
|
|
double d13 = d10 - this.entity.posZ;
|
|
|
|
double d14 = this.entity.motionX * this.entity.motionX + this.entity.motionY * this.entity.motionY + this.entity.motionZ * this.entity.motionZ;
|
|
|
|
double d15 = d11 * d11 + d12 * d12 + d13 * d13;
|
|
|
|
|
|
|
|
// if (d15 - d14 > 100.0D && (!this.playerEntity.canUse(Permissions.NOMOVECHECK)))
|
|
|
|
// {
|
|
|
|
// Log.warn(this.user + " bewegte sich zu schnell! " + d11 + "," + d12 + "," + d13 + " (" + d11 + ", " + d12 + ", " + d13 + ")");
|
|
|
|
// this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotYaw, this.playerEntity.rotPitch);
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
float f3 = 0.0625F;
|
|
|
|
boolean flag = worldserver.getCollidingBoundingBoxes(this.entity, this.entity.getEntityBoundingBox().contract((double)f3, (double)f3, (double)f3)).isEmpty();
|
|
|
|
|
|
|
|
if (this.entity.onGround && !packetIn.isOnGround() && d12 > 0.0D)
|
|
|
|
{
|
|
|
|
this.entity.jump();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.moveEntity(d11, d12, d13);
|
|
|
|
this.entity.onGround = packetIn.isOnGround();
|
|
|
|
d11 = d8 - this.entity.posX;
|
|
|
|
d12 = d9 - this.entity.posY;
|
|
|
|
|
|
|
|
if (d12 > -0.5D || d12 < 0.5D)
|
|
|
|
{
|
|
|
|
d12 = 0.0D;
|
|
|
|
}
|
|
|
|
|
|
|
|
d13 = d10 - this.entity.posZ;
|
|
|
|
d15 = d11 * d11 + d12 * d12 + d13 * d13;
|
|
|
|
boolean flag1 = false;
|
|
|
|
|
|
|
|
if (d15 > 0.0625D) // && /* !this.playerEntity.isPlayerSleeping() && */ !this.playerEntity.creative)
|
|
|
|
{
|
|
|
|
flag1 = true;
|
|
|
|
// Log.warn(this.user + " bewegte sich falsch!");
|
|
|
|
}
|
|
|
|
|
|
|
|
this.entity.setPositionAndRotation(d8, d9, d10, f1, f2);
|
|
|
|
this.entity.addMovementStat(this.entity.posX - d0, this.entity.posY - d1, this.entity.posZ - d2);
|
|
|
|
|
|
|
|
if (!this.entity.noClip)
|
|
|
|
{
|
|
|
|
boolean flag2 = worldserver.getCollidingBoundingBoxes(this.entity, this.entity.getEntityBoundingBox().contract((double)f3, (double)f3, (double)f3)).isEmpty();
|
|
|
|
|
|
|
|
if (flag && (flag1 || !flag2)) // && !this.playerEntity.isPlayerSleeping())
|
|
|
|
{
|
|
|
|
this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, f1, f2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// AxisAlignedBB axisalignedbb = this.playerEntity.getEntityBoundingBox().expand((double)f3, (double)f3, (double)f3).addCoord(0.0D, -0.55D, 0.0D);
|
|
|
|
|
|
|
|
// if (!Config.flight && !this.playerEntity.capabilities.allowFlying && worldserver.gravity > 0.0 && !worldserver.checkBlockCollision(axisalignedbb) && !this.netManager.isLocalChannel())
|
|
|
|
// {
|
|
|
|
// if (d12 >= -0.03125D)
|
|
|
|
// {
|
|
|
|
// ++this.floatingTickCount;
|
|
|
|
//
|
|
|
|
// if (this.floatingTickCount > Math.min(80, (int)(80.0 * (2.0 - worldserver.gravity))))
|
|
|
|
// {
|
|
|
|
// Log.warn(this.user + " wurde wegen zu langem Aufenthalt in der Luft getrennt!");
|
|
|
|
// this.kick("Fliegen ist auf diesem Server nicht erlaubt");
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// this.floatingTickCount = 0;
|
|
|
|
// }
|
|
|
|
|
|
|
|
this.entity.onGround = packetIn.isOnGround();
|
|
|
|
this.entity.getServerWorld().updateMountedMovingPlayer(this.entity);
|
|
|
|
this.handleFalling(this.entity.posY - d7, packetIn.isOnGround());
|
|
|
|
}
|
|
|
|
else if (this.tickTime - this.lastMoved > 20)
|
|
|
|
{
|
|
|
|
this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, this.entity.rotYaw, this.entity.rotPitch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateSync() {
|
|
|
|
if (this.entity.getHealth() != this.lastHealth)
|
|
|
|
{
|
|
|
|
this.sendPacket(new SPacketUpdateHealth(this.entity.getHealth()));
|
|
|
|
this.lastHealth = this.entity.getHealth();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.entity.getHealth() + this.entity.getAbsorptionAmount() != this.combinedHealth)
|
|
|
|
{
|
|
|
|
this.combinedHealth = this.entity.getHealth() + this.entity.getAbsorptionAmount();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.entity.experienceTotal != this.lastExperience)
|
|
|
|
{
|
|
|
|
this.lastExperience = this.entity.experienceTotal;
|
|
|
|
this.sendPacket(new SPacketSetExperience(this.entity.experience, this.entity.experienceTotal, this.entity.experienceLevel));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processBreak(CPacketBreak packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension);
|
|
|
|
BlockPos blockpos = packetIn.getPosition();
|
|
|
|
|
|
|
|
switch (packetIn.getStatus())
|
|
|
|
{
|
|
|
|
case DROP_ITEM:
|
|
|
|
// if (!this.playerEntity.isSpectator())
|
|
|
|
// {
|
|
|
|
this.entity.dropOneItem(false);
|
|
|
|
// }
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
case DROP_ALL_ITEMS:
|
|
|
|
// if (!this.playerEntity.isSpectator())
|
|
|
|
// {
|
|
|
|
this.entity.dropOneItem(true);
|
|
|
|
// }
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
case RELEASE_USE_ITEM:
|
|
|
|
this.entity.stopUsingItem();
|
|
|
|
return;
|
|
|
|
|
|
|
|
case START_DESTROY_BLOCK:
|
|
|
|
case ABORT_DESTROY_BLOCK:
|
|
|
|
case STOP_DESTROY_BLOCK:
|
|
|
|
double d0 = this.entity.posX - ((double)blockpos.getX() + 0.5D);
|
|
|
|
double d1 = this.entity.posY - ((double)blockpos.getY() + 0.5D) + 1.5D;
|
|
|
|
double d2 = this.entity.posZ - ((double)blockpos.getZ() + 0.5D);
|
|
|
|
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
|
|
|
|
double max = this.entity.getReachDistance() + 1.0D;
|
|
|
|
max *= max;
|
|
|
|
|
|
|
|
if (d3 > max)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (blockpos.getY() >= World.HEIGHT)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (packetIn.getStatus() == CPacketBreak.Action.START_DESTROY_BLOCK)
|
|
|
|
{
|
|
|
|
if (World.isValidXZ(blockpos))
|
|
|
|
{
|
|
|
|
this.onBlockClicked(blockpos, packetIn.getFacing());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.sendPacket(new SPacketBlockChange(worldserver, blockpos));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (packetIn.getStatus() == CPacketBreak.Action.STOP_DESTROY_BLOCK)
|
|
|
|
{
|
|
|
|
this.blockRemoving(blockpos);
|
|
|
|
}
|
|
|
|
else if (packetIn.getStatus() == CPacketBreak.Action.ABORT_DESTROY_BLOCK)
|
|
|
|
{
|
|
|
|
this.cancelDestroyingBlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (worldserver.getState(blockpos).getBlock().getMaterial() != Material.air)
|
|
|
|
{
|
|
|
|
this.sendPacket(new SPacketBlockChange(worldserver, blockpos));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw new IllegalArgumentException("Ungültige Aktion");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processPlace(CPacketPlace packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension);
|
|
|
|
ItemStack itemstack = this.entity.inventory.getCurrentItem();
|
|
|
|
boolean flag = false;
|
|
|
|
BlockPos blockpos = packetIn.getPosition();
|
|
|
|
Facing enumfacing = Facing.getFront(packetIn.getPlacedBlockDirection());
|
|
|
|
|
|
|
|
if (packetIn.getPlacedBlockDirection() == 255)
|
|
|
|
{
|
|
|
|
if (itemstack == null)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if(!InteractionHandler.onPlayerInteract(this.playerEntity, false, null)) {
|
|
|
|
this.tryUseItem(itemstack);
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
else if (blockpos.getY() < World.HEIGHT - 1 || enumfacing != Facing.UP && blockpos.getY() < World.HEIGHT)
|
|
|
|
{
|
|
|
|
double max = this.entity.getReachDistance() + 3.0D;
|
|
|
|
max *= max;
|
|
|
|
if (this.hasMoved && this.entity.getDistanceSq((double)blockpos.getX() + 0.5D, (double)blockpos.getY() + 0.5D, (double)blockpos.getZ() + 0.5D) < max && World.isValidXZ(blockpos))
|
|
|
|
{
|
|
|
|
this.activateBlockOrUseItem(itemstack, blockpos, enumfacing, packetIn.getPlacedBlockOffsetX(), packetIn.getPlacedBlockOffsetY(), packetIn.getPlacedBlockOffsetZ());
|
|
|
|
}
|
|
|
|
|
|
|
|
flag = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// String comp = String.format("Die maximale Bauhöhe beträgt %d Blöcke", World.HEIGHT);
|
|
|
|
//// comp.setColor(ChatFormat.RED);
|
|
|
|
// this.message(comp);
|
|
|
|
flag = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
this.entity.connection.sendPacket(new SPacketBlockChange(worldserver, blockpos));
|
|
|
|
this.entity.connection.sendPacket(new SPacketBlockChange(worldserver, blockpos.offset(enumfacing)));
|
|
|
|
}
|
|
|
|
|
|
|
|
itemstack = this.entity.inventory.getCurrentItem();
|
|
|
|
|
|
|
|
if (itemstack != null && itemstack.stackSize == 0)
|
|
|
|
{
|
|
|
|
this.entity.inventory.mainInventory[this.entity.inventory.currentItem] = null;
|
|
|
|
itemstack = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (itemstack == null || itemstack.getMaxItemUseDuration() == 0)
|
|
|
|
{
|
|
|
|
this.isChangingQuantityOnly = true;
|
|
|
|
this.entity.inventory.mainInventory[this.entity.inventory.currentItem] = ItemStack.copyItemStack(this.entity.inventory.mainInventory[this.entity.inventory.currentItem]);
|
|
|
|
Slot slot = this.entity.openContainer.getSlotFromInventory(this.entity.inventory, this.entity.inventory.currentItem);
|
|
|
|
this.entity.openContainer.detectAndSendChanges();
|
|
|
|
this.isChangingQuantityOnly = false;
|
|
|
|
|
|
|
|
if (!ItemStack.areItemStacksEqual(this.entity.inventory.getCurrentItem(), packetIn.getStack()))
|
|
|
|
{
|
|
|
|
this.sendPacket(new S2FPacketSetSlot(this.entity.openContainer.windowId, slot.slotNumber, this.entity.inventory.getCurrentItem()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void useEntity(int entityId, boolean interact)
|
|
|
|
{
|
|
|
|
WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension);
|
|
|
|
Entity entity = worldserver.getEntityByID(entityId);
|
|
|
|
if (entity != null)
|
|
|
|
{
|
|
|
|
boolean flag = this.entity.canEntityBeSeen(entity);
|
|
|
|
double max = this.entity.getReachDistance() + 1.0D;
|
|
|
|
max *= max;
|
|
|
|
// double d0 = 36.0D;
|
|
|
|
if(!flag) {
|
|
|
|
max = (this.entity.getReachDistance() + 1.0D) * 0.5D; // 9.0D
|
|
|
|
max *= max;
|
|
|
|
}
|
|
|
|
if (this.entity.getDistanceSqToEntity(entity) < max)
|
|
|
|
{
|
|
|
|
if (interact)
|
|
|
|
{
|
|
|
|
this.entity.interactWith(entity);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (entity instanceof EntityItem || entity instanceof EntityXp || entity instanceof EntityArrow || entity == this.entity)
|
|
|
|
{
|
|
|
|
throw new IllegalArgumentException("Ungültiges Objekt angegriffen");
|
|
|
|
// Log.warn("Spieler " + this.user + " versuchte ein falsches Objekt anzugreifen");
|
|
|
|
// return;
|
|
|
|
}
|
|
|
|
this.entity.attackTargetEntityWithCurrentItem(entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processAction(CPacketAction packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
|
|
|
|
switch (packetIn.getAction())
|
|
|
|
{
|
|
|
|
case START_SNEAKING:
|
|
|
|
this.entity.setSneaking(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STOP_SNEAKING:
|
|
|
|
this.entity.setSneaking(false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case START_SPRINTING:
|
|
|
|
this.entity.setSprinting(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STOP_SPRINTING:
|
|
|
|
this.entity.setSprinting(false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
// case STOP_SLEEPING:
|
|
|
|
// this.playerEntity.wakeUpPlayer();
|
|
|
|
// this.hasMoved = false;
|
|
|
|
// break;
|
|
|
|
|
|
|
|
case RIDING_JUMP:
|
|
|
|
if (this.entity.vehicle instanceof EntityHorse)
|
|
|
|
{
|
|
|
|
((EntityHorse)this.entity.vehicle).setJumpPower(packetIn.getAuxData());
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPEN_INVENTORY:
|
|
|
|
if (this.entity.vehicle instanceof EntityHorse)
|
|
|
|
{
|
|
|
|
((EntityHorse)this.entity.vehicle).openGUI(this.entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case START_FLYING:
|
|
|
|
this.entity.flying = this.entity.hasEffect(Potion.flying) || this.entity.noclip;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STOP_FLYING:
|
|
|
|
this.entity.flying = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PERFORM_RESPAWN:
|
|
|
|
this.respawnPlayer();
|
|
|
|
break;
|
|
|
|
|
|
|
|
// case REQUEST_STATS:
|
|
|
|
// this.sendStats();
|
|
|
|
// break;
|
|
|
|
|
|
|
|
// case SET_MODELPARTS:
|
|
|
|
// this.entity.setModelParts(packetIn.getAuxData());
|
|
|
|
// break;
|
|
|
|
|
|
|
|
case SET_HEIGHT:
|
|
|
|
this.entity.setHeight(((float)ExtMath.clampi(packetIn.getAuxData(), 120, 320) * 0.01f) / this.entity.getSpecies().size);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SELECT_TRADE:
|
|
|
|
try
|
|
|
|
{
|
|
|
|
int idx = packetIn.getAuxData();
|
|
|
|
Container container = this.entity.openContainer;
|
|
|
|
if(container instanceof ContainerMerchant)
|
|
|
|
((ContainerMerchant)container).setCurrentRecipeIndex(idx);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
Log.JNI.error(e, "Konnte Handel nicht wählen");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
// case SET_BEACON:
|
|
|
|
// if (this.entity.openContainer instanceof ContainerBeacon)
|
|
|
|
// {
|
|
|
|
// try
|
|
|
|
// {
|
|
|
|
// int k = packetIn.getAuxData() & 255;
|
|
|
|
// int l = packetIn.getAuxData() >> 8;
|
|
|
|
// ContainerBeacon containerbeacon = (ContainerBeacon)this.entity.openContainer;
|
|
|
|
// Slot slot = containerbeacon.getSlot(0);
|
|
|
|
//
|
|
|
|
// if (slot.getHasStack())
|
|
|
|
// {
|
|
|
|
// slot.decrStackSize(1);
|
|
|
|
// IInventory iinventory = containerbeacon.func_180611_e();
|
|
|
|
// iinventory.setField(1, k);
|
|
|
|
// iinventory.setField(2, l);
|
|
|
|
// iinventory.markDirty();
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// catch (Exception exception)
|
|
|
|
// {
|
|
|
|
// SKC.error((String)"Konnte Leuchtfeuer nicht ändern", (Throwable)exception);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
|
|
|
|
case SWING_ARM:
|
|
|
|
this.entity.swingItem();
|
|
|
|
// if(packetIn.getAuxData() != 0)
|
|
|
|
// this.playerEntity.swingItemMiss(); // InteractionHandler.onPlayerInteract(this.playerEntity, true, null);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SET_ITEMSLOT:
|
|
|
|
if(packetIn.getAuxData() >= 0 && packetIn.getAuxData() < InventoryPlayer.getHotbarSize())
|
|
|
|
this.entity.inventory.currentItem = packetIn.getAuxData();
|
|
|
|
// else
|
|
|
|
// Log.warn(this.user + " versuchte, einen ungültigen Slot zu wählen");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ATTACK:
|
|
|
|
this.useEntity(packetIn.getAuxData(), false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case INTERACT:
|
|
|
|
this.useEntity(packetIn.getAuxData(), true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CLOSE_CONTAINER:
|
|
|
|
if(this.entity.openContainer.windowId == packetIn.getAuxData())
|
|
|
|
this.closeContainer();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CONFIRM_TRANSACTION:
|
|
|
|
Short tr = this.transactions.lookup(this.entity.openContainer.windowId);
|
|
|
|
if(tr != null && (short)(packetIn.getAuxData() >> 8) == tr.shortValue() && this.entity.openContainer.windowId == (packetIn.getAuxData() & 255) && !this.entity.openContainer.getCanCraft(this.entity)) // && !this.playerEntity.isSpectator())
|
|
|
|
this.entity.openContainer.setCanCraft(this.entity, true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ENCHANT_ITEM:
|
|
|
|
if(this.entity.openContainer.windowId == (packetIn.getAuxData() & 255) && this.entity.openContainer.getCanCraft(this.entity)) // && !this.playerEntity.isSpectator())
|
|
|
|
{
|
|
|
|
this.entity.openContainer.enchantItem(this.entity, (packetIn.getAuxData() >> 8) % 3);
|
|
|
|
this.entity.openContainer.detectAndSendChanges();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SET_ALIGN:
|
|
|
|
Alignment align = Alignment.values()[packetIn.getAuxData() % Alignment.values().length];
|
|
|
|
this.entity.setAlignment(align);
|
|
|
|
// this.serverController.sendPacket(new S38PacketPlayerListItem(Action.UPDATE_DISPLAY_NAME, this.playerEntity));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ITEM_ACTION:
|
|
|
|
ItemStack item = this.entity.getCurrentEquippedItem();
|
|
|
|
if(item != null)
|
|
|
|
item.getItem().onAction(item, this.entity, this.entity.worldObj,
|
|
|
|
ItemControl.values()[packetIn.getAuxData() % ItemControl.values().length], null);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GOD:
|
|
|
|
if(this.isAdmin()) {
|
|
|
|
// this.playerEntity.setCheat(!this.playerEntity.godmode);
|
|
|
|
this.entity.fallDistance = 0.0F;
|
|
|
|
if(this.entity.hasEffect(Potion.digSpeed) && this.entity.getEffect(Potion.digSpeed).getAmplifier() == 255) {
|
|
|
|
this.entity.removeEffect(Potion.digSpeed.id);
|
|
|
|
this.entity.removeEffect(Potion.resistance.id);
|
|
|
|
this.entity.removeEffect(Potion.fireResistance.id);
|
|
|
|
this.entity.removeEffect(Potion.flying.id);
|
|
|
|
this.entity.removeEffect(Potion.manaBoost.id);
|
|
|
|
this.addFeed(TextColor.RED + "Statuseffekte wurden entfernt");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.entity.extinguish();
|
|
|
|
this.entity.setHealth(this.entity.getMaxHealth());
|
|
|
|
this.entity.setManaPoints(this.entity.getMaxMana());
|
|
|
|
this.entity.clearEffects(false);
|
|
|
|
this.entity.addEffect(new PotionEffect(Potion.digSpeed.id, Integer.MAX_VALUE, 255, false, false));
|
|
|
|
this.entity.addEffect(new PotionEffect(Potion.resistance.id, Integer.MAX_VALUE, 255, false, false));
|
|
|
|
this.entity.addEffect(new PotionEffect(Potion.fireResistance.id, Integer.MAX_VALUE, 0, false, false));
|
|
|
|
this.entity.addEffect(new PotionEffect(Potion.flying.id, Integer.MAX_VALUE, 0, false, false));
|
|
|
|
this.entity.addEffect(new PotionEffect(Potion.manaBoost.id, Integer.MAX_VALUE, 255, false, false));
|
|
|
|
this.addFeed(TextColor.GREEN + "Statuseffekte wurden hinzugefügt");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NOCLIP:
|
|
|
|
if(this.isAdmin()) {
|
|
|
|
if(!this.entity.noclip)
|
|
|
|
this.entity.mountEntity(null);
|
|
|
|
this.entity.noclip ^= true;
|
|
|
|
this.entity.flying &= this.entity.hasEffect(Potion.flying) || this.entity.noclip;
|
|
|
|
this.entity.fallDistance = 0.0F;
|
|
|
|
this.sendPlayerAbilities();
|
|
|
|
this.addFeed((this.entity.noclip ? TextColor.GREEN : TextColor.RED) + "NoClip ist jetzt " + (this.entity.noclip ? "eingeschaltet" : "ausgeschaltet"));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SPEED:
|
|
|
|
if(this.isAdmin()) {
|
|
|
|
if(this.entity.hasEffect(Potion.moveSpeed))
|
|
|
|
this.entity.removeEffect(Potion.moveSpeed.id);
|
|
|
|
else
|
|
|
|
this.entity.addEffect(new PotionEffect(Potion.moveSpeed.id, Integer.MAX_VALUE, 19, false, false));
|
|
|
|
this.addFeed(TextColor.GREEN + "Deine Geschwindigkeit wurde auf %dx geändert", (int)(this.entity.getAIMoveSpeed() * 10.0f));
|
|
|
|
// int speed = this.playerEntity.speed != 1.0f ? 1 : 5;
|
|
|
|
// this.playerEntity.speed = (float)speed;
|
|
|
|
// this.playerEntity.sendPlayerAbilities();
|
|
|
|
// this.playerEntity.addFeed(TextColor.GREEN + "Deine Geschwindigkeit wurde auf %dx geändert", speed);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HEAL:
|
|
|
|
if(this.isAdmin() && this.entity.getHealth() > 0) {
|
|
|
|
this.entity.extinguish();
|
|
|
|
this.entity.setHealth(this.entity.getMaxHealth());
|
|
|
|
this.entity.setManaPoints(this.entity.getMaxMana());
|
|
|
|
this.entity.clearEffects(true);
|
|
|
|
this.addFeed(TextColor.DGREEN + "Du wurdest geheilt");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REPAIR:
|
|
|
|
if(this.isAdmin() && this.entity.getCurrentEquippedItem() != null) {
|
|
|
|
ItemStack itemstack = this.entity.getCurrentEquippedItem();
|
|
|
|
int diff = itemstack.getMaxStackSize() - itemstack.stackSize;
|
|
|
|
itemstack.stackSize = itemstack.getMaxStackSize();
|
|
|
|
itemstack.setRepairCost(0);
|
|
|
|
if(itemstack.getItem().getMaxDamage() > 0)
|
|
|
|
itemstack.setItemDamage(0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PERF:
|
|
|
|
if(this.isAdmin()) {
|
|
|
|
Server server = this.server;
|
|
|
|
server.saveAllPlayerData(false);
|
|
|
|
server.saveWorldInfo();
|
|
|
|
for(WorldServer world : server.getWorlds()) {
|
|
|
|
world.saveAllChunks();
|
|
|
|
}
|
|
|
|
// sender.addConsole("Beende E/A...");
|
|
|
|
Region.finishWrite();
|
|
|
|
// sender.addConsole("E/A beendet und Puffer geleert");
|
|
|
|
// sender.addConsole("Entlade Dimensionen...");
|
|
|
|
int worlds = server.getWorlds().size();
|
|
|
|
List<WorldServer> unload = Lists.newArrayList(server.getWorlds());
|
|
|
|
for(WorldServer world : unload) {
|
|
|
|
server.unloadWorld(world);
|
|
|
|
}
|
|
|
|
unload.clear();
|
|
|
|
worlds -= server.getWorlds().size();
|
|
|
|
// if(worlds > 0)
|
|
|
|
// sender.addConsole("%s Dimensionen wurden entladen", worlds);
|
|
|
|
long mem = Runtime.getRuntime().freeMemory();
|
|
|
|
System.gc();
|
|
|
|
System.gc();
|
|
|
|
mem = Runtime.getRuntime().freeMemory() - mem;
|
|
|
|
mem = mem < 0L ? 0L : mem;
|
|
|
|
// sender.addConsole("Server-JVM GC ausgeführt: ", );
|
|
|
|
this.addFeed(TextColor.DGREEN + "%s%s MB freigegeben, %s MB von %s MB verwendet (%s %%)", worlds > 0 ? worlds + " entladen, " : "", mem / 1024L / 1024L, (Runtime.getRuntime().totalMemory() -
|
|
|
|
Runtime.getRuntime().freeMemory()) / 1024L / 1024L, Runtime.getRuntime().totalMemory() / 1024L / 1024L,
|
|
|
|
Runtime.getRuntime().freeMemory() * 100L / Runtime.getRuntime().maxMemory());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MAGNET:
|
|
|
|
if(this.isAdmin()) {
|
|
|
|
List<Entity> list = this.entity.worldObj.getEntitiesWithinAABB(Entity.class, new BoundingBox(this.entity.getPosition().subtract(new BlockPos(128, 128, 128)), this.entity.getPosition().add(new BlockPos(128, 128, 128))), new Predicate<Entity>() {
|
|
|
|
public boolean test(Entity entity) {
|
|
|
|
return entity.isEntityAlive() && (entity instanceof EntityItem || entity instanceof EntityXp);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
for(Entity entity : list) {
|
|
|
|
entity.teleport(this.entity.posX, this.entity.posY, this.entity.posZ,
|
|
|
|
this.entity.rotYaw, this.entity.rotPitch, this.entity.worldObj.dimension.getDimensionId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw new IllegalArgumentException("Ungültige Aktion!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processInput(CPacketInput packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
this.setEntityActionState(packetIn.getStrafeSpeed(), packetIn.getForwardSpeed(), packetIn.isJumping(), packetIn.isSneaking());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processClick(CPacketClick packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
|
|
|
|
if (this.entity.openContainer.windowId == packetIn.getWindowId() && this.entity.openContainer.getCanCraft(this.entity))
|
|
|
|
{
|
|
|
|
// if (this.playerEntity.isSpectator())
|
|
|
|
// {
|
|
|
|
// List<ItemStack> list = Lists.<ItemStack>newArrayList();
|
|
|
|
//
|
|
|
|
// for (int i = 0; i < this.playerEntity.openContainer.inventorySlots.size(); ++i)
|
|
|
|
// {
|
|
|
|
// list.add(((Slot)this.playerEntity.openContainer.inventorySlots.get(i)).getStack());
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// this.playerEntity.updateCraftingInventory(this.playerEntity.openContainer, list);
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
ItemStack itemstack = this.entity.openContainer.slotClick(packetIn.getSlotId(), packetIn.getUsedButton(), packetIn.getMode(), this.entity);
|
|
|
|
|
|
|
|
if (ItemStack.areItemStacksEqual(packetIn.getClickedItem(), itemstack))
|
|
|
|
{
|
|
|
|
this.entity.connection.sendPacket(new S32PacketConfirmTransaction(packetIn.getWindowId(), packetIn.getActionNumber(), true));
|
|
|
|
this.isChangingQuantityOnly = true;
|
|
|
|
this.entity.openContainer.detectAndSendChanges();
|
|
|
|
this.updateHeldItem();
|
|
|
|
this.isChangingQuantityOnly = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.transactions.addKey(this.entity.openContainer.windowId, Short.valueOf(packetIn.getActionNumber()));
|
|
|
|
this.entity.connection.sendPacket(new S32PacketConfirmTransaction(packetIn.getWindowId(), packetIn.getActionNumber(), false));
|
|
|
|
this.entity.openContainer.setCanCraft(this.entity, false);
|
|
|
|
List<ItemStack> list1 = Lists.<ItemStack>newArrayList();
|
|
|
|
|
|
|
|
for (int j = 0; j < this.entity.openContainer.inventorySlots.size(); ++j)
|
|
|
|
{
|
|
|
|
list1.add(((Slot)this.entity.openContainer.inventorySlots.get(j)).getStack());
|
|
|
|
}
|
|
|
|
|
|
|
|
this.updateCraftingInventory(this.entity.openContainer, list1);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processCheat(CPacketCheat packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
|
|
|
|
if(!this.isAdmin())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// if (this.playerEntity.creative)
|
|
|
|
// {
|
|
|
|
// boolean drop = packetIn.getSlotId() < 0;
|
|
|
|
// boolean changed = false;
|
|
|
|
ItemStack itemstack = packetIn.getStack();
|
|
|
|
// if(itemstack != null && itemstack.getItem() == Items.barrier && !this.playerEntity.canUse(Permissions.BARRIER)) {
|
|
|
|
// changed = true;
|
|
|
|
// itemstack = null;
|
|
|
|
// }
|
|
|
|
// if(itemstack != null && !itemstack.validate()) {
|
|
|
|
// changed = true;
|
|
|
|
// }
|
|
|
|
|
|
|
|
if (itemstack.hasTagCompound() && itemstack.getTagCompound().hasKey("BlockEntityTag"))
|
|
|
|
{
|
|
|
|
// if(!itemstack.getTagCompound().hasKey("BlockEntityTag", 10)) {
|
|
|
|
// changed = true;
|
|
|
|
// itemstack.setTagCompound(null);
|
|
|
|
// }
|
|
|
|
// else {
|
|
|
|
NBTTagCompound nbttagcompound = itemstack.getTagCompound().getCompoundTag("BlockEntityTag");
|
|
|
|
|
|
|
|
if (nbttagcompound.hasKey("x") && nbttagcompound.hasKey("y") && nbttagcompound.hasKey("z"))
|
|
|
|
{
|
|
|
|
BlockPos blockpos = new BlockPos(nbttagcompound.getInteger("x"), nbttagcompound.getInteger("y"), nbttagcompound.getInteger("z"));
|
|
|
|
TileEntity tileentity = this.entity.worldObj.getTileEntity(blockpos);
|
|
|
|
|
|
|
|
if (tileentity != null)
|
|
|
|
{
|
|
|
|
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
|
|
|
tileentity.writeToNBT(nbttagcompound1);
|
|
|
|
nbttagcompound1.removeTag("x");
|
|
|
|
nbttagcompound1.removeTag("y");
|
|
|
|
nbttagcompound1.removeTag("z");
|
|
|
|
itemstack.setTagInfo("BlockEntityTag", nbttagcompound1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
// boolean validSlot = packetIn.getSlotId() >= 1 && packetIn.getSlotId() < 36 + InventoryPlayer.getHotbarSize();
|
|
|
|
boolean validItem = itemstack.getItem() != null;
|
|
|
|
boolean validData = itemstack.getMetadata() >= 0 && itemstack.stackSize <= itemstack.getMaxStackSize() && itemstack.stackSize > 0; // TODO: max
|
|
|
|
|
|
|
|
if (validItem && validData)
|
|
|
|
{
|
|
|
|
int amount = itemstack.stackSize;
|
|
|
|
if(packetIn.getSlot() == -1) {
|
|
|
|
this.entity.inventory.addItemStackToInventory(itemstack);
|
|
|
|
amount -= itemstack.stackSize;
|
|
|
|
}
|
|
|
|
else if(packetIn.getSlot() >= 0 && packetIn.getSlot() < 9) {
|
|
|
|
ItemStack old = this.entity.inventory.getStackInSlot(packetIn.getSlot());
|
|
|
|
if(old != null) {
|
|
|
|
if(ItemStack.areItemsEqual(itemstack, old) && ItemStack.areItemStackTagsEqual(itemstack, old)) {
|
|
|
|
itemstack.stackSize = Math.min(itemstack.getMaxStackSize(), old.stackSize + itemstack.stackSize);
|
|
|
|
amount = itemstack.stackSize - old.stackSize;
|
|
|
|
}
|
|
|
|
else if(old.stackSize == 1)
|
|
|
|
this.addFeed(TextColor.DRED + "* %s zerstört",
|
|
|
|
old.getColoredName(TextColor.DRED));
|
|
|
|
else
|
|
|
|
this.addFeed(TextColor.DRED + "* %d %s zerstört", old.stackSize,
|
|
|
|
old.getColoredName(TextColor.DRED));
|
|
|
|
}
|
|
|
|
this.entity.inventory.setInventorySlotContents(packetIn.getSlot(), itemstack);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.entity.openContainer.detectAndSendChanges();
|
|
|
|
if(amount <= 0)
|
|
|
|
return;
|
|
|
|
this.entity.worldObj.playSoundAtEntity(this.entity, SoundEvent.POP, 0.2F, ((this.entity.worldObj.rand.floatv() - this.entity.worldObj.rand.floatv()) * 0.7F + 1.0F) * 2.0F);
|
|
|
|
if(amount == 1)
|
|
|
|
this.addFeed(TextColor.DGREEN + "* %s geschummelt",
|
|
|
|
itemstack.getColoredName(TextColor.DGREEN));
|
|
|
|
else
|
|
|
|
this.addFeed(TextColor.DGREEN + "* %d %s geschummelt", amount,
|
|
|
|
itemstack.getColoredName(TextColor.DGREEN));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processSign(CPacketSign packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
|
|
|
|
WorldServer worldserver = this.entity.getServerWorld(); // this.serverController.getWorld(this.playerEntity.dimension);
|
|
|
|
BlockPos blockpos = packetIn.getPosition();
|
|
|
|
|
|
|
|
if (worldserver.isBlockLoaded(blockpos))
|
|
|
|
{
|
|
|
|
TileEntity tileentity = worldserver.getTileEntity(blockpos);
|
|
|
|
|
|
|
|
if (!(tileentity instanceof TileEntitySign))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TileEntitySign tileentitysign = (TileEntitySign)tileentity;
|
|
|
|
|
|
|
|
if (tileentitysign.getPlayer() != this.entity)
|
|
|
|
{
|
|
|
|
// Log.warn("Spieler " + this.user + " versuchte, ein nicht editierbares Schild zu ändern");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
String[] lines = packetIn.getLines();
|
|
|
|
|
|
|
|
// boolean color = this.playerEntity.canUse(Permissions.SIGNFORMAT);
|
|
|
|
for (int i = 0; i < lines.length; ++i)
|
|
|
|
{
|
|
|
|
tileentitysign.signText[i] = TextColor.stripCodes(lines[i]); // lines[i]; // color ? lines[i] : ChatFormat.stripCodes(lines[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// if(this.signCommand != null) {
|
|
|
|
// if(this.playerEntity.isAdmin()) {
|
|
|
|
// tileentitysign.command = this.signCommand;
|
|
|
|
//// this.serverController.getSigns().addEntry(new Sign(new WorldPos(tileentitysign), this.signCommand));
|
|
|
|
// this.playerEntity.addFeed(TextColor.GREEN + "Befehl für Schild gesetzt: " + TextColor.LIGHT_GRAY + "/" + this.signCommand);
|
|
|
|
// }
|
|
|
|
// this.signCommand = null;
|
|
|
|
// }
|
|
|
|
|
|
|
|
tileentitysign.markDirty();
|
|
|
|
worldserver.markBlockForUpdate(blockpos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private List<String> getWarpList() {
|
|
|
|
List<String> warps = Lists.newArrayList(this.server.getUsers());
|
|
|
|
warps.add("@spawn");
|
|
|
|
for(String warp : this.server.getWarps().keySet()) {
|
|
|
|
warps.add("@" + warp);
|
|
|
|
}
|
|
|
|
for(String dim : UniverseRegistry.getWorldNames()) {
|
|
|
|
warps.add("*" + dim);
|
|
|
|
}
|
|
|
|
return warps;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static List<String> getVarList() {
|
|
|
|
List<String> list = Lists.newArrayList(Config.VARS.keySet());
|
|
|
|
list.add("time");
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static List<String> getVarCompletion(String var) {
|
|
|
|
Config.Value v = Config.VARS.get(var);
|
|
|
|
if(v == null)
|
|
|
|
return Lists.newArrayList();
|
|
|
|
if(v.type == ValueType.BOOLEAN)
|
|
|
|
return Boolean.parseBoolean(v.getValue()) ? Lists.newArrayList("false", "true") : Lists.newArrayList("true", "false");
|
|
|
|
else if(v.type == ValueType.INTEGER || v.type == ValueType.FLOAT)
|
|
|
|
return Lists.newArrayList(v.def);
|
|
|
|
return Lists.newArrayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processComplete(CPacketComplete packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
List<String> list = Lists.<String>newArrayList(); // Command.getCompletions(this.playerEntity, packetIn.getMessage());
|
|
|
|
|
|
|
|
// for (String s : )
|
|
|
|
// {
|
|
|
|
// list.add(s);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if(list == null) {
|
|
|
|
// list = Lists.<String>newArrayList();
|
|
|
|
String s = packetIn.getMessage();
|
|
|
|
char pre = s.startsWith("@") || (this.isAdmin() && (s.startsWith("#") || s.startsWith("!"))) || ((Config.teleportAllowed || this.isAdmin()) && s.startsWith("/")) ? s.charAt(0) : 0;
|
|
|
|
s = pre == 0 ? s : s.substring(1);
|
|
|
|
String[] argv = s.split(" ", -1);
|
|
|
|
s = argv[argv.length - 1];
|
|
|
|
Iterable<String> res = pre == '#' ?
|
|
|
|
(argv.length == 1 ? getVarList() : (argv.length == 2 ? (argv[0].equals("time") ? Lists.newArrayList("day", "night", "noon", "midnight", "sunrise", "sunset") : getVarCompletion(argv[0])) : Lists.newArrayList())) : (pre == '/' ? (argv.length == 4 ? UniverseRegistry.getWorldNames() : (argv.length == 1 ? this.getWarpList() : Lists.newArrayList())) : this.server.getAllUsernames());
|
|
|
|
for(String s1 : res) {
|
|
|
|
if(s1.regionMatches(true, 0, s, 0, s.length()))
|
|
|
|
list.add((argv.length == 1 ? pre : "") + s1);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
this.entity.connection.sendPacket(new S3APacketTabComplete((String[])list.toArray(new String[list.size()])));
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean respawnPlayer() {
|
|
|
|
if(this.entity.getHealth() > 0)
|
|
|
|
return false;
|
|
|
|
this.server.recreatePlayer(this);
|
|
|
|
// if(Config.noRespawn)
|
|
|
|
// this.playerEntity.setGamemode(Gamemode.SPECTATOR);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processSkin(CPacketSkin packetIn)
|
|
|
|
{
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
// if(!this.netManager.isLocalChannel() && System.currentTimeMillis() - this.lastSkinUpdate < 1000L) {
|
|
|
|
// String comp = "Bitte warte 1 Sekunde bevor du deinen Skin änderst";
|
|
|
|
//// comp.setColor();
|
|
|
|
// this.message(comp);
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
// this.entity.setModel(packetIn.getModel());
|
|
|
|
this.entity.setSkin(packetIn.getCompressed());
|
|
|
|
this.server.sendPacket(new SPacketSkin(this.entity.getId(), packetIn.getCompressed())); // , packetIn.getModel()));
|
|
|
|
// if(/* this.lastSkinUpdate != 0L && */ Config.sendSkinChange && !this.netManager.isLocalChannel()) {
|
|
|
|
// String comp = "Dein Skin wurde geändert";
|
|
|
|
//// comp.setColor();
|
|
|
|
// this.message(comp);
|
|
|
|
// }
|
|
|
|
// this.lastSkinUpdate = System.currentTimeMillis();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void processBook(CPacketBook packetIn) {
|
|
|
|
NetHandler.checkThread(packetIn, this, this.server);
|
|
|
|
String[] pages = packetIn.getPages();
|
|
|
|
// if (!ItemWritableBook.isNBTValid(itemstack1.getTagCompound()))
|
|
|
|
// throw new IOException("Fehlerhafter Buch-Tag!");
|
|
|
|
ItemStack itemstack = this.entity.inventory.getCurrentItem();
|
|
|
|
if (itemstack != null && itemstack.getItem() == Items.writable_book)
|
|
|
|
{
|
|
|
|
if(pages.length == 0) {
|
|
|
|
if(itemstack.hasTagCompound()) {
|
|
|
|
itemstack.getTagCompound().removeTag("pages");
|
|
|
|
if(itemstack.getTagCompound().hasNoTags())
|
|
|
|
itemstack.setTagCompound(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NBTTagList list = new NBTTagList();
|
|
|
|
for(String page : pages) {
|
|
|
|
list.appendTag(new NBTTagString(page));
|
|
|
|
}
|
|
|
|
itemstack.setTagInfo("pages", list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void processCmdBlock(CPacketCmdBlock packetIn) {
|
|
|
|
// NetHandler.checkThread(packetIn, this, this.serverController);
|
|
|
|
//
|
|
|
|
// if (!Config.commandBlocks)
|
|
|
|
// {
|
|
|
|
// this.message(new Translation("advMode.notEnabled"));
|
|
|
|
// }
|
|
|
|
// else if (!this.playerEntity.canUse(Permissions.CMDBLOCK)) {
|
|
|
|
// this.message(new Translation("advMode.notAllowed"));
|
|
|
|
// }
|
|
|
|
// else if(this.playerEntity.capabilities.isCreativeMode)
|
|
|
|
// {
|
|
|
|
// try
|
|
|
|
// {
|
|
|
|
// int j = packetIn.getType();
|
|
|
|
// CommandBlockLogic commandblocklogic = null;
|
|
|
|
//
|
|
|
|
// if (j == 0)
|
|
|
|
// {
|
|
|
|
// TileEntity tileentity = this.playerEntity.worldObj.getTileEntity(packetIn.getPosition());
|
|
|
|
//
|
|
|
|
// if (tileentity instanceof TileEntityCommandBlock)
|
|
|
|
// {
|
|
|
|
// commandblocklogic = ((TileEntityCommandBlock)tileentity).getCommandBlockLogic();
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// else if (j == 1)
|
|
|
|
// {
|
|
|
|
// Entity entity = this.playerEntity.worldObj.getEntityByID(packetIn.getEntityId());
|
|
|
|
//
|
|
|
|
// if (entity instanceof EntityMinecartCommandBlock)
|
|
|
|
// {
|
|
|
|
// commandblocklogic = ((EntityMinecartCommandBlock)entity).getCommandBlockLogic();
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// String s1 = packetIn.getCommand();
|
|
|
|
// boolean flag = packetIn.getTrackOutput();
|
|
|
|
//
|
|
|
|
// if (commandblocklogic != null)
|
|
|
|
// {
|
|
|
|
// commandblocklogic.setCommand(s1);
|
|
|
|
// commandblocklogic.setTrackOutput(flag);
|
|
|
|
//
|
|
|
|
// if (!flag)
|
|
|
|
// {
|
|
|
|
// commandblocklogic.setLastOutput((TextComponent)null);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// commandblocklogic.setEnabled(true);
|
|
|
|
// commandblocklogic.updateCommand();
|
|
|
|
// this.message(new Translation("advMode.setCommand.success", s1));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// catch (Exception exception1)
|
|
|
|
// {
|
|
|
|
// Log.error((String)"Konnte Befehlsblock nicht setzen", (Throwable)exception1);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|