A fuck ton of changes
This commit is contained in:
parent
8d4f78755d
commit
7f292dffca
|
@ -78,7 +78,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.2.4</version>
|
<version>2.9.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.avaje</groupId>
|
<groupId>org.avaje</groupId>
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.20</version>
|
<version>1.18.22</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Thread Affinity -->
|
<!-- Thread Affinity -->
|
||||||
|
@ -136,8 +136,6 @@
|
||||||
<!-- versions after this appear to be broken -->
|
<!-- versions after this appear to be broken -->
|
||||||
<version>3.1</version>
|
<version>3.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- we use the Eclipse compiler as it doesn't need a JDK -->
|
|
||||||
<compilerId>eclipse</compilerId>
|
|
||||||
<!-- source and target are ignored if this isn't true -->
|
<!-- source and target are ignored if this isn't true -->
|
||||||
<optimize>true</optimize>
|
<optimize>true</optimize>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package net.techcable.tacospigot.event.entity;
|
||||||
|
|
||||||
|
public interface ChunkSnapshot {
|
||||||
|
|
||||||
|
}
|
|
@ -121,4 +121,8 @@ public interface Chunk {
|
||||||
* @return true if the chunk has unloaded successfully, otherwise false
|
* @return true if the chunk has unloaded successfully, otherwise false
|
||||||
*/
|
*/
|
||||||
boolean unload();
|
boolean unload();
|
||||||
|
|
||||||
|
net.techcable.tacospigot.event.entity.ChunkSnapshot takeSnapshot();
|
||||||
|
|
||||||
|
void restoreSnapshot(net.techcable.tacospigot.event.entity.ChunkSnapshot snapshot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -494,6 +494,23 @@ public interface World extends PluginMessageRecipient, Metadatable {
|
||||||
*/
|
*/
|
||||||
public boolean setSpawnLocation(int x, int y, int z);
|
public boolean setSpawnLocation(int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the spawn location of the world
|
||||||
|
*
|
||||||
|
* @param x X coordinate
|
||||||
|
* @param y Y coordinate
|
||||||
|
* @param z Z coordinate
|
||||||
|
* @return True if it was successfully set.
|
||||||
|
*/
|
||||||
|
public boolean setSpawnLocation(double x, double y, double z, float yaw, float pitch);
|
||||||
|
/**
|
||||||
|
* Sets the spawn location of the world
|
||||||
|
*
|
||||||
|
* @param location Location of the spawn
|
||||||
|
* @return True if it was successfully set.
|
||||||
|
*/
|
||||||
|
public boolean setSpawnLocation(Location location);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the relative in-game time of this world.
|
* Gets the relative in-game time of this world.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -29,6 +29,12 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.22</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-all</artifactId>
|
<artifactId>netty-all</artifactId>
|
||||||
|
@ -105,18 +111,23 @@
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<version>1.10.19</version>
|
<version>1.10.19</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>it.unimi.dsi</groupId>
|
||||||
|
<artifactId>fastutil</artifactId>
|
||||||
|
<version>8.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.jafama</groupId>
|
||||||
|
<artifactId>jafama</artifactId>
|
||||||
|
<version>2.3.2</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>hamcrest-library</artifactId>
|
<artifactId>hamcrest-library</artifactId>
|
||||||
<version>1.3</version>
|
<version>1.3</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.18.20</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.velocitypowered</groupId>
|
<groupId>com.velocitypowered</groupId>
|
||||||
<artifactId>velocity-native</artifactId>
|
<artifactId>velocity-native</artifactId>
|
||||||
|
@ -228,7 +239,7 @@
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Gotta go after shade plugin -->
|
<!-- Gotta go after shade plugin -->
|
||||||
<plugin>
|
<!-- <plugin>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>specialsource-maven-plugin</artifactId>
|
<artifactId>specialsource-maven-plugin</artifactId>
|
||||||
<version>1.2.1</version>
|
<version>1.2.1</version>
|
||||||
|
@ -244,15 +255,13 @@
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>-->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<!-- versions after this appear to be broken -->
|
<!-- versions after this appear to be broken -->
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- we use the Eclipse compiler as it doesn't need a JDK -->
|
|
||||||
<compilerId>eclipse</compilerId>
|
|
||||||
<!-- source and target are ignored if this isn't true -->
|
<!-- source and target are ignored if this isn't true -->
|
||||||
<optimize>true</optimize>
|
<optimize>true</optimize>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.elevatemc.spigot.chunk;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.server.NibbleArray;
|
||||||
|
|
||||||
|
public class ChunkSectionSnapshot {
|
||||||
|
|
||||||
|
private final int nonEmptyBlockCount;
|
||||||
|
private final int tickingBlockCount;
|
||||||
|
private final char[] blockIds;
|
||||||
|
private final NibbleArray emittedLight;
|
||||||
|
private final NibbleArray skyLight;
|
||||||
|
|
||||||
|
public ChunkSectionSnapshot(
|
||||||
|
int nonEmptyBlockCount,
|
||||||
|
int tickingBlockCount,
|
||||||
|
char[] blockIds,
|
||||||
|
NibbleArray emittedLight,
|
||||||
|
NibbleArray skyLight
|
||||||
|
) {
|
||||||
|
this.nonEmptyBlockCount = nonEmptyBlockCount;
|
||||||
|
this.tickingBlockCount = tickingBlockCount;
|
||||||
|
this.blockIds = blockIds;
|
||||||
|
this.emittedLight = emittedLight;
|
||||||
|
this.skyLight = skyLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getNonEmptyBlockCount() {
|
||||||
|
return nonEmptyBlockCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getTickingBlockCount() {
|
||||||
|
return tickingBlockCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final char[] getBlockIds() {
|
||||||
|
return blockIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final NibbleArray getEmittedLight() {
|
||||||
|
return emittedLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final NibbleArray getSkyLight() {
|
||||||
|
return skyLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.elevatemc.spigot.chunk;
|
||||||
|
|
||||||
|
import net.minecraft.server.NBTTagCompound;
|
||||||
|
import net.techcable.tacospigot.event.entity.ChunkSnapshot;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CraftChunkSnapshot implements ChunkSnapshot {
|
||||||
|
|
||||||
|
private final ChunkSectionSnapshot[] sections = new ChunkSectionSnapshot[16];
|
||||||
|
private final List<NBTTagCompound> tileEntities = new ArrayList<>();
|
||||||
|
|
||||||
|
public ChunkSectionSnapshot[] getSections() {
|
||||||
|
return this.sections;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NBTTagCompound> getTileEntities() {
|
||||||
|
return this.tileEntities;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
package com.elevatemc.spigot.chunk;
|
||||||
|
|
||||||
|
import net.minecraft.server.*;
|
||||||
|
|
||||||
|
public class WeakChunkCache implements IBlockAccess {
|
||||||
|
|
||||||
|
private final int lowerChunkX;
|
||||||
|
private final int lowerChunkZ;
|
||||||
|
private final Chunk[][] chunks;
|
||||||
|
private boolean ownArray = false;
|
||||||
|
|
||||||
|
public WeakChunkCache(Chunk[][] chunks, int lowerChunkX, int lowerChunkZ) {
|
||||||
|
this.chunks = chunks;
|
||||||
|
this.lowerChunkX = lowerChunkX;
|
||||||
|
this.lowerChunkZ = lowerChunkZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeakChunkCache(World world, int chunkX, int chunkZ, int chunkRadius) {
|
||||||
|
this(world, chunkX - chunkRadius, chunkZ - chunkRadius, chunkX + chunkRadius, chunkZ + chunkRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeakChunkCache(World world, int lowerChunkX, int lowerChunkZ, int upperChunkX, int upperChunkZ) {
|
||||||
|
this.lowerChunkX = lowerChunkX;
|
||||||
|
this.lowerChunkZ = lowerChunkZ;
|
||||||
|
|
||||||
|
this.chunks = new Chunk[upperChunkX - this.lowerChunkX + 1][upperChunkZ - this.lowerChunkZ + 1];
|
||||||
|
this.ownArray = true;
|
||||||
|
|
||||||
|
for (int chunkX = this.lowerChunkX; chunkX <= upperChunkX; ++chunkX) {
|
||||||
|
for (int chunkZ = this.lowerChunkZ; chunkZ <= upperChunkZ; ++chunkZ) {
|
||||||
|
this.chunks[chunkX - this.lowerChunkX][chunkZ - this.lowerChunkZ] = world.getChunkIfLoaded(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeakChunkCache(World world, int lowerBlockX, int lowerBlockY, int lowerBlockZ, int upperBlockX, int upperBlockY, int upperBlockZ, int blockRadius) {
|
||||||
|
this(world, (lowerBlockX - blockRadius) >> 4,
|
||||||
|
(lowerBlockZ - blockRadius) >> 4,
|
||||||
|
(upperBlockX + blockRadius) >> 4,
|
||||||
|
(upperBlockZ + blockRadius) >> 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBlockData getData(BlockPosition blockPosition) {
|
||||||
|
if (blockPosition.getY() >= 0 && blockPosition.getY() < 256) {
|
||||||
|
int indexX = (blockPosition.getX() >> 4) - this.lowerChunkX;
|
||||||
|
int indexZ = (blockPosition.getZ() >> 4) - this.lowerChunkZ;
|
||||||
|
if (indexX >= 0 && indexX < this.chunks.length && indexZ >= 0 && indexZ < this.chunks[indexX].length) {
|
||||||
|
Chunk chunk = this.chunks[indexX][indexZ];
|
||||||
|
if (chunk != null) {
|
||||||
|
return chunk.getBlockData(blockPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLoaded(int x, int y, int z) {
|
||||||
|
int indexX = (x >> 4) - this.lowerChunkX;
|
||||||
|
int indexZ = (z >> 4) - this.lowerChunkZ;
|
||||||
|
if (indexX >= 0 && indexX < this.chunks.length && indexZ >= 0 && indexZ < this.chunks[indexX].length) {
|
||||||
|
return this.chunks[indexX][indexZ] != null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
if(this.ownArray) {
|
||||||
|
for(int i = 0; i < this.chunks.length; i++) {
|
||||||
|
for(int j = 0; j < this.chunks[i].length; j++) {
|
||||||
|
this.chunks[i][j] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity getTileEntity(BlockPosition blockPosition) {
|
||||||
|
int indexX = (blockPosition.getX() >> 4) - this.lowerChunkX;
|
||||||
|
int indexZ = (blockPosition.getZ() >> 4) - this.lowerChunkZ;
|
||||||
|
|
||||||
|
Chunk chunk = this.chunks[indexX][indexZ];
|
||||||
|
if (chunk != null) {
|
||||||
|
return chunk.i(blockPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockData getType(BlockPosition blockPosition) {
|
||||||
|
Block block = Blocks.AIR;
|
||||||
|
|
||||||
|
if (blockPosition.getY() >= 0 && blockPosition.getY() < 256) {
|
||||||
|
int indexX = (blockPosition.getX() >> 4) - this.lowerChunkX;
|
||||||
|
int indexZ = (blockPosition.getZ() >> 4) - this.lowerChunkZ;
|
||||||
|
|
||||||
|
if (indexX >= 0 && indexX < this.chunks.length && indexZ >= 0 && indexZ < this.chunks[indexX].length) {
|
||||||
|
Chunk chunk = this.chunks[indexX][indexZ];
|
||||||
|
if (chunk != null) {
|
||||||
|
block = chunk.getType(blockPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return block.getBlockData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty(BlockPosition blockPosition) {
|
||||||
|
return getType(blockPosition) != Blocks.AIR.getBlockData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockPower(BlockPosition blockposition, EnumDirection enumdirection) {
|
||||||
|
IBlockData iblockdata = this.getType(blockposition);
|
||||||
|
return iblockdata.getBlock().b(this, blockposition, iblockdata, enumdirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import java.lang.management.ManagementFactory;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
|
|
||||||
public class TicksPerSecondCommand extends Command {
|
public class TicksPerSecondCommand extends Command {
|
||||||
|
|
||||||
public TicksPerSecondCommand() {
|
public TicksPerSecondCommand() {
|
||||||
|
|
|
@ -2,18 +2,26 @@ package com.elevatemc.spigot;
|
||||||
|
|
||||||
import com.elevatemc.spigot.command.KnockbackCommand;
|
import com.elevatemc.spigot.command.KnockbackCommand;
|
||||||
import com.elevatemc.spigot.command.TicksPerSecondCommand;
|
import com.elevatemc.spigot.command.TicksPerSecondCommand;
|
||||||
|
import com.elevatemc.spigot.handler.MovementHandler;
|
||||||
|
import com.elevatemc.spigot.handler.PacketHandler;
|
||||||
import com.elevatemc.spigot.util.YamlConfig;
|
import com.elevatemc.spigot.util.YamlConfig;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import com.elevatemc.spigot.knockback.KnockbackHandler;
|
import com.elevatemc.spigot.knockback.KnockbackHandler;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class eSpigot {
|
public class eSpigot {
|
||||||
|
|
||||||
|
|
||||||
|
private final Set<PacketHandler> packetHandlers = new HashSet<>();
|
||||||
|
private final Set<MovementHandler> movementHandlers = new HashSet<>();
|
||||||
public static final ScheduledExecutorService EXECUTOR_SERVICE =
|
public static final ScheduledExecutorService EXECUTOR_SERVICE =
|
||||||
Executors.newSingleThreadScheduledExecutor();
|
Executors.newSingleThreadScheduledExecutor();
|
||||||
|
|
||||||
|
@ -45,6 +53,25 @@ public class eSpigot {
|
||||||
EXECUTOR_SERVICE.scheduleAtFixedRate(() -> MinecraftServer.getServer().aq().processFastPackets(), 5L, 5L, TimeUnit.MILLISECONDS);
|
EXECUTOR_SERVICE.scheduleAtFixedRate(() -> MinecraftServer.getServer().aq().processFastPackets(), 5L, 5L, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addPacketHandler(PacketHandler handler) {
|
||||||
|
Bukkit.getLogger().info("Adding packet handler: " + handler.getClass().getPackage().getName() + "." + handler.getClass().getSimpleName());
|
||||||
|
this.packetHandlers.add(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMovementHandler(MovementHandler handler) {
|
||||||
|
Bukkit.getLogger().info("Adding movement handler: " + handler.getClass().getPackage().getName() + "." + handler.getClass().getSimpleName());
|
||||||
|
this.movementHandlers.add(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<MovementHandler> getMovementHandlers() {
|
||||||
|
return this.movementHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<PacketHandler> getPacketHandlers() {
|
||||||
|
return this.packetHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public YamlConfig getConfig() {
|
public YamlConfig getConfig() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.elevatemc.spigot.event;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Item;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BlockDropItemsEvent extends Event implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private Block block;
|
||||||
|
private Player player;
|
||||||
|
private List<Item> toDrop;
|
||||||
|
private boolean cancelled = false;
|
||||||
|
|
||||||
|
public BlockDropItemsEvent(Block block, Player player, List<Item> toDrop) {
|
||||||
|
this.block = block;
|
||||||
|
this.player = player;
|
||||||
|
this.toDrop = toDrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlock() {
|
||||||
|
return this.block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return this.player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Item> getToDrop() {
|
||||||
|
return this.toDrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return this.cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.elevatemc.spigot.event;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.player.PlayerEvent;
|
||||||
|
|
||||||
|
public class PlayerHealthChangeEvent extends PlayerEvent {
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
|
private final double previousHealth;
|
||||||
|
private final double newHealth;
|
||||||
|
|
||||||
|
public PlayerHealthChangeEvent(Player who, double previousHealth, double newHealth) {
|
||||||
|
super(who);
|
||||||
|
|
||||||
|
this.previousHealth = previousHealth;
|
||||||
|
this.newHealth = newHealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPreviousHealth() {
|
||||||
|
return previousHealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getNewHealth() {
|
||||||
|
return newHealth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.elevatemc.spigot.event;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.player.PlayerEvent;
|
||||||
|
|
||||||
|
public class PlayerPearlRefundEvent extends PlayerEvent {
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
|
public PlayerPearlRefundEvent(final Player player) {
|
||||||
|
super(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.elevatemc.spigot.handler;
|
||||||
|
|
||||||
|
import net.minecraft.server.PacketPlayInFlying;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public interface MovementHandler {
|
||||||
|
|
||||||
|
void handleUpdateLocation(Player player, Location to, Location from, PacketPlayInFlying packet);
|
||||||
|
|
||||||
|
void handleUpdateRotation(Player player, Location to, Location from, PacketPlayInFlying packet);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.elevatemc.spigot.handler;
|
||||||
|
|
||||||
|
import net.minecraft.server.Packet;
|
||||||
|
import net.minecraft.server.PlayerConnection;
|
||||||
|
|
||||||
|
public interface PacketHandler {
|
||||||
|
|
||||||
|
default void handleReceivedPacket(PlayerConnection connection, Packet<?> packet) {}
|
||||||
|
|
||||||
|
default void handleSentPacket(PlayerConnection connection, Packet<?> packet) {}
|
||||||
|
|
||||||
|
default boolean handleSentPacketCancellable(PlayerConnection connection, Packet<?> packet) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntry;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntryEntity;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntryPosition;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJob;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobNavigationEntity;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobNavigationPosition;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchQueuingManager;
|
||||||
|
import net.minecraft.server.*;
|
||||||
|
import org.bukkit.util.BlockVector;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class AsyncNavigation extends Navigation {
|
||||||
|
|
||||||
|
private HashMap<UUID, SearchCacheEntry> searchCache;
|
||||||
|
private HashMap<PositionPathSearchType, SearchCacheEntryPosition> positionSearchCache;
|
||||||
|
private static double minimumDistanceForOffloadingSquared = 0.0D;
|
||||||
|
private int cleanUpDelay = 0;
|
||||||
|
private PathSearchQueuingManager queuingManager;
|
||||||
|
|
||||||
|
public AsyncNavigation(EntityInsentient entityInsentient, World world) {
|
||||||
|
super(entityInsentient, world);
|
||||||
|
|
||||||
|
this.searchCache = new HashMap<>();
|
||||||
|
this.positionSearchCache = new HashMap<>();
|
||||||
|
this.queuingManager = new PathSearchQueuingManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockVector createBlockVectorForPosition(int x, int y, int z) {
|
||||||
|
return new BlockVector(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void issueSearch(Entity target, float range, boolean j, boolean k, boolean l, boolean m) {
|
||||||
|
this.queuingManager.queueSearch(new PathSearchJobNavigationEntity(this.b, target, range, j, k, l, m));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void issueSearch(PositionPathSearchType type, BlockPosition blockPosition, float range, boolean j, boolean k, boolean l, boolean m) {
|
||||||
|
this.queuingManager.queueSearch(new PathSearchJobNavigationPosition(type, this.b, blockPosition, range, j, k, l, m));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelSearch(PathSearchJob pathSearch) {
|
||||||
|
this.queuingManager.checkLastSearchResult(pathSearch);
|
||||||
|
pathSearch.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSearchResult(PathSearchJobNavigationEntity pathSearch) {
|
||||||
|
this.queuingManager.checkLastSearchResult(pathSearch);
|
||||||
|
SearchCacheEntry entry = pathSearch.getCacheEntryValue();
|
||||||
|
if (entry != null && entry.didSearchSucceed()) {
|
||||||
|
synchronized (this.searchCache) {
|
||||||
|
UUID key = pathSearch.getCacheEntryKey();
|
||||||
|
this.searchCache.put(key, entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSearchResult(PathSearchJobNavigationPosition pathSearch) {
|
||||||
|
this.queuingManager.checkLastSearchResult(pathSearch);
|
||||||
|
SearchCacheEntryPosition entry = pathSearch.getCacheEntryValue();
|
||||||
|
if (entry != null && entry.didSearchSucceed()) {
|
||||||
|
synchronized (this.positionSearchCache) {
|
||||||
|
PositionPathSearchType key = pathSearch.getCacheEntryKey();
|
||||||
|
this.positionSearchCache.put(key, entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathEntity a(BlockPosition blockPosition) {
|
||||||
|
return this.a(PositionPathSearchType.ANYOTHER, blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean a(PositionPathSearchType type, double d0, double d1, double d2, double d3) {
|
||||||
|
PathEntity pathentity = this.a(type, (double) MathHelper.floor(d0), (double) ((int) d1), (double) MathHelper.floor(d2));
|
||||||
|
return this.a(pathentity, d3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathEntity a(Entity entity) {
|
||||||
|
if (!this.offloadSearches() || this.b.h(entity) < minimumDistanceForOffloadingSquared) {
|
||||||
|
return super.a(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.b()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchCacheEntry entry = null;
|
||||||
|
UUID id = entity.getUniqueID();
|
||||||
|
synchronized (this.searchCache) {
|
||||||
|
if (this.searchCache.containsKey(id)) {
|
||||||
|
entry = this.searchCache.get(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PathEntity resultPath = null;
|
||||||
|
if (entry != null) {
|
||||||
|
resultPath = entry.getAdjustedPathEntity();
|
||||||
|
if (!entry.isStillValid()) {
|
||||||
|
this.issueSearch(entity, this.i(), this.a.getB(), this.a.getC(), this.a.getD(), this.a.getE());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entry == null && !this.queuingManager.hasAsyncSearchIssued()) {
|
||||||
|
resultPath = super.a(entity);
|
||||||
|
if (resultPath != null) {
|
||||||
|
entry = new SearchCacheEntryEntity(this.b, entity, resultPath);
|
||||||
|
synchronized (this.searchCache) {
|
||||||
|
SearchCacheEntry oldEntry = this.searchCache.put(id, entry);
|
||||||
|
if (oldEntry != null) {
|
||||||
|
oldEntry.cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathEntity a(PositionPathSearchType type, double d0, double d1, double d2) {
|
||||||
|
if (!this.offloadSearches() || this.b.e(d0, d1, d2) < minimumDistanceForOffloadingSquared) {
|
||||||
|
return super.a(d0, d1, d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.b()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = MathHelper.floor(d0);
|
||||||
|
int y = (int) d1;
|
||||||
|
int z = MathHelper.floor(d2);
|
||||||
|
|
||||||
|
SearchCacheEntryPosition entry = null;
|
||||||
|
synchronized (this.positionSearchCache) {
|
||||||
|
if (this.positionSearchCache.containsKey(type)) {
|
||||||
|
entry = this.positionSearchCache.get(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PathEntity resultPath = null;
|
||||||
|
if (entry != null) {
|
||||||
|
resultPath = entry.getAdjustedPathEntity();
|
||||||
|
if (!entry.isStillValid()) {
|
||||||
|
this.issueSearch(type, new BlockPosition(x, y, z), this.i(), this.a.getB(), this.a.getC(), this.a.getD(), this.a.getE());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry == null && !this.queuingManager.hasAsyncSearchIssued()) {
|
||||||
|
resultPath = super.a(d0, d1, d2);
|
||||||
|
if (resultPath != null) {
|
||||||
|
entry = new SearchCacheEntryPosition(this.b, x, y, z, resultPath);
|
||||||
|
synchronized (this.positionSearchCache) {
|
||||||
|
SearchCacheEntry oldEntry = this.positionSearchCache.put(type, entry);
|
||||||
|
if (oldEntry != null) {
|
||||||
|
oldEntry.cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanUpExpiredSearches() {
|
||||||
|
if (++this.cleanUpDelay > 100) {
|
||||||
|
this.cleanUpDelay = 0;
|
||||||
|
synchronized (this.searchCache) {
|
||||||
|
Iterator<Map.Entry<UUID, SearchCacheEntry>> iter = this.searchCache.entrySet().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Map.Entry<UUID, SearchCacheEntry> entry = iter.next();
|
||||||
|
if (entry.getValue().hasExpired()) {
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
synchronized (this.positionSearchCache) {
|
||||||
|
Iterator<Map.Entry<PositionPathSearchType, SearchCacheEntryPosition>> iter2 = this.positionSearchCache.entrySet().iterator();
|
||||||
|
while (iter2.hasNext()) {
|
||||||
|
Map.Entry<PositionPathSearchType, SearchCacheEntryPosition> entry = iter2.next();
|
||||||
|
if (entry.getValue().hasExpired()) {
|
||||||
|
iter2.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean offloadSearches() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch;
|
||||||
|
|
||||||
|
import net.minecraft.server.*;
|
||||||
|
|
||||||
|
public class AsyncPathfinder extends Pathfinder {
|
||||||
|
|
||||||
|
private IBlockAccess iblockaccess;
|
||||||
|
|
||||||
|
public AsyncPathfinder(IBlockAccess iblockaccess) {
|
||||||
|
super(new AsyncPathfinderNormal(iblockaccess));
|
||||||
|
|
||||||
|
this.iblockaccess = iblockaccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathEntity a(IBlockAccess var1, Entity var2, Entity var3, float var4) {
|
||||||
|
return super.a(iblockaccess, var2, var3, var4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathEntity a(IBlockAccess var1, Entity var2, BlockPosition var3, float var4) {
|
||||||
|
return super.a(iblockaccess, var2, var3, var4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch;
|
||||||
|
|
||||||
|
import net.minecraft.server.Entity;
|
||||||
|
import net.minecraft.server.IBlockAccess;
|
||||||
|
import net.minecraft.server.PathfinderNormal;
|
||||||
|
|
||||||
|
public class AsyncPathfinderNormal extends PathfinderNormal {
|
||||||
|
|
||||||
|
private IBlockAccess iblockaccess;
|
||||||
|
|
||||||
|
public AsyncPathfinderNormal(IBlockAccess iblockaccess) {
|
||||||
|
this.iblockaccess = iblockaccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void a(IBlockAccess iblockaccess, Entity entity) {
|
||||||
|
super.a(this.iblockaccess, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJob;
|
||||||
|
import com.elevatemc.spigot.threading.NamePriorityThreadFactory;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
public class PathSearchThrottlerThread extends ThreadPoolExecutor {
|
||||||
|
|
||||||
|
private int queueLimit;
|
||||||
|
private LinkedHashMap<PathSearchJob, PathSearchJob> filter;
|
||||||
|
private HashSet<Integer> activeSearchHashes;
|
||||||
|
private static PathSearchThrottlerThread instance;
|
||||||
|
|
||||||
|
public PathSearchThrottlerThread(int poolSize) {
|
||||||
|
super(poolSize, poolSize, 1L, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(), new NamePriorityThreadFactory(Thread.MIN_PRIORITY, "eSpigot_PathFinder"));
|
||||||
|
instance = this;
|
||||||
|
adjustPoolSize(poolSize);
|
||||||
|
this.filter = new LinkedHashMap<>();
|
||||||
|
this.activeSearchHashes = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean queuePathSearch(PathSearchJob newJob) {
|
||||||
|
boolean jobHasBeenQueued = false;
|
||||||
|
if(newJob != null) {
|
||||||
|
synchronized(this.filter) {
|
||||||
|
if(this.filter.containsKey(newJob) || this.filter.size() < 1000) {
|
||||||
|
jobHasBeenQueued = true;
|
||||||
|
PathSearchJob previousJob = this.filter.put(newJob, newJob);
|
||||||
|
if(previousJob != null) {
|
||||||
|
previousJob.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!jobHasBeenQueued) {
|
||||||
|
newJob.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PathSearchJob jobToExecute = null;
|
||||||
|
synchronized(this.filter) {
|
||||||
|
Iterator<Map.Entry<PathSearchJob, PathSearchJob>> iter = this.filter.entrySet().iterator();
|
||||||
|
while(iter.hasNext() && this.getQueue().size() < this.queueLimit) {
|
||||||
|
jobToExecute = iter.next().getValue();
|
||||||
|
if(!this.activeSearchHashes.contains(jobToExecute.getSearchHash())) {
|
||||||
|
iter.remove();
|
||||||
|
if(jobToExecute != null) {
|
||||||
|
this.activeSearchHashes.add(jobToExecute.getSearchHash());
|
||||||
|
this.submit(jobToExecute);
|
||||||
|
}
|
||||||
|
if(newJob != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jobHasBeenQueued;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() {
|
||||||
|
this.getQueue().clear();
|
||||||
|
super.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterExecute(Runnable runnable, Throwable throwable) {
|
||||||
|
super.afterExecute(runnable, throwable);
|
||||||
|
if(runnable instanceof FutureTask) {
|
||||||
|
FutureTask<PathSearchJob> task = (FutureTask<PathSearchJob>) runnable;
|
||||||
|
PathSearchJob job = null;
|
||||||
|
try {
|
||||||
|
job = task.get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
}
|
||||||
|
if(job != null) {
|
||||||
|
synchronized(this.filter) {
|
||||||
|
this.activeSearchHashes.remove(job.getSearchHash());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.queuePathSearch(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void adjustPoolSize(int size) {
|
||||||
|
if(instance != null) {
|
||||||
|
if(size > instance.getMaximumPoolSize()) {
|
||||||
|
instance.setMaximumPoolSize(size);
|
||||||
|
instance.setCorePoolSize(size);
|
||||||
|
} else if(size < instance.getMaximumPoolSize()) {
|
||||||
|
instance.setCorePoolSize(size);
|
||||||
|
instance.setMaximumPoolSize(size);
|
||||||
|
}
|
||||||
|
instance.queueLimit = size * 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch;
|
||||||
|
|
||||||
|
|
||||||
|
public enum PositionPathSearchType {
|
||||||
|
|
||||||
|
ANYOTHER,
|
||||||
|
AVOIDPLAYER,
|
||||||
|
FLEESUN,
|
||||||
|
JUMPONBLOCK,
|
||||||
|
MOVEINDOORS,
|
||||||
|
MOVETHROUGHVILLAGE,
|
||||||
|
MOVETOWARDSRESTRICTION,
|
||||||
|
MOVETOWARDSTARGET,
|
||||||
|
PANIC,
|
||||||
|
PLAY,
|
||||||
|
RANDOMSTROLL,
|
||||||
|
TAME;
|
||||||
|
}
|
78
TacoSpigot-Server/src/main/java/com/elevatemc/spigot/pathsearch/cache/SearchCacheEntry.java
vendored
Normal file
78
TacoSpigot-Server/src/main/java/com/elevatemc/spigot/pathsearch/cache/SearchCacheEntry.java
vendored
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch.cache;
|
||||||
|
|
||||||
|
import net.minecraft.server.*;
|
||||||
|
import org.bukkit.util.BlockVector;
|
||||||
|
|
||||||
|
public class SearchCacheEntry {
|
||||||
|
|
||||||
|
protected long tick;
|
||||||
|
protected BlockVector positionStart;
|
||||||
|
protected BlockVector positionTarget;
|
||||||
|
protected EntityInsentient entity;
|
||||||
|
private PathEntity path;
|
||||||
|
|
||||||
|
public SearchCacheEntry(EntityInsentient entity, PathEntity path) {
|
||||||
|
this.entity = entity;
|
||||||
|
this.positionStart = this.getEntityPosition(this.entity);
|
||||||
|
this.path = path;
|
||||||
|
this.tick = this.getCurrentTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getCurrentTick() {
|
||||||
|
return MinecraftServer.currentTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BlockVector getEntityPosition(Entity entity) {
|
||||||
|
return new BlockVector(entity.locX, entity.locY, entity.locZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BlockVector getTargetPosition(int x, int y, int z) {
|
||||||
|
return new BlockVector(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStillValid() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathEntity getPathEntity() {
|
||||||
|
return this.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasExpired() {
|
||||||
|
return !this.entity.isAlive() || (this.getCurrentTick() - this.tick) > 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean didSearchSucceed() {
|
||||||
|
return this.path != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldBeRefreshed() {
|
||||||
|
return (this.getCurrentTick() - this.tick) > 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathEntity getAdjustedPathEntity() {
|
||||||
|
if(this.path != null && (this.path.e() < this.path.d() - 1)) {
|
||||||
|
PathPoint pathpoint = this.path.a(this.path.e());
|
||||||
|
double currentDist = this.entity.e(pathpoint.a, pathpoint.b, pathpoint.c);
|
||||||
|
while(this.path.e() < this.path.d() - 1) {
|
||||||
|
pathpoint = this.path.a(this.path.e() + 1);
|
||||||
|
double nextDist = this.entity.e(pathpoint.a, pathpoint.b, pathpoint.c);
|
||||||
|
if(nextDist < currentDist) {
|
||||||
|
currentDist = nextDist;
|
||||||
|
this.path.a();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
this.positionStart = null;
|
||||||
|
this.positionTarget = null;
|
||||||
|
this.entity = null;
|
||||||
|
this.path = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch.cache;
|
||||||
|
|
||||||
|
import net.minecraft.server.Entity;
|
||||||
|
import net.minecraft.server.EntityInsentient;
|
||||||
|
import net.minecraft.server.PathEntity;
|
||||||
|
import org.bukkit.util.BlockVector;
|
||||||
|
|
||||||
|
public class SearchCacheEntryEntity extends SearchCacheEntry {
|
||||||
|
|
||||||
|
private Entity target;
|
||||||
|
|
||||||
|
public SearchCacheEntryEntity(EntityInsentient entity, Entity target, PathEntity path) {
|
||||||
|
super(entity, path);
|
||||||
|
|
||||||
|
this.target = target;
|
||||||
|
this.positionTarget = this.getEntityPosition(this.target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStillValid() {
|
||||||
|
if (this.getCurrentTick() - this.tick > 20) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockVector bvStart = this.getEntityPosition(this.entity);
|
||||||
|
BlockVector bvTarget = this.getEntityPosition(this.target);
|
||||||
|
|
||||||
|
return bvStart.equals(this.positionStart) && bvTarget.equals(this.positionTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanup() {
|
||||||
|
super.cleanup();
|
||||||
|
|
||||||
|
this.target = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch.cache;
|
||||||
|
|
||||||
|
import net.minecraft.server.EntityInsentient;
|
||||||
|
import net.minecraft.server.PathEntity;
|
||||||
|
import org.bukkit.util.BlockVector;
|
||||||
|
|
||||||
|
public class SearchCacheEntryPosition extends SearchCacheEntry {
|
||||||
|
|
||||||
|
public SearchCacheEntryPosition(EntityInsentient entity, int x, int y, int z, PathEntity path) {
|
||||||
|
super(entity, path);
|
||||||
|
|
||||||
|
this.positionTarget = this.getTargetPosition(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStillValid() {
|
||||||
|
if (this.getCurrentTick() - this.tick > 20) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockVector bvStart = this.getEntityPosition(this.entity);
|
||||||
|
return bvStart.equals(this.positionStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean targetEquals(BlockVector bv) {
|
||||||
|
return this.positionTarget.equals(bv);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch.jobs;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.chunk.WeakChunkCache;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntry;
|
||||||
|
import net.minecraft.server.EntityInsentient;
|
||||||
|
import net.minecraft.server.MathHelper;
|
||||||
|
import net.minecraft.server.PathEntity;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public abstract class PathSearchJob implements Callable<PathSearchJob> {
|
||||||
|
|
||||||
|
protected EntityInsentient entity;
|
||||||
|
protected WeakChunkCache chunkCache;
|
||||||
|
protected boolean issued;
|
||||||
|
protected float range;
|
||||||
|
protected boolean b1, b2, b3, b4;
|
||||||
|
protected PathEntity pathEntity;
|
||||||
|
protected int hash;
|
||||||
|
|
||||||
|
public PathSearchJob(EntityInsentient entity, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
||||||
|
this.entity = entity;
|
||||||
|
this.range = range;
|
||||||
|
this.b1 = b1;
|
||||||
|
this.b2 = b2;
|
||||||
|
this.b3 = b3;
|
||||||
|
this.b4 = b4;
|
||||||
|
this.issued = false;
|
||||||
|
this.hash = entity.getUniqueID().hashCode();
|
||||||
|
this.createChunkCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createChunkCache() {
|
||||||
|
int x = MathHelper.floor(this.entity.locX);
|
||||||
|
int y = MathHelper.floor(this.entity.locY);
|
||||||
|
int z = MathHelper.floor(this.entity.locZ);
|
||||||
|
int radius = (int) (this.range + 8.0F);
|
||||||
|
int xMinor = x - radius;
|
||||||
|
int yMinor = y - radius;
|
||||||
|
int zMinor = z - radius;
|
||||||
|
int xMajor = x + radius;
|
||||||
|
int yMajor = y + radius;
|
||||||
|
int zMajor = z + radius;
|
||||||
|
this.chunkCache = new WeakChunkCache(this.entity.world, xMinor, yMinor, zMinor, xMajor, yMajor, zMajor, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
this.entity = null;
|
||||||
|
this.chunkCache = null;
|
||||||
|
this.pathEntity = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSearchHash() {
|
||||||
|
return this.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Object getCacheEntryKey();
|
||||||
|
|
||||||
|
public abstract SearchCacheEntry getCacheEntryValue();
|
||||||
|
|
||||||
|
public abstract void cancel();
|
||||||
|
|
||||||
|
protected boolean isEntityStillValid() {
|
||||||
|
return this.entity != null && this.entity.valid && this.entity.isAlive();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch.jobs;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.pathsearch.AsyncPathfinder;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntry;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntryEntity;
|
||||||
|
import net.minecraft.server.Entity;
|
||||||
|
import net.minecraft.server.EntityCreature;
|
||||||
|
|
||||||
|
public class PathSearchJobEntity extends PathSearchJob {
|
||||||
|
|
||||||
|
private Entity target;
|
||||||
|
|
||||||
|
public PathSearchJobEntity(EntityCreature entity, Entity target, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
||||||
|
super(entity, range, b1, b2, b3, b4);
|
||||||
|
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathSearchJob call() throws Exception {
|
||||||
|
if(!this.isEntityStillValid()) {
|
||||||
|
this.cancel();
|
||||||
|
} else if(!this.issued) {
|
||||||
|
this.issued = true;
|
||||||
|
this.pathEntity = (new AsyncPathfinder(this.chunkCache)).a(this.chunkCache, entity, this.target, this.range);
|
||||||
|
((EntityCreature) this.entity).setSearchResult(this, this.target, this.pathEntity);
|
||||||
|
this.cleanup();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanup() {
|
||||||
|
super.cleanup();
|
||||||
|
this.target = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCacheEntryKey() {
|
||||||
|
return this.entity.getUniqueID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SearchCacheEntry getCacheEntryValue() {
|
||||||
|
return new SearchCacheEntryEntity(this.entity, this.target, this.pathEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
((EntityCreature) this.entity).cancelSearch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof PathSearchJobEntity)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getSearchHash() == ((PathSearchJobEntity)o).getSearchHash();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch.jobs;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.pathsearch.AsyncPathfinder;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntry;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntryEntity;
|
||||||
|
import net.minecraft.server.Entity;
|
||||||
|
import net.minecraft.server.EntityInsentient;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PathSearchJobNavigationEntity extends PathSearchJob {
|
||||||
|
|
||||||
|
private Entity target;
|
||||||
|
|
||||||
|
public PathSearchJobNavigationEntity(EntityInsentient entity, Entity target, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
||||||
|
super(entity, range, b1, b2, b3, b4);
|
||||||
|
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathSearchJob call() throws Exception {
|
||||||
|
if (!this.isEntityStillValid()) {
|
||||||
|
this.cancel();
|
||||||
|
} else if (!this.issued) {
|
||||||
|
this.issued = true;
|
||||||
|
this.pathEntity = (new AsyncPathfinder(this.chunkCache)).a(this.chunkCache, entity, this.target, this.range);
|
||||||
|
this.entity.getNavigation().setSearchResult(this);
|
||||||
|
this.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanup() {
|
||||||
|
super.cleanup();
|
||||||
|
this.target = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getCacheEntryKey() {
|
||||||
|
return this.target.getUniqueID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchCacheEntry getCacheEntryValue() {
|
||||||
|
return new SearchCacheEntryEntity(this.entity, this.target, this.pathEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
this.entity.getNavigation().cancelSearch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null || !(o instanceof PathSearchJobNavigationEntity)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getSearchHash() == ((PathSearchJobNavigationEntity) o).getSearchHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch.jobs;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.pathsearch.AsyncPathfinder;
|
||||||
|
import com.elevatemc.spigot.pathsearch.PositionPathSearchType;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntryPosition;
|
||||||
|
import net.minecraft.server.BlockPosition;
|
||||||
|
import net.minecraft.server.EntityInsentient;
|
||||||
|
|
||||||
|
public class PathSearchJobNavigationPosition extends PathSearchJob {
|
||||||
|
|
||||||
|
private BlockPosition blockPosition;
|
||||||
|
private PositionPathSearchType type;
|
||||||
|
|
||||||
|
public PathSearchJobNavigationPosition(PositionPathSearchType type, EntityInsentient entity, BlockPosition blockPosition, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
||||||
|
super(entity, range, b1, b2, b3, b4);
|
||||||
|
|
||||||
|
this.type = type;
|
||||||
|
this.blockPosition = blockPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathSearchJob call() throws Exception {
|
||||||
|
if(!this.isEntityStillValid()) {
|
||||||
|
this.cancel();
|
||||||
|
} else if(!this.issued) {
|
||||||
|
this.issued = true;
|
||||||
|
this.pathEntity = (new AsyncPathfinder(this.chunkCache)).a(this.chunkCache, entity, blockPosition, range);
|
||||||
|
this.entity.getNavigation().setSearchResult(this);
|
||||||
|
this.cleanup();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionPathSearchType getCacheEntryKey() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchCacheEntryPosition getCacheEntryValue() {
|
||||||
|
return new SearchCacheEntryPosition(this.entity, blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), this.pathEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.type.hashCode() ^
|
||||||
|
(this.getSearchHash() << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if(o == null || !(o instanceof PathSearchJobNavigationPosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PathSearchJobNavigationPosition other = (PathSearchJobNavigationPosition) o;
|
||||||
|
|
||||||
|
return this.type.equals(
|
||||||
|
other.type) &&
|
||||||
|
this.getSearchHash() ==
|
||||||
|
other.getSearchHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
this.entity.getNavigation().cancelSearch(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch.jobs;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.pathsearch.AsyncPathfinder;
|
||||||
|
import com.elevatemc.spigot.pathsearch.PositionPathSearchType;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntry;
|
||||||
|
import com.elevatemc.spigot.pathsearch.cache.SearchCacheEntryPosition;
|
||||||
|
import net.minecraft.server.BlockPosition;
|
||||||
|
import net.minecraft.server.EntityCreature;
|
||||||
|
|
||||||
|
public class PathSearchJobPosition extends PathSearchJob {
|
||||||
|
|
||||||
|
private BlockPosition blockPosition;
|
||||||
|
private PositionPathSearchType type;
|
||||||
|
|
||||||
|
public PathSearchJobPosition(EntityCreature entity, BlockPosition blockPosition, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
||||||
|
super(entity, range, b1, b2, b3, b4);
|
||||||
|
|
||||||
|
this.type = PositionPathSearchType.ANYOTHER;
|
||||||
|
this.blockPosition = blockPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathSearchJob call() throws Exception {
|
||||||
|
if(!this.isEntityStillValid()) {
|
||||||
|
this.cancel();
|
||||||
|
} else if(!this.issued) {
|
||||||
|
this.issued = true;
|
||||||
|
this.pathEntity = (new AsyncPathfinder(this.chunkCache)).a(this.chunkCache, entity, blockPosition, range);
|
||||||
|
((EntityCreature)this.entity).setSearchResult(this, this.pathEntity);
|
||||||
|
this.cleanup();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCacheEntryKey() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SearchCacheEntry getCacheEntryValue() {
|
||||||
|
return new SearchCacheEntryPosition(this.entity, this.blockPosition.getX(), this.blockPosition.getY(), this.blockPosition.getZ(), this.pathEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.type.hashCode() ^ (this.getSearchHash() << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if(o == null || !(o instanceof PathSearchJobPosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PathSearchJobPosition other = (PathSearchJobPosition) o;
|
||||||
|
|
||||||
|
return this.type.equals(
|
||||||
|
other.type) &&
|
||||||
|
this.getSearchHash() == other.getSearchHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
((EntityCreature) this.entity).cancelSearch(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.elevatemc.spigot.pathsearch.jobs;
|
||||||
|
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.threading.ThreadingManager;
|
||||||
|
|
||||||
|
public class PathSearchQueuingManager {
|
||||||
|
|
||||||
|
private PathSearchJob lastQueuedJob;
|
||||||
|
|
||||||
|
public PathSearchQueuingManager() {
|
||||||
|
this.lastQueuedJob = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean hasAsyncSearchIssued() {
|
||||||
|
return this.lastQueuedJob != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void queueSearch(PathSearchJob job) {
|
||||||
|
if (ThreadingManager.queuePathSearch(job)) {
|
||||||
|
this.lastQueuedJob = job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void checkLastSearchResult(PathSearchJob pathSearch) {
|
||||||
|
if (this.lastQueuedJob == pathSearch) {
|
||||||
|
this.lastQueuedJob = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.elevatemc.spigot.threading;
|
||||||
|
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
|
||||||
|
public class NamePriorityThreadFactory implements ThreadFactory {
|
||||||
|
|
||||||
|
private final int priority;
|
||||||
|
private int idCounter = 0;
|
||||||
|
private String name = "gSpigotThread";
|
||||||
|
private boolean isDaemon = false;
|
||||||
|
private Queue<WeakReference<Thread>> createdThreadList;
|
||||||
|
|
||||||
|
public NamePriorityThreadFactory(int priority) {
|
||||||
|
this.priority = FastMath.min(FastMath.max(priority, Thread.MIN_PRIORITY), Thread.MAX_PRIORITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamePriorityThreadFactory(int priority, String name) {
|
||||||
|
this(priority);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamePriorityThreadFactory(String name) {
|
||||||
|
this(Thread.NORM_PRIORITY);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamePriorityThreadFactory setDaemon(boolean daemon) {
|
||||||
|
this.isDaemon = daemon;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamePriorityThreadFactory setLogThreads(boolean log) {
|
||||||
|
if (log) {
|
||||||
|
if (this.createdThreadList == null) {
|
||||||
|
this.createdThreadList = new ConcurrentLinkedQueue<WeakReference<Thread>>();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.createdThreadList = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable runnable) {
|
||||||
|
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
|
||||||
|
thread.setPriority(this.priority);
|
||||||
|
thread.setName(this.name + "-" + idCounter);
|
||||||
|
thread.setDaemon(this.isDaemon);
|
||||||
|
if (this.createdThreadList != null) {
|
||||||
|
this.createdThreadList.add(new WeakReference<>(thread));
|
||||||
|
}
|
||||||
|
idCounter++;
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getActiveCount() {
|
||||||
|
if (this.createdThreadList != null) {
|
||||||
|
Iterator<WeakReference<Thread>> iter = this.createdThreadList.iterator();
|
||||||
|
int count = 0;
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
WeakReference<Thread> ref = iter.next();
|
||||||
|
Thread t = ref.get();
|
||||||
|
if (t == null) {
|
||||||
|
iter.remove();
|
||||||
|
} else if (t.isAlive()) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Queue<WeakReference<Thread>> getThreadList() {
|
||||||
|
return this.createdThreadList;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,281 @@
|
||||||
|
package com.elevatemc.spigot.threading;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.pathsearch.PathSearchThrottlerThread;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJob;
|
||||||
|
import net.minecraft.server.NBTCompressedStreamTools;
|
||||||
|
import net.minecraft.server.NBTTagCompound;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class ThreadingManager {
|
||||||
|
|
||||||
|
private static ThreadingManager instance;
|
||||||
|
|
||||||
|
private final Logger log = LogManager.getLogger();
|
||||||
|
private PathSearchThrottlerThread pathSearchThrottler;
|
||||||
|
private ScheduledExecutorService timerService = Executors.newScheduledThreadPool(1, new NamePriorityThreadFactory(Thread.NORM_PRIORITY + 2, "eSpigot_TimerService"));
|
||||||
|
private TickCounter tickCounter = new TickCounter();
|
||||||
|
private NamePriorityThreadFactory cachedThreadPoolFactory;
|
||||||
|
private ExecutorService cachedThreadPool;
|
||||||
|
|
||||||
|
private ScheduledFuture<Object> tickTimerTask;
|
||||||
|
private TickTimer tickTimerObject;
|
||||||
|
private static int timerDelay = 45;
|
||||||
|
|
||||||
|
private TaskQueueWorker nbtFiles;
|
||||||
|
private TaskQueueWorker headConversions;
|
||||||
|
|
||||||
|
public ThreadingManager() {
|
||||||
|
instance = this;
|
||||||
|
this.pathSearchThrottler = new PathSearchThrottlerThread(2);
|
||||||
|
this.timerService.scheduleAtFixedRate(this.tickCounter, 1, 1000, TimeUnit.MILLISECONDS);
|
||||||
|
this.tickTimerObject = new TickTimer();
|
||||||
|
this.cachedThreadPoolFactory = new NamePriorityThreadFactory(Thread.currentThread().getPriority() - 1, "eSpigot_Async-Executor").setLogThreads(true).setDaemon(true);
|
||||||
|
this.cachedThreadPool = Executors.newCachedThreadPool(this.cachedThreadPoolFactory);
|
||||||
|
this.nbtFiles = this.createTaskQueueWorker();
|
||||||
|
this.headConversions = this.createTaskQueueWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown() {
|
||||||
|
this.pathSearchThrottler.shutdown();
|
||||||
|
this.timerService.shutdown();
|
||||||
|
this.cachedThreadPool.shutdown();
|
||||||
|
while((this.nbtFiles.isActive()) && !this.cachedThreadPool.isTerminated()) {
|
||||||
|
try {
|
||||||
|
this.cachedThreadPool.awaitTermination(10, TimeUnit.SECONDS);
|
||||||
|
log.warn("gSpigot is still waiting for NBT files to be written to disk. " + this.nbtFiles.getTaskCount() + " to go...");
|
||||||
|
} catch(InterruptedException e) {}
|
||||||
|
}
|
||||||
|
if(!this.cachedThreadPool.isTerminated()) {
|
||||||
|
this.cachedThreadPool.shutdownNow();
|
||||||
|
try {
|
||||||
|
this.cachedThreadPool.awaitTermination(10L, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if(this.cachedThreadPoolFactory.getActiveCount() > 0) {
|
||||||
|
log.warn("gSpigot is still waiting for " + this.cachedThreadPoolFactory.getActiveCount() + " async threads to finish.");
|
||||||
|
Queue<WeakReference<Thread>> queue = this.cachedThreadPoolFactory.getThreadList();
|
||||||
|
Iterator<WeakReference<Thread>> iter = null;
|
||||||
|
if(queue != null) {
|
||||||
|
System.out.println("== List of async threads that did not terminate on their own == ");
|
||||||
|
iter = queue.iterator();
|
||||||
|
}
|
||||||
|
while(iter != null && iter.hasNext()) {
|
||||||
|
WeakReference<Thread> ref = iter.next();
|
||||||
|
Thread t = ref.get();
|
||||||
|
if(t == null) {
|
||||||
|
iter.remove();
|
||||||
|
} else if (t.isAlive()) {
|
||||||
|
StackTraceElement[] e = t.getStackTrace();
|
||||||
|
System.out.println(t.getName() + " - " + t.getState().toString());
|
||||||
|
for(StackTraceElement et: e) {
|
||||||
|
System.out.println(et.toString());
|
||||||
|
}
|
||||||
|
System.out.println("========================== ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveNBTFileStatic(NBTTagCompound compound, File file) {
|
||||||
|
instance.saveNBTFile(compound, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveNBTFile(NBTTagCompound compound, File file) {
|
||||||
|
this.nbtFiles.queueTask(new NBTFileSaver(compound, file));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NBTFileSaver implements Runnable {
|
||||||
|
|
||||||
|
private NBTTagCompound compound;
|
||||||
|
private File file;
|
||||||
|
|
||||||
|
public NBTFileSaver(NBTTagCompound compound, File file) {
|
||||||
|
this.compound = compound;
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
FileOutputStream fileoutputstream = null;
|
||||||
|
try {
|
||||||
|
fileoutputstream = new FileOutputStream(this.file);
|
||||||
|
NBTCompressedStreamTools.a(this.compound, fileoutputstream);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(fileoutputstream != null) {
|
||||||
|
try {
|
||||||
|
fileoutputstream.close();
|
||||||
|
} catch (IOException e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.compound = null;
|
||||||
|
this.file = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean queuePathSearch(PathSearchJob pathSearchJob) {
|
||||||
|
return instance.pathSearchThrottler.queuePathSearch(pathSearchJob);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TickCounter implements Runnable {
|
||||||
|
|
||||||
|
private ArrayDeque<Integer> ticksPerSecond;
|
||||||
|
private AtomicInteger ticksCounter;
|
||||||
|
|
||||||
|
public TickCounter() {
|
||||||
|
this.ticksPerSecond = new ArrayDeque<>();
|
||||||
|
this.ticksCounter = new AtomicInteger(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int lastCount = this.ticksCounter.getAndSet(0);
|
||||||
|
synchronized(this.ticksPerSecond) {
|
||||||
|
this.ticksPerSecond.addLast(lastCount);
|
||||||
|
if(this.ticksPerSecond.size() > 30) {
|
||||||
|
this.ticksPerSecond.removeFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void increaseTickCounter() {
|
||||||
|
this.ticksCounter.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer[] getTicksPerSecond() {
|
||||||
|
synchronized(this.ticksPerSecond) {
|
||||||
|
return this.ticksPerSecond.toArray(new Integer[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TickCounter getTickCounter() {
|
||||||
|
return instance.tickCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startTickTimerTask() {
|
||||||
|
instance.tickTimerTask = instance.timerService.schedule(instance.tickTimerObject, timerDelay, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelTimerTask(float tickTime) {
|
||||||
|
if(checkTickTime(tickTime) && instance.tickTimerTask.cancel(false)) {
|
||||||
|
instance.tickTimerObject.tickFinishedEarly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkTickTime(float tickTime) {
|
||||||
|
if(tickTime > 45.0F) {
|
||||||
|
if(timerDelay > 40) {
|
||||||
|
timerDelay--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(timerDelay < 45) {
|
||||||
|
timerDelay++;
|
||||||
|
}
|
||||||
|
return tickTime < 40.0F;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TickTimer implements Callable<Object> {
|
||||||
|
public Object call() {
|
||||||
|
this.tickIsGoingToFinishLate();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tickIsGoingToFinishLate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tickFinishedEarly() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void execute(Runnable runnable) {
|
||||||
|
instance.cachedThreadPool.execute(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Future<?> submit(Runnable runnable) {
|
||||||
|
return instance.cachedThreadPool.submit(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Future<?> submit(Callable<?> callable) {
|
||||||
|
return instance.cachedThreadPool.submit(callable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void queueHeadConversion(Runnable runnable) {
|
||||||
|
instance.headConversions.queueTask(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TaskQueueWorker createTaskQueue() {
|
||||||
|
return instance.createTaskQueueWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskQueueWorker createTaskQueueWorker() {
|
||||||
|
return new TaskQueueWorker(this.cachedThreadPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TaskQueueWorker implements Runnable {
|
||||||
|
private ConcurrentLinkedDeque<Runnable> taskQueue = new ConcurrentLinkedDeque<>();
|
||||||
|
private ExecutorService service;
|
||||||
|
private volatile boolean isActive = false;
|
||||||
|
|
||||||
|
public TaskQueueWorker(ExecutorService service) {
|
||||||
|
this.service = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Runnable task = null;
|
||||||
|
while(this.isActive = ((task = this.taskQueue.pollFirst()) != null)) {
|
||||||
|
try {
|
||||||
|
task.run();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Thread " + Thread.currentThread().getName() + " encountered an exception: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queueTask(Runnable runnable) {
|
||||||
|
this.taskQueue.addLast(runnable);
|
||||||
|
if(!this.isActive) {
|
||||||
|
this.isActive = true;
|
||||||
|
this.service.execute(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
if(!this.isActive && !this.taskQueue.isEmpty()) {
|
||||||
|
this.isActive = true;
|
||||||
|
this.service.execute(this);
|
||||||
|
}
|
||||||
|
return this.isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTaskCount() {
|
||||||
|
int count = this.taskQueue.size();
|
||||||
|
if(this.isActive) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Executor getCommonThreadPool() {
|
||||||
|
return instance.cachedThreadPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,211 @@
|
||||||
|
package com.elevatemc.spigot.util;
|
||||||
|
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializable {
|
||||||
|
|
||||||
|
protected String worldName;
|
||||||
|
public int lowerX;
|
||||||
|
public int lowerY;
|
||||||
|
public int lowerZ;
|
||||||
|
public int upperX;
|
||||||
|
public int upperY;
|
||||||
|
public int upperZ;
|
||||||
|
|
||||||
|
public Cuboid(Location loc1, Location loc2) {
|
||||||
|
if (loc1.getWorld() != loc2.getWorld()) {
|
||||||
|
throw new IllegalArgumentException("Locations must be on the same world");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.worldName = loc1.getWorld().getName();
|
||||||
|
this.lowerX = FastMath.min(loc1.getBlockX(), loc2.getBlockX());
|
||||||
|
this.lowerY = FastMath.min(loc1.getBlockY(), loc2.getBlockY());
|
||||||
|
this.lowerZ = FastMath.min(loc1.getBlockZ(), loc2.getBlockZ());
|
||||||
|
this.upperX = FastMath.max(loc1.getBlockX(), loc2.getBlockX());
|
||||||
|
this.upperY = FastMath.max(loc1.getBlockY(), loc2.getBlockY());
|
||||||
|
this.upperZ = FastMath.max(loc1.getBlockZ(), loc2.getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cuboid(Cuboid cuboid) {
|
||||||
|
this.worldName = cuboid.worldName;
|
||||||
|
this.lowerX = cuboid.lowerX;
|
||||||
|
this.lowerY = cuboid.lowerY;
|
||||||
|
this.lowerZ = cuboid.lowerZ;
|
||||||
|
this.upperX = cuboid.upperX;
|
||||||
|
this.upperY = cuboid.upperY;
|
||||||
|
this.upperZ = cuboid.upperZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cuboid(Map<String, Object> map) {
|
||||||
|
this.worldName = (String) map.get("worldName");
|
||||||
|
this.lowerX = (int) map.get("x1");
|
||||||
|
this.lowerY = (int) map.get("y1");
|
||||||
|
this.lowerZ = (int) map.get("z1");
|
||||||
|
this.upperX = (int) map.get("x2");
|
||||||
|
this.upperY = (int) map.get("y2");
|
||||||
|
this.upperZ = (int) map.get("z2");
|
||||||
|
}
|
||||||
|
|
||||||
|
public World getWorld() {
|
||||||
|
World world = Bukkit.getWorld(this.worldName);
|
||||||
|
if (world == null) {
|
||||||
|
throw new IllegalStateException("World '" + this.worldName + "' is not loaded");
|
||||||
|
}
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getLowerNE() {
|
||||||
|
return new Location(this.getWorld(), this.lowerX, this.lowerY, this.lowerZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getUpperSW() {
|
||||||
|
return new Location(this.getWorld(), this.upperX, this.upperY, this.upperZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getCenter() {
|
||||||
|
return new Location(
|
||||||
|
this.getWorld(),
|
||||||
|
this.lowerX + (((this.upperX + 1) - this.lowerX) / 2.0),
|
||||||
|
this.lowerY + (((this.upperY + 1) - this.lowerY) / 2.0),
|
||||||
|
this.lowerZ + (((this.upperZ + 1) - this.lowerZ) / 2.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSizeX() {
|
||||||
|
return this.upperX - this.lowerX + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSizeY() {
|
||||||
|
return this.upperY - this.lowerY + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSizeZ() {
|
||||||
|
return this.upperZ - this.lowerZ + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVolume() {
|
||||||
|
return this.getSizeX() * this.getSizeY() * this.getSizeZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Chunk> getChunks() {
|
||||||
|
List<Chunk> results = new ArrayList<>();
|
||||||
|
World world = this.getWorld();
|
||||||
|
|
||||||
|
final int x1 = this.lowerX & -0x10;
|
||||||
|
final int x2 = this.upperX & -0x10;
|
||||||
|
final int z1 = this.lowerZ & -0x10;
|
||||||
|
final int z2 = this.upperZ & -0x10;
|
||||||
|
|
||||||
|
int x3 = x1;
|
||||||
|
while (x3 <= x2) {
|
||||||
|
int z3 = z1;
|
||||||
|
while (z3 <= z2) {
|
||||||
|
results.add(world.getChunkAt(x3 >> 4, z3 << 4));
|
||||||
|
z3 += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
x3 += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Block> getBlocks() {
|
||||||
|
List<Block> copy = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Block block : this) {
|
||||||
|
copy.add(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(int x, int y, int z) {
|
||||||
|
return x >= lowerX && x <= upperX && y >= lowerY && y <= upperY && z >= lowerZ && z <= upperZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Location location) {
|
||||||
|
return worldName.equals(location.getWorld().getName()) && contains(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Block block) {
|
||||||
|
return contains(block.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Entity entity) {
|
||||||
|
return contains(entity.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Block> iterator() {
|
||||||
|
return new CuboidIterator(this.getWorld(), this.lowerX, this.lowerY, this.lowerZ, this.upperX, this.upperY, this.upperZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> serialize() {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("worldName", this.worldName);
|
||||||
|
map.put("x1", this.lowerX);
|
||||||
|
map.put("y1", this.lowerY);
|
||||||
|
map.put("z1", this.lowerZ);
|
||||||
|
map.put("x2", this.upperX);
|
||||||
|
map.put("y2", this.upperY);
|
||||||
|
map.put("z2", this.upperZ);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CuboidIterator implements Iterator<Block> {
|
||||||
|
private final World world;
|
||||||
|
|
||||||
|
private final int baseX;
|
||||||
|
private final int baseY;
|
||||||
|
private final int baseZ;
|
||||||
|
|
||||||
|
private int x = 0;
|
||||||
|
private int y = 0;
|
||||||
|
private int z = 0;
|
||||||
|
|
||||||
|
private final int sizeX;
|
||||||
|
private final int sizeY;
|
||||||
|
private final int sizeZ;
|
||||||
|
|
||||||
|
public CuboidIterator(World world, int x1, int y1, int z1, int x2, int y2, int z2) {
|
||||||
|
this.world = world;
|
||||||
|
this.baseX = FastMath.min(x1, x2);
|
||||||
|
this.baseY = FastMath.min(y1, y2);
|
||||||
|
this.baseZ = FastMath.min(z1, z2);
|
||||||
|
this.sizeX = FastMath.abs(x2 - x1) + 1;
|
||||||
|
this.sizeY = FastMath.abs(y2 - y1) + 1;
|
||||||
|
this.sizeZ = FastMath.abs(z2 - z1) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return this.x < this.sizeX && this.y < this.sizeY && this.z < this.sizeZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Block next() {
|
||||||
|
Block block = this.world.getBlockAt(this.baseX + this.x, this.baseY + this.y, this.baseZ + this.z);
|
||||||
|
if (++this.x >= this.sizeX) {
|
||||||
|
this.x = 0;
|
||||||
|
|
||||||
|
if (++this.y >= this.sizeY) {
|
||||||
|
this.y = 0;
|
||||||
|
++this.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.event.BlockDropItemsEvent;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftItem;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class Block {
|
public class Block {
|
||||||
|
|
||||||
|
public List<org.bukkit.entity.Item> droppedItemsCatcher;
|
||||||
|
|
||||||
private static final MinecraftKey a = new MinecraftKey("air");
|
private static final MinecraftKey a = new MinecraftKey("air");
|
||||||
public static final RegistryBlocks<MinecraftKey, Block> REGISTRY = new RegistryBlocks(Block.a);
|
public static final RegistryBlocks<MinecraftKey, Block> REGISTRY = new RegistryBlocks(Block.a);
|
||||||
public static final RegistryID<IBlockData> d = new RegistryID();
|
public static final RegistryID<IBlockData> d = new RegistryID();
|
||||||
|
@ -342,7 +349,30 @@ public class Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void b(World world, BlockPosition blockposition, IBlockData iblockdata, int i) {
|
public final void b(World world, BlockPosition blockposition, IBlockData iblockdata, int i) {
|
||||||
|
if (this == Blocks.AIR) return;
|
||||||
|
if (this.droppedItemsCatcher == null) {
|
||||||
|
|
||||||
|
this.droppedItemsCatcher = new ArrayList<>(1);
|
||||||
this.dropNaturally(world, blockposition, iblockdata, 1.0F, i);
|
this.dropNaturally(world, blockposition, iblockdata, 1.0F, i);
|
||||||
|
|
||||||
|
BlockDropItemsEvent dropItemsEvent = new BlockDropItemsEvent(world.getWorld().getBlockAt(
|
||||||
|
blockposition.getX(),
|
||||||
|
blockposition.getY(),
|
||||||
|
blockposition.getZ()), null, this.droppedItemsCatcher);
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().callEvent(dropItemsEvent);
|
||||||
|
|
||||||
|
if (!dropItemsEvent.isCancelled() && dropItemsEvent.getToDrop() != null) {
|
||||||
|
for (final org.bukkit.entity.Item item : dropItemsEvent.getToDrop()) {
|
||||||
|
|
||||||
|
world.addEntity(((CraftItem) item).getHandle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.droppedItemsCatcher = null;
|
||||||
|
} else {
|
||||||
|
this.dropNaturally(world, blockposition, iblockdata, 1.0F, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) {
|
public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class Chunk {
|
||||||
private boolean done;
|
private boolean done;
|
||||||
private boolean lit;
|
private boolean lit;
|
||||||
private boolean p;
|
private boolean p;
|
||||||
private boolean q;
|
public boolean q;
|
||||||
private boolean r;
|
private boolean r;
|
||||||
private long lastSaved;
|
private long lastSaved;
|
||||||
private int t;
|
private int t;
|
||||||
|
@ -828,7 +828,7 @@ public class Chunk {
|
||||||
return j >= this.heightMap[k << 4 | i];
|
return j >= this.heightMap[k << 4 | i];
|
||||||
}
|
}
|
||||||
|
|
||||||
private TileEntity i(BlockPosition blockposition) {
|
public TileEntity i(BlockPosition blockposition) {
|
||||||
Block block = this.getType(blockposition);
|
Block block = this.getType(blockposition);
|
||||||
|
|
||||||
return !block.isTileEntity() ? null : ((IContainer) block).a(this.world, this.c(blockposition));
|
return !block.isTileEntity() ? null : ((IContainer) block).a(this.world, this.c(blockposition));
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.chunk.ChunkSectionSnapshot;
|
||||||
|
|
||||||
public class ChunkSection {
|
public class ChunkSection {
|
||||||
|
|
||||||
private int yPos;
|
private int yPos;
|
||||||
|
@ -8,7 +10,7 @@ public class ChunkSection {
|
||||||
private char[] blockIds;
|
private char[] blockIds;
|
||||||
private NibbleArray emittedLight;
|
private NibbleArray emittedLight;
|
||||||
private NibbleArray skyLight;
|
private NibbleArray skyLight;
|
||||||
boolean isDirty; // PaperSpigot
|
public boolean isDirty;
|
||||||
|
|
||||||
public ChunkSection(int i, boolean flag) {
|
public ChunkSection(int i, boolean flag) {
|
||||||
this.yPos = i;
|
this.yPos = i;
|
||||||
|
@ -58,7 +60,6 @@ public class ChunkSection {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.blockIds[j << 8 | k << 4 | i] = (char) Block.d.b(iblockdata);
|
this.blockIds[j << 8 | k << 4 | i] = (char) Block.d.b(iblockdata);
|
||||||
isDirty = true; // PaperSpigot
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block b(int i, int j, int k) {
|
public Block b(int i, int j, int k) {
|
||||||
|
@ -85,7 +86,6 @@ public class ChunkSection {
|
||||||
|
|
||||||
public void a(int i, int j, int k, int l) {
|
public void a(int i, int j, int k, int l) {
|
||||||
this.skyLight.a(i, j, k, l);
|
this.skyLight.a(i, j, k, l);
|
||||||
isDirty = true; // PaperSpigot
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int d(int i, int j, int k) {
|
public int d(int i, int j, int k) {
|
||||||
|
@ -94,7 +94,6 @@ public class ChunkSection {
|
||||||
|
|
||||||
public void b(int i, int j, int k, int l) {
|
public void b(int i, int j, int k, int l) {
|
||||||
this.emittedLight.a(i, j, k, l);
|
this.emittedLight.a(i, j, k, l);
|
||||||
isDirty = true; // PaperSpigot
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int e(int i, int j, int k) {
|
public int e(int i, int j, int k) {
|
||||||
|
@ -145,4 +144,23 @@ public class ChunkSection {
|
||||||
public void b(NibbleArray nibblearray) {
|
public void b(NibbleArray nibblearray) {
|
||||||
this.skyLight = nibblearray;
|
this.skyLight = nibblearray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ChunkSectionSnapshot createSnapshot() {
|
||||||
|
return new ChunkSectionSnapshot(
|
||||||
|
nonEmptyBlockCount,
|
||||||
|
tickingBlockCount,
|
||||||
|
blockIds.clone(),
|
||||||
|
new NibbleArray(),
|
||||||
|
new NibbleArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restoreSnapshot(ChunkSectionSnapshot snap) {
|
||||||
|
nonEmptyBlockCount = snap.getNonEmptyBlockCount();
|
||||||
|
tickingBlockCount = snap.getTickingBlockCount();
|
||||||
|
blockIds = snap.getBlockIds().clone();
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ public abstract class Entity implements ICommandListener {
|
||||||
public float M;
|
public float M;
|
||||||
public float N;
|
public float N;
|
||||||
public float fallDistance;
|
public float fallDistance;
|
||||||
private int h;
|
public int h; //Last ground Y
|
||||||
public double P;
|
public double P;
|
||||||
public double Q;
|
public double Q;
|
||||||
public double R;
|
public double R;
|
||||||
|
|
|
@ -3,6 +3,10 @@ package net.minecraft.server;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJob;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobEntity;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobPosition;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchQueuingManager;
|
||||||
import org.bukkit.event.entity.EntityUnleashEvent;
|
import org.bukkit.event.entity.EntityUnleashEvent;
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
|
@ -15,6 +19,41 @@ public abstract class EntityCreature extends EntityInsentient {
|
||||||
private PathfinderGoal c;
|
private PathfinderGoal c;
|
||||||
private boolean bm;
|
private boolean bm;
|
||||||
|
|
||||||
|
// ImHacking start
|
||||||
|
private PathSearchQueuingManager queuingManager = new PathSearchQueuingManager();
|
||||||
|
private boolean searchIssued = false;
|
||||||
|
private PathEntity returnedPathEntity;
|
||||||
|
|
||||||
|
public boolean isSearchingForAPath() {
|
||||||
|
return this.queuingManager.hasAsyncSearchIssued();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelSearch(PathSearchJob pathSearch) {
|
||||||
|
this.queuingManager.checkLastSearchResult(pathSearch);
|
||||||
|
pathSearch.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void issueSearch(BlockPosition blockPosition, float range) {
|
||||||
|
this.queuingManager.queueSearch(new PathSearchJobPosition(this, blockPosition, range, true, false, false, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void issueSearch(Entity target, float range) {
|
||||||
|
this.queuingManager.queueSearch(new PathSearchJobEntity(this, target, range, true, false, false, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchResult(PathSearchJobEntity pathSearchJobEntity, Entity target, PathEntity pathentity) {
|
||||||
|
this.queuingManager.checkLastSearchResult(pathSearchJobEntity);
|
||||||
|
if (this.goalTarget != null && this.goalTarget.equals(target)) {
|
||||||
|
this.returnedPathEntity = pathentity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchResult(PathSearchJobPosition pathSearchJobPosition, PathEntity pathentity) {
|
||||||
|
this.queuingManager.checkLastSearchResult(pathSearchJobPosition);
|
||||||
|
this.returnedPathEntity = pathentity;
|
||||||
|
}
|
||||||
|
// ImHacking end
|
||||||
|
|
||||||
public EntityCreature(World world) {
|
public EntityCreature(World world) {
|
||||||
super(world);
|
super(world);
|
||||||
this.a = BlockPosition.ZERO;
|
this.a = BlockPosition.ZERO;
|
||||||
|
@ -31,7 +70,7 @@ public abstract class EntityCreature extends EntityInsentient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean cf() {
|
public boolean cf() {
|
||||||
return !this.navigation.m();
|
return !this.getNavigation().m();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean cg() {
|
public boolean cg() {
|
||||||
|
|
|
@ -1,15 +1,37 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
|
import com.elevatemc.spigot.event.PlayerPearlRefundEvent;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.material.Gate;
|
||||||
|
import org.bukkit.material.Openable;
|
||||||
|
import org.bukkit.util.BlockIterator;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
public class EntityEnderPearl extends EntityProjectile {
|
public class EntityEnderPearl extends EntityProjectile {
|
||||||
|
|
||||||
private EntityLiving c;
|
private EntityLiving c;
|
||||||
|
|
||||||
|
private Location teleportLocation;
|
||||||
|
|
||||||
|
private static final Set<Block> PROHIBITED_PEARL_BLOCKS = Sets.newHashSet(Block.getById(85), Block.getById(107));
|
||||||
|
public static List<String> pearlAbleType = Arrays.asList("STEP", "STAIR");
|
||||||
|
public static List<org.bukkit.Material> forwardTypes = Collections.singletonList(org.bukkit.Material.ENDER_PORTAL_FRAME);
|
||||||
|
|
||||||
public EntityEnderPearl(World world) {
|
public EntityEnderPearl(World world) {
|
||||||
super(world);
|
super(world);
|
||||||
this.loadChunks = world.paperSpigotConfig.loadUnloadedEnderPearls; // PaperSpigot
|
this.loadChunks = world.paperSpigotConfig.loadUnloadedEnderPearls; // PaperSpigot
|
||||||
|
@ -21,80 +43,177 @@ public class EntityEnderPearl extends EntityProjectile {
|
||||||
this.loadChunks = world.paperSpigotConfig.loadUnloadedEnderPearls; // PaperSpigot
|
this.loadChunks = world.paperSpigotConfig.loadUnloadedEnderPearls; // PaperSpigot
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void a(MovingObjectPosition movingobjectposition) {
|
@Override
|
||||||
EntityLiving entityliving = this.getShooter();
|
protected void a(final MovingObjectPosition objectPosition) {
|
||||||
|
final EntityLiving entityliving = this.getShooter();
|
||||||
|
BlockPosition position = objectPosition.a();
|
||||||
|
if(position == null) {
|
||||||
|
position = new BlockPosition(this);
|
||||||
|
}
|
||||||
|
Block block = this.world.getType(position).getBlock();
|
||||||
|
|
||||||
if (movingobjectposition.entity != null) {
|
if (block == Blocks.TRIPWIRE) {
|
||||||
if (movingobjectposition.entity == this.c) {
|
return;
|
||||||
|
} else if (block == Blocks.FENCE_GATE) {
|
||||||
|
BlockIterator bi = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Vector l = new Vector(this.locX, this.locY, this.locZ);
|
||||||
|
Vector l2 = new Vector(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ);
|
||||||
|
Vector dir = new Vector(l2.getX() - l.getX(), l2.getY() - l.getY(), l2.getZ() - l.getZ()).normalize();
|
||||||
|
bi = new BlockIterator(this.world.getWorld(), l, dir, 0, 1);
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bi != null) {
|
||||||
|
boolean open = true;
|
||||||
|
boolean hasSolidBlock = false;
|
||||||
|
|
||||||
|
while (bi.hasNext()) {
|
||||||
|
org.bukkit.block.Block b = bi.next();
|
||||||
|
|
||||||
|
if (b.getType().isSolid() && b.getType().isOccluding()) {
|
||||||
|
hasSolidBlock = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.getState().getData() instanceof Gate && !((Gate) b.getState().getData()).isOpen()) {
|
||||||
|
open = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (open && !hasSolidBlock) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
movingobjectposition.entity.damageEntity(DamageSource.projectile(this, entityliving), 0.0F);
|
}
|
||||||
|
if (objectPosition.entity != null) {
|
||||||
|
if (objectPosition.entity == this.c) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
objectPosition.entity.damageEntity(DamageSource.projectile(this, entityliving), 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaperSpigot start - Remove entities in unloaded chunks
|
if (this.inUnloadedChunk && this.world.paperSpigotConfig.removeUnloadedEnderPearls) {
|
||||||
if (this.inUnloadedChunk && world.paperSpigotConfig.removeUnloadedEnderPearls) {
|
|
||||||
this.die();
|
this.die();
|
||||||
}
|
}
|
||||||
// PaperSpigot end
|
|
||||||
|
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 32; ++i) {
|
||||||
this.world.addParticle(EnumParticle.PORTAL, this.locX, this.locY + this.random.nextDouble() * 2.0D, this.locZ, this.random.nextGaussian(), 0.0D, this.random.nextGaussian(), new int[0]);
|
this.world.addParticle(EnumParticle.PORTAL, this.locX, this.locY + this.random.nextDouble() * 2.0, this.locZ, this.random.nextGaussian(),
|
||||||
|
0.0, this.random.nextGaussian());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.world.isClientSide) {
|
if (!this.world.isClientSide) {
|
||||||
if (entityliving instanceof EntityPlayer) {
|
if (entityliving instanceof EntityPlayer) {
|
||||||
EntityPlayer entityplayer = (EntityPlayer) entityliving;
|
final EntityPlayer entityplayer = (EntityPlayer)entityliving;
|
||||||
|
|
||||||
if (entityplayer.playerConnection.a().g() && entityplayer.world == this.world && !entityplayer.isSleeping()) {
|
if (entityplayer.playerConnection.a().g() && entityplayer.world == this.world && !entityplayer.isSleeping()) {
|
||||||
// CraftBukkit start - Fire PlayerTeleportEvent
|
if (teleportLocation != null) {
|
||||||
org.bukkit.craftbukkit.entity.CraftPlayer player = entityplayer.getBukkitEntity();
|
CraftPlayer player = entityplayer.getBukkitEntity();
|
||||||
org.bukkit.Location location = getBukkitEntity().getLocation();
|
Location previousLocation = player.getLocation();
|
||||||
location.setPitch(player.getLocation().getPitch());
|
|
||||||
location.setYaw(player.getLocation().getYaw());
|
teleportLocation.setYaw(previousLocation.getYaw());
|
||||||
|
teleportLocation.setPitch(previousLocation.getPitch());
|
||||||
|
|
||||||
|
// Fix an issue with the pearl actually not teleporting you into the exact Y it will
|
||||||
|
// randomly/based of the pitch the Y would change, the closer to the thrower/thrown from
|
||||||
|
// will cause it to be higher, unless directly down
|
||||||
|
teleportLocation.setY((int) teleportLocation.getY());
|
||||||
|
|
||||||
|
PlayerTeleportEvent teleEvent = new PlayerTeleportEvent(player, player.getLocation(),
|
||||||
|
teleportLocation, PlayerTeleportEvent.TeleportCause.ENDER_PEARL);
|
||||||
|
|
||||||
PlayerTeleportEvent teleEvent = new PlayerTeleportEvent(player, player.getLocation(), location, PlayerTeleportEvent.TeleportCause.ENDER_PEARL);
|
|
||||||
Bukkit.getPluginManager().callEvent(teleEvent);
|
Bukkit.getPluginManager().callEvent(teleEvent);
|
||||||
|
|
||||||
if (!teleEvent.isCancelled() && !entityplayer.playerConnection.isDisconnected()) {
|
if (!teleEvent.isCancelled() && !entityplayer.playerConnection.isDisconnected()) {
|
||||||
if (this.random.nextFloat() < 0.05F && this.world.getGameRules().getBoolean("doMobSpawning")) {
|
|
||||||
EntityEndermite entityendermite = new EntityEndermite(this.world);
|
|
||||||
|
|
||||||
entityendermite.a(true);
|
|
||||||
entityendermite.setPositionRotation(entityliving.locX, entityliving.locY, entityliving.locZ, entityliving.yaw, entityliving.pitch);
|
|
||||||
this.world.addEntity(entityendermite);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entityliving.au()) {
|
if (entityliving.au()) {
|
||||||
entityliving.mount((Entity) null);
|
this.getShooter().mount(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityplayer.playerConnection.teleport(teleEvent.getTo());
|
entityplayer.playerConnection.teleport(teleEvent.getTo());
|
||||||
entityliving.fallDistance = 0.0F;
|
entityliving.fallDistance = 0.0F;
|
||||||
|
((Entity)entityliving).h = -1;
|
||||||
CraftEventFactory.entityDamage = this;
|
CraftEventFactory.entityDamage = this;
|
||||||
entityliving.damageEntity(DamageSource.FALL, 5.0F);
|
entityliving.damageEntity(DamageSource.FALL, 5.0F);
|
||||||
CraftEventFactory.entityDamage = null;
|
CraftEventFactory.entityDamage = null;
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
} else {
|
||||||
|
//ImHacking Add Player Pearl Refund
|
||||||
|
Bukkit.getPluginManager().callEvent(new PlayerPearlRefundEvent(entityplayer.getBukkitEntity()));
|
||||||
|
// ImHacking (Give back the pearl since the teleport location was not made correctly)
|
||||||
|
player.getInventory().addItem(new ItemStack(org.bukkit.Material.ENDER_PEARL));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (entityliving != null) {
|
} else if (entityliving != null) {
|
||||||
entityliving.enderTeleportTo(this.locX, this.locY, this.locZ);
|
entityliving.enderTeleportTo(this.locX, this.locY, this.locZ);
|
||||||
entityliving.fallDistance = 0.0F;
|
entityliving.fallDistance = 0.0f;
|
||||||
|
((Entity)entityliving).h = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.die();
|
this.die();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void t_() {
|
public void t_() {
|
||||||
EntityLiving entityliving = this.getShooter();
|
final EntityLiving shooter = this.getShooter();
|
||||||
|
|
||||||
if (entityliving != null && entityliving instanceof EntityHuman && !entityliving.isAlive()) {
|
// ImHacking Start - Prevent Pearling into blocks
|
||||||
|
// (This is a simple check to make sure
|
||||||
|
// that people can't make an impossible pearl through block
|
||||||
|
if (shooter != null && !shooter.isAlive()) {
|
||||||
this.die();
|
this.die();
|
||||||
} else {
|
} else {
|
||||||
super.t_();
|
AxisAlignedBB boundingBox = AxisAlignedBB.a(this.locX - 0.3D, this.locY - 0.05D, this.locZ - 0.3D, this.locX + 0.3D, this.locY + 0.5D, this.locZ + 0.3D);
|
||||||
|
|
||||||
|
if (!this.world.boundingBoxContainsMaterials(this.getBoundingBox().grow(0.25D,
|
||||||
|
0D, 0.25D), PROHIBITED_PEARL_BLOCKS) && this.world.getCubes(this, boundingBox).isEmpty()) {
|
||||||
|
this.teleportLocation = getBukkitEntity().getLocation();
|
||||||
|
}
|
||||||
|
org.bukkit.block.Block block = this.world.getWorld().getBlockAt(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ));
|
||||||
|
org.bukkit.Material typeHere = this.world.getWorld().getBlockAt(MathHelper.floor(this.locX),
|
||||||
|
MathHelper.floor(this.locY), MathHelper.floor(this.locZ)).getType();
|
||||||
|
|
||||||
|
if (pearlAbleType.stream().anyMatch(it -> typeHere.name().contains(it))) {
|
||||||
|
this.teleportLocation = getBukkitEntity().getLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shooter != null && forwardTypes.stream().anyMatch(it ->
|
||||||
|
block.getRelative(getDirection((EntityPlayer) shooter)).getType() == it)) {
|
||||||
|
this.teleportLocation = getBukkitEntity().getLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeHere == org.bukkit.Material.FENCE_GATE) {
|
||||||
|
if (((Openable) block.getState().getData()).isOpen()) {
|
||||||
|
this.teleportLocation = getBukkitEntity().getLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shooter != null) {
|
||||||
|
final org.bukkit.block.Block newTrap = block.getRelative(getDirection((EntityPlayer) shooter)).getRelative(BlockFace.DOWN);
|
||||||
|
|
||||||
|
if (newTrap.getType() == org.bukkit.Material.COBBLE_WALL || newTrap.getType() == Material.FENCE) {
|
||||||
|
this.teleportLocation = newTrap.getLocation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
super.t_();
|
||||||
|
// ImHacking End
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BlockFace getDirection(EntityPlayer entityPlayer) {
|
||||||
|
float yaw = entityPlayer.getBukkitEntity().getLocation().getYaw();
|
||||||
|
if (yaw < 0) {
|
||||||
|
yaw += 360;
|
||||||
|
}
|
||||||
|
if (yaw >= 315 || yaw < 45) {
|
||||||
|
return BlockFace.SOUTH;
|
||||||
|
} else if (yaw < 135) {
|
||||||
|
return BlockFace.WEST;
|
||||||
|
} else if (yaw < 225) {
|
||||||
|
return BlockFace.NORTH;
|
||||||
|
} else if (yaw < 315) {
|
||||||
|
return BlockFace.EAST;
|
||||||
|
}
|
||||||
|
return BlockFace.NORTH;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -749,7 +749,7 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener {
|
||||||
EntityHorse entityhorse = this.a(this, 16.0D);
|
EntityHorse entityhorse = this.a(this, 16.0D);
|
||||||
|
|
||||||
if (entityhorse != null && this.h((Entity) entityhorse) > 4.0D) {
|
if (entityhorse != null && this.h((Entity) entityhorse) > 4.0D) {
|
||||||
this.navigation.a((Entity) entityhorse);
|
this.getNavigation().a(entityhorse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.event.PlayerHealthChangeEvent;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.elevatemc.spigot.eSpigot;
|
import com.elevatemc.spigot.eSpigot;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||||
import org.bukkit.craftbukkit.entity.CraftItem;
|
import org.bukkit.craftbukkit.entity.CraftItem;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||||
|
@ -1756,8 +1759,13 @@ public abstract class EntityHuman extends EntityLiving {
|
||||||
if (f < 0.0F) {
|
if (f < 0.0F) {
|
||||||
f = 0.0F;
|
f = 0.0F;
|
||||||
}
|
}
|
||||||
|
float previous = getAbsorptionHearts(); // ImHacking
|
||||||
this.getDataWatcher().watch(17, Float.valueOf(f));
|
this.getDataWatcher().watch(17, Float.valueOf(f));
|
||||||
|
// ImHacking Start - Player Health Change Event
|
||||||
|
if (previous != f) {
|
||||||
|
Bukkit.getPluginManager().callEvent(new PlayerHealthChangeEvent(((CraftPlayer) getBukkitEntity()), previous, getHealth()));
|
||||||
|
}
|
||||||
|
// ImHacking End
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean a(ChestLock chestlock) {
|
public boolean a(ChestLock chestlock) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
|
import com.elevatemc.spigot.pathsearch.AsyncNavigation;
|
||||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||||
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
|
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
|
||||||
|
@ -21,10 +22,10 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||||
protected ControllerMove moveController;
|
protected ControllerMove moveController;
|
||||||
protected ControllerJump g;
|
protected ControllerJump g;
|
||||||
private EntityAIBodyControl b;
|
private EntityAIBodyControl b;
|
||||||
protected NavigationAbstract navigation;
|
private Navigation navigation;
|
||||||
public PathfinderGoalSelector goalSelector;
|
public PathfinderGoalSelector goalSelector;
|
||||||
public PathfinderGoalSelector targetSelector;
|
public PathfinderGoalSelector targetSelector;
|
||||||
private EntityLiving goalTarget;
|
public EntityLiving goalTarget;
|
||||||
private EntitySenses bk;
|
private EntitySenses bk;
|
||||||
private ItemStack[] equipment = new ItemStack[5];
|
private ItemStack[] equipment = new ItemStack[5];
|
||||||
public float[] dropChances = new float[5];
|
public float[] dropChances = new float[5];
|
||||||
|
@ -43,7 +44,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||||
this.moveController = new ControllerMove(this);
|
this.moveController = new ControllerMove(this);
|
||||||
this.g = new ControllerJump(this);
|
this.g = new ControllerJump(this);
|
||||||
this.b = new EntityAIBodyControl(this);
|
this.b = new EntityAIBodyControl(this);
|
||||||
this.navigation = this.b(world);
|
this.navigation = new AsyncNavigation(this, world); // ImHacking
|
||||||
this.bk = new EntitySenses(this);
|
this.bk = new EntitySenses(this);
|
||||||
|
|
||||||
for (int i = 0; i < this.dropChances.length; ++i) {
|
for (int i = 0; i < this.dropChances.length; ++i) {
|
||||||
|
@ -76,7 +77,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||||
return this.g;
|
return this.g;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NavigationAbstract getNavigation() {
|
public Navigation getNavigation() {
|
||||||
return this.navigation;
|
return this.navigation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,8 @@ public abstract class EntityLiving extends Entity {
|
||||||
protected boolean aP;
|
protected boolean aP;
|
||||||
protected int ticksFarFromPlayer;
|
protected int ticksFarFromPlayer;
|
||||||
protected float aR;
|
protected float aR;
|
||||||
|
|
||||||
|
public int lastGroundY; //lastGroundY
|
||||||
protected float aS;
|
protected float aS;
|
||||||
protected float aT;
|
protected float aT;
|
||||||
protected float aU;
|
protected float aU;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -13,6 +15,10 @@ public abstract class EntityProjectile extends Entity implements IProjectile {
|
||||||
public int shake;
|
public int shake;
|
||||||
public EntityLiving shooter;
|
public EntityLiving shooter;
|
||||||
public String shooterName;
|
public String shooterName;
|
||||||
|
|
||||||
|
//ImHacking - Start
|
||||||
|
public CraftPlayer player;
|
||||||
|
//ImHacking - End
|
||||||
private int i;
|
private int i;
|
||||||
private int ar;
|
private int ar;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class EntityRabbit extends EntityAnimal {
|
||||||
|
|
||||||
// CraftBukkit start - code from constructor
|
// CraftBukkit start - code from constructor
|
||||||
public void initializePathFinderGoals(){
|
public void initializePathFinderGoals(){
|
||||||
this.navigation.a(2.5F);
|
this.getNavigation().a(2.5F);
|
||||||
this.goalSelector.a(1, new PathfinderGoalFloat(this));
|
this.goalSelector.a(1, new PathfinderGoalFloat(this));
|
||||||
this.goalSelector.a(1, new EntityRabbit.PathfinderGoalRabbitPanic(this, 1.33D));
|
this.goalSelector.a(1, new EntityRabbit.PathfinderGoalRabbitPanic(this, 1.33D));
|
||||||
this.goalSelector.a(2, new PathfinderGoalTempt(this, 1.0D, Items.CARROT, false));
|
this.goalSelector.a(2, new PathfinderGoalTempt(this, 1.0D, Items.CARROT, false));
|
||||||
|
@ -123,7 +123,7 @@ public class EntityRabbit extends EntityAnimal {
|
||||||
|
|
||||||
if (!entityrabbit_controllerjumprabbit.c()) {
|
if (!entityrabbit_controllerjumprabbit.c()) {
|
||||||
if (this.moveController.a() && this.bs == 0) {
|
if (this.moveController.a() && this.bs == 0) {
|
||||||
PathEntity pathentity = this.navigation.j();
|
PathEntity pathentity = this.getNavigation().j();
|
||||||
Vec3D vec3d = new Vec3D(this.moveController.d(), this.moveController.e(), this.moveController.f());
|
Vec3D vec3d = new Vec3D(this.moveController.d(), this.moveController.e(), this.moveController.f());
|
||||||
|
|
||||||
if (pathentity != null && pathentity.e() < pathentity.d()) {
|
if (pathentity != null && pathentity.e() < pathentity.d()) {
|
||||||
|
|
|
@ -272,8 +272,8 @@ public class EntityWolf extends EntityTameableAnimal {
|
||||||
if (this.e((EntityLiving) entityhuman) && !this.world.isClientSide && !this.d(itemstack)) {
|
if (this.e((EntityLiving) entityhuman) && !this.world.isClientSide && !this.d(itemstack)) {
|
||||||
this.bm.setSitting(!this.isSitting());
|
this.bm.setSitting(!this.isSitting());
|
||||||
this.aY = false;
|
this.aY = false;
|
||||||
this.navigation.n();
|
this.getNavigation().n();
|
||||||
this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
|
this.setGoalTarget(null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
|
||||||
}
|
}
|
||||||
} else if (itemstack != null && itemstack.getItem() == Items.BONE && !this.isAngry()) {
|
} else if (itemstack != null && itemstack.getItem() == Items.BONE && !this.isAngry()) {
|
||||||
if (!entityhuman.abilities.canInstantlyBuild) {
|
if (!entityhuman.abilities.canInstantlyBuild) {
|
||||||
|
@ -288,8 +288,8 @@ public class EntityWolf extends EntityTameableAnimal {
|
||||||
// CraftBukkit - added event call and isCancelled check.
|
// CraftBukkit - added event call and isCancelled check.
|
||||||
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
||||||
this.setTamed(true);
|
this.setTamed(true);
|
||||||
this.navigation.n();
|
this.getNavigation().n();
|
||||||
this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true);
|
this.setGoalTarget(null, TargetReason.FORGOT_TARGET, true);
|
||||||
this.bm.setSitting(true);
|
this.bm.setSitting(true);
|
||||||
this.setHealth(this.getMaxHealth()); // CraftBukkit - 20.0 -> getMaxHealth()
|
this.setHealth(this.getMaxHealth()); // CraftBukkit - 20.0 -> getMaxHealth()
|
||||||
this.setOwnerUUID(entityhuman.getUniqueID().toString());
|
this.setOwnerUUID(entityhuman.getUniqueID().toString());
|
||||||
|
|
|
@ -0,0 +1,239 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.pathsearch.PositionPathSearchType;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJob;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobNavigationEntity;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobNavigationPosition;
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class Navigation extends NavigationAbstract {
|
||||||
|
|
||||||
|
protected PathfinderNormal a;
|
||||||
|
private boolean f;
|
||||||
|
|
||||||
|
public Navigation(EntityInsentient var1, World var2) {
|
||||||
|
super(var1, var2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImHacking start
|
||||||
|
public void setSearchResult(PathSearchJobNavigationEntity pathSearch) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchResult(PathSearchJobNavigationPosition pathSearch) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathEntity a(PositionPathSearchType type, double d0, double d1, double d2) {
|
||||||
|
return this.a(d0, d1, d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean a(PositionPathSearchType type, double d0, double d1, double d2, double d3) {
|
||||||
|
return this.a(d0, d1, d2, d3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanUpExpiredSearches() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelSearch(PathSearchJob pathSearch) {
|
||||||
|
}
|
||||||
|
// ImHacking end
|
||||||
|
|
||||||
|
protected Pathfinder a() {
|
||||||
|
this.a = new PathfinderNormal();
|
||||||
|
this.a.a(true);
|
||||||
|
return new Pathfinder(this.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean b() {
|
||||||
|
return this.b.onGround || this.h() && this.o() || this.b.au() && this.b instanceof EntityZombie && this.b.vehicle instanceof EntityChicken;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Vec3D c() {
|
||||||
|
return new Vec3D(this.b.locX, (double) this.p(), this.b.locZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int p() {
|
||||||
|
if (this.b.V() && this.h()) {
|
||||||
|
int var1 = (int) this.b.getBoundingBox().b;
|
||||||
|
Block var2 = this.c.getType(new BlockPosition(MathHelper.floor(this.b.locX), var1, MathHelper.floor(this.b.locZ))).getBlock();
|
||||||
|
int var3 = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (var2 != Blocks.FLOWING_WATER && var2 != Blocks.WATER) {
|
||||||
|
return var1;
|
||||||
|
}
|
||||||
|
|
||||||
|
++var1;
|
||||||
|
var2 = this.c.getType(new BlockPosition(MathHelper.floor(this.b.locX), var1, MathHelper.floor(this.b.locZ))).getBlock();
|
||||||
|
++var3;
|
||||||
|
} while (var3 <= 16);
|
||||||
|
|
||||||
|
return (int) this.b.getBoundingBox().b;
|
||||||
|
} else {
|
||||||
|
return (int) (this.b.getBoundingBox().b + 0.5D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void d() {
|
||||||
|
super.d();
|
||||||
|
if (this.f) {
|
||||||
|
if (this.c.i(new BlockPosition(MathHelper.floor(this.b.locX), (int) (this.b.getBoundingBox().b + 0.5D), MathHelper.floor(this.b.locZ)))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int var1 = 0; var1 < this.d.d(); ++var1) {
|
||||||
|
PathPoint var2 = this.d.a(var1);
|
||||||
|
if (this.c.i(new BlockPosition(var2.a, var2.b, var2.c))) {
|
||||||
|
this.d.b(var1 - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean a(Vec3D var1, Vec3D var2, int var3, int var4, int var5) {
|
||||||
|
int var6 = MathHelper.floor(var1.a);
|
||||||
|
int var7 = MathHelper.floor(var1.c);
|
||||||
|
double var8 = var2.a - var1.a;
|
||||||
|
double var10 = var2.c - var1.c;
|
||||||
|
double var12 = var8 * var8 + var10 * var10;
|
||||||
|
if (var12 < 1.0E-8D) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
double var14 = 1.0D / FastMath.sqrt(var12);
|
||||||
|
var8 *= var14;
|
||||||
|
var10 *= var14;
|
||||||
|
var3 += 2;
|
||||||
|
var5 += 2;
|
||||||
|
if (!this.a(var6, (int) var1.b, var7, var3, var4, var5, var1, var8, var10)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
var3 -= 2;
|
||||||
|
var5 -= 2;
|
||||||
|
double var16 = 1.0D / FastMath.abs(var8);
|
||||||
|
double var18 = 1.0D / FastMath.abs(var10);
|
||||||
|
double var20 = (double) (var6 * 1) - var1.a;
|
||||||
|
double var22 = (double) (var7 * 1) - var1.c;
|
||||||
|
if (var8 >= 0.0D) {
|
||||||
|
++var20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var10 >= 0.0D) {
|
||||||
|
++var22;
|
||||||
|
}
|
||||||
|
|
||||||
|
var20 /= var8;
|
||||||
|
var22 /= var10;
|
||||||
|
int var24 = var8 < 0.0D ? -1 : 1;
|
||||||
|
int var25 = var10 < 0.0D ? -1 : 1;
|
||||||
|
int var26 = MathHelper.floor(var2.a);
|
||||||
|
int var27 = MathHelper.floor(var2.c);
|
||||||
|
int var28 = var26 - var6;
|
||||||
|
int var29 = var27 - var7;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (var28 * var24 <= 0 && var29 * var25 <= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var20 < var22) {
|
||||||
|
var20 += var16;
|
||||||
|
var6 += var24;
|
||||||
|
var28 = var26 - var6;
|
||||||
|
} else {
|
||||||
|
var22 += var18;
|
||||||
|
var7 += var25;
|
||||||
|
var29 = var27 - var7;
|
||||||
|
}
|
||||||
|
} while (this.a(var6, (int) var1.b, var7, var3, var4, var5, var1, var8, var10));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean a(int var1, int var2, int var3, int var4, int var5, int var6, Vec3D var7, double var8, double var10) {
|
||||||
|
int var12 = var1 - var4 / 2;
|
||||||
|
int var13 = var3 - var6 / 2;
|
||||||
|
if (!this.b(var12, var2, var13, var4, var5, var6, var7, var8, var10)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
for (int var14 = var12; var14 < var12 + var4; ++var14) {
|
||||||
|
for (int var15 = var13; var15 < var13 + var6; ++var15) {
|
||||||
|
double var16 = (double) var14 + 0.5D - var7.a;
|
||||||
|
double var18 = (double) var15 + 0.5D - var7.c;
|
||||||
|
if (!(var16 * var8 + var18 * var10 < 0.0D)) {
|
||||||
|
Block var20 = this.c.getType(new BlockPosition(var14, var2 - 1, var15)).getBlock();
|
||||||
|
Material var21 = var20.getMaterial();
|
||||||
|
if (var21 == Material.AIR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var21 == Material.WATER && !this.b.V()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var21 == Material.LAVA) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean b(int var1, int var2, int var3, int var4, int var5, int var6, Vec3D var7, double var8, double var10) {
|
||||||
|
Iterator var12 = BlockPosition.a(new BlockPosition(var1, var2, var3), new BlockPosition(var1 + var4 - 1, var2 + var5 - 1, var3 + var6 - 1)).iterator();
|
||||||
|
|
||||||
|
while (var12.hasNext()) {
|
||||||
|
BlockPosition var13 = (BlockPosition) var12.next();
|
||||||
|
double var14 = (double) var13.getX() + 0.5D - var7.a;
|
||||||
|
double var16 = (double) var13.getZ() + 0.5D - var7.c;
|
||||||
|
if (!(var14 * var8 + var16 * var10 < 0.0D)) {
|
||||||
|
Block var18 = this.c.getType(var13).getBlock();
|
||||||
|
if (!var18.b(this.c, var13)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(boolean var1) {
|
||||||
|
this.a.c(var1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean e() {
|
||||||
|
return this.a.e();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(boolean var1) {
|
||||||
|
this.a.b(var1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void c(boolean var1) {
|
||||||
|
this.a.a(var1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean g() {
|
||||||
|
return this.a.b();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void d(boolean var1) {
|
||||||
|
this.a.d(var1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean h() {
|
||||||
|
return this.a.d();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void e(boolean var1) {
|
||||||
|
this.f = var1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,10 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.pathsearch.PositionPathSearchType;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJob;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobNavigationEntity;
|
||||||
|
import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobNavigationPosition;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.eSpigot;
|
||||||
import com.elevatemc.spigot.util.CryptException;
|
import com.elevatemc.spigot.util.CryptException;
|
||||||
import com.google.common.collect.Queues;
|
import com.google.common.collect.Queues;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
@ -190,9 +191,18 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet> {
|
||||||
if (this.channel.isOpen()) {
|
if (this.channel.isOpen()) {
|
||||||
try {
|
try {
|
||||||
packet.a(this.m);
|
packet.a(this.m);
|
||||||
} catch (CancelledPacketHandleException cancelledpackethandleexception) {
|
|
||||||
|
|
||||||
|
if (this.m instanceof PlayerConnection) {
|
||||||
|
try {
|
||||||
|
eSpigot.getInstance().getPacketHandlers().forEach(packetHandler -> packetHandler.handleReceivedPacket((PlayerConnection) this.m, packet));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (CancelledPacketHandleException cancelledpackethandleexception) {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class PacketPlayInUseEntity implements Packet<PacketListenerPlayIn> {
|
||||||
|
|
||||||
|
public int a;
|
||||||
|
public EnumEntityUseAction action;
|
||||||
|
public Vec3D c;
|
||||||
|
|
||||||
|
public PacketPlayInUseEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
this.a = packetdataserializer.e();
|
||||||
|
this.action = packetdataserializer.a(EnumEntityUseAction.class);
|
||||||
|
if (this.action == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) {
|
||||||
|
this.c = new Vec3D( packetdataserializer.readFloat(), packetdataserializer.readFloat(), packetdataserializer.readFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.b(this.a);
|
||||||
|
packetdataserializer.a(this.action);
|
||||||
|
if (this.action == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) {
|
||||||
|
packetdataserializer.writeFloat((float)this.c.a);
|
||||||
|
packetdataserializer.writeFloat((float)this.c.b);
|
||||||
|
packetdataserializer.writeFloat((float)this.c.c);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketListenerPlayIn packetlistenerplayin) {
|
||||||
|
packetlistenerplayin.a(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity a(World world) {
|
||||||
|
return world.a(this.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnumEntityUseAction a() {
|
||||||
|
return this.action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3D b() {
|
||||||
|
return this.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EnumEntityUseAction {
|
||||||
|
INTERACT,
|
||||||
|
ATTACK,
|
||||||
|
INTERACT_AT;
|
||||||
|
|
||||||
|
private EnumEntityUseAction() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class PacketPlayOutAttachEntity implements Packet<PacketListenerPlayOut> {
|
||||||
|
|
||||||
|
public int a;
|
||||||
|
public int b;
|
||||||
|
public int c;
|
||||||
|
|
||||||
|
public PacketPlayOutAttachEntity() {}
|
||||||
|
|
||||||
|
public PacketPlayOutAttachEntity(int entity, int vehicle) {
|
||||||
|
a = 0;
|
||||||
|
b = entity;
|
||||||
|
c = vehicle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketPlayOutAttachEntity(int i, Entity entity, Entity entity1) {
|
||||||
|
this.a = i;
|
||||||
|
this.b = entity.getId();
|
||||||
|
this.c = entity1 != null ? entity1.getId() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
this.b = packetdataserializer.readInt();
|
||||||
|
this.c = packetdataserializer.readInt();
|
||||||
|
this.a = packetdataserializer.readUnsignedByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.writeInt(this.b);
|
||||||
|
packetdataserializer.writeInt(this.c);
|
||||||
|
packetdataserializer.writeByte(this.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketListenerPlayOut packetlistenerplayout) {
|
||||||
|
packetlistenerplayout.a(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class PacketPlayOutEntityMetadata implements Packet<PacketListenerPlayOut> {
|
||||||
|
|
||||||
|
public int a;
|
||||||
|
public List<DataWatcher.WatchableObject> b;
|
||||||
|
|
||||||
|
public PacketPlayOutEntityMetadata() {}
|
||||||
|
|
||||||
|
public PacketPlayOutEntityMetadata(int i, DataWatcher datawatcher, boolean flag) {
|
||||||
|
this.a = i;
|
||||||
|
if (flag) {
|
||||||
|
this.b = datawatcher.c();
|
||||||
|
} else {
|
||||||
|
this.b = datawatcher.b();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
this.a = packetdataserializer.e();
|
||||||
|
this.b = DataWatcher.b(packetdataserializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.b(this.a);
|
||||||
|
DataWatcher.a(this.b, packetdataserializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketListenerPlayOut packetlistenerplayout) {
|
||||||
|
packetlistenerplayout.a(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,312 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import com.mojang.authlib.properties.Property;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class PacketPlayOutPlayerInfo implements Packet<PacketListenerPlayOut> {
|
||||||
|
|
||||||
|
public PacketPlayOutPlayerInfo.EnumPlayerInfoAction a;
|
||||||
|
public List<PacketPlayOutPlayerInfo.PlayerInfoData> b = Lists.newArrayList();
|
||||||
|
|
||||||
|
public PacketPlayOutPlayerInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction packetplayoutplayerinfo_enumplayerinfoaction, EntityPlayer... aentityplayer) {
|
||||||
|
this.a = packetplayoutplayerinfo_enumplayerinfoaction;
|
||||||
|
EntityPlayer[] aentityplayer1 = aentityplayer;
|
||||||
|
int i = aentityplayer.length;
|
||||||
|
|
||||||
|
for (int j = 0; j < i; ++j) {
|
||||||
|
EntityPlayer entityplayer = aentityplayer1[j];
|
||||||
|
|
||||||
|
this.b.add(new PacketPlayOutPlayerInfo.PlayerInfoData(entityplayer.getProfile(),
|
||||||
|
entityplayer.ping, entityplayer.playerInteractManager.getGameMode(), entityplayer.getPlayerListName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction packetplayoutplayerinfo_enumplayerinfoaction, List<PacketPlayOutPlayerInfo.PlayerInfoData> b) {
|
||||||
|
this.a = packetplayoutplayerinfo_enumplayerinfoaction;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
public static PacketPlayOutPlayerInfo addPlayer(EntityPlayer player) {
|
||||||
|
PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo();
|
||||||
|
packet.a = EnumPlayerInfoAction.ADD_PLAYER;
|
||||||
|
PacketPlayOutPlayerInfo.PlayerInfoData playerInfoData =
|
||||||
|
new PacketPlayOutPlayerInfo.PlayerInfoData(player.getProfile(), player.ping,
|
||||||
|
player.playerInteractManager.getGameMode(), player.getPlayerListName());
|
||||||
|
packet.b.add(playerInfoData);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PacketPlayOutPlayerInfo updatePing(EntityPlayer player) {
|
||||||
|
PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo();
|
||||||
|
packet.a = EnumPlayerInfoAction.UPDATE_LATENCY;
|
||||||
|
PacketPlayOutPlayerInfo.PlayerInfoData playerInfoData =
|
||||||
|
new PacketPlayOutPlayerInfo.PlayerInfoData(player.getProfile(), player.ping,
|
||||||
|
player.playerInteractManager.getGameMode(), player.getPlayerListName());
|
||||||
|
packet.b.add(playerInfoData);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PacketPlayOutPlayerInfo updateGamemode(EntityPlayer player) {
|
||||||
|
PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo();
|
||||||
|
packet.a = EnumPlayerInfoAction.UPDATE_GAME_MODE;
|
||||||
|
PacketPlayOutPlayerInfo.PlayerInfoData playerInfoData =
|
||||||
|
new PacketPlayOutPlayerInfo.PlayerInfoData(player.getProfile(), player.ping,
|
||||||
|
player.playerInteractManager.getGameMode(), player.getPlayerListName());
|
||||||
|
packet.b.add(playerInfoData);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PacketPlayOutPlayerInfo updateDisplayName(EntityPlayer player) {
|
||||||
|
PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo();
|
||||||
|
packet.a = EnumPlayerInfoAction.UPDATE_DISPLAY_NAME;
|
||||||
|
PacketPlayOutPlayerInfo.PlayerInfoData playerInfoData =
|
||||||
|
new PacketPlayOutPlayerInfo.PlayerInfoData(player.getProfile(), player.ping,
|
||||||
|
player.playerInteractManager.getGameMode(), player.getPlayerListName());
|
||||||
|
packet.b.add(playerInfoData);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PacketPlayOutPlayerInfo removePlayer(EntityPlayer player) {
|
||||||
|
PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo();
|
||||||
|
packet.a = EnumPlayerInfoAction.REMOVE_PLAYER;
|
||||||
|
PacketPlayOutPlayerInfo.PlayerInfoData playerInfoData =
|
||||||
|
new PacketPlayOutPlayerInfo.PlayerInfoData(player.getProfile(), player.ping,
|
||||||
|
player.playerInteractManager.getGameMode(), player.getPlayerListName());
|
||||||
|
packet.b.add(playerInfoData);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
this.a = packetdataserializer.a(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.class);
|
||||||
|
int i = packetdataserializer.e();
|
||||||
|
|
||||||
|
for (int j = 0; j < i; ++j) {
|
||||||
|
GameProfile gameprofile = null;
|
||||||
|
int k = 0;
|
||||||
|
WorldSettings.EnumGamemode worldsettings_enumgamemode = null;
|
||||||
|
IChatBaseComponent ichatbasecomponent = null;
|
||||||
|
|
||||||
|
switch (PacketPlayOutPlayerInfo.SyntheticClass_1.a[this.a.ordinal()]) {
|
||||||
|
case 1:
|
||||||
|
gameprofile = new GameProfile(packetdataserializer.g(), packetdataserializer.c(16));
|
||||||
|
int l = packetdataserializer.e();
|
||||||
|
|
||||||
|
for (int i1 = 0; i1 < l; ++i1) {
|
||||||
|
String s = packetdataserializer.c(32767);
|
||||||
|
String s1 = packetdataserializer.c(32767);
|
||||||
|
|
||||||
|
if (packetdataserializer.readBoolean()) {
|
||||||
|
gameprofile.getProperties().put(s, new Property(s, s1, packetdataserializer.c(32767)));
|
||||||
|
} else {
|
||||||
|
gameprofile.getProperties().put(s, new Property(s, s1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
worldsettings_enumgamemode = WorldSettings.EnumGamemode.getById(packetdataserializer.e());
|
||||||
|
k = packetdataserializer.e();
|
||||||
|
if (packetdataserializer.readBoolean()) {
|
||||||
|
ichatbasecomponent = packetdataserializer.d();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
gameprofile = new GameProfile(packetdataserializer.g(), null);
|
||||||
|
worldsettings_enumgamemode = WorldSettings.EnumGamemode.getById(packetdataserializer.e());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
gameprofile = new GameProfile(packetdataserializer.g(), null);
|
||||||
|
k = packetdataserializer.e();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
gameprofile = new GameProfile(packetdataserializer.g(), null);
|
||||||
|
if (packetdataserializer.readBoolean()) {
|
||||||
|
ichatbasecomponent = packetdataserializer.d();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
gameprofile = new GameProfile(packetdataserializer.g(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.b.add(new PacketPlayOutPlayerInfo.PlayerInfoData(gameprofile, k, worldsettings_enumgamemode, ichatbasecomponent));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.a((Enum) this.a);
|
||||||
|
packetdataserializer.b(this.b.size());
|
||||||
|
Iterator iterator = this.b.iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
PacketPlayOutPlayerInfo.PlayerInfoData packetplayoutplayerinfo_playerinfodata = (PacketPlayOutPlayerInfo.PlayerInfoData) iterator.next();
|
||||||
|
|
||||||
|
switch (PacketPlayOutPlayerInfo.SyntheticClass_1.a[this.a.ordinal()]) {
|
||||||
|
case 1:
|
||||||
|
packetdataserializer.a(packetplayoutplayerinfo_playerinfodata.a().getId());
|
||||||
|
packetdataserializer.a(packetplayoutplayerinfo_playerinfodata.a().getName());
|
||||||
|
packetdataserializer.b(packetplayoutplayerinfo_playerinfodata.a().getProperties().size());
|
||||||
|
Iterator iterator1 = packetplayoutplayerinfo_playerinfodata.a().getProperties().values().iterator();
|
||||||
|
|
||||||
|
while (iterator1.hasNext()) {
|
||||||
|
Property property = (Property) iterator1.next();
|
||||||
|
|
||||||
|
packetdataserializer.a(property.getName());
|
||||||
|
packetdataserializer.a(property.getValue());
|
||||||
|
if (property.hasSignature()) {
|
||||||
|
packetdataserializer.writeBoolean(true);
|
||||||
|
packetdataserializer.a(property.getSignature());
|
||||||
|
} else {
|
||||||
|
packetdataserializer.writeBoolean(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
packetdataserializer.b(packetplayoutplayerinfo_playerinfodata.c().getId());
|
||||||
|
packetdataserializer.b(packetplayoutplayerinfo_playerinfodata.b());
|
||||||
|
if (packetplayoutplayerinfo_playerinfodata.d() == null) {
|
||||||
|
packetdataserializer.writeBoolean(false);
|
||||||
|
} else {
|
||||||
|
packetdataserializer.writeBoolean(true);
|
||||||
|
packetdataserializer.a(packetplayoutplayerinfo_playerinfodata.d());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
packetdataserializer.a(packetplayoutplayerinfo_playerinfodata.a().getId());
|
||||||
|
packetdataserializer.b(packetplayoutplayerinfo_playerinfodata.c().getId());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
packetdataserializer.a(packetplayoutplayerinfo_playerinfodata.a().getId());
|
||||||
|
packetdataserializer.b(packetplayoutplayerinfo_playerinfodata.b());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
packetdataserializer.a(packetplayoutplayerinfo_playerinfodata.a().getId());
|
||||||
|
if (packetplayoutplayerinfo_playerinfodata.d() == null) {
|
||||||
|
packetdataserializer.writeBoolean(false);
|
||||||
|
} else {
|
||||||
|
packetdataserializer.writeBoolean(true);
|
||||||
|
packetdataserializer.a(packetplayoutplayerinfo_playerinfodata.d());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
packetdataserializer.a(packetplayoutplayerinfo_playerinfodata.a().getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketListenerPlayOut packetlistenerplayout) {
|
||||||
|
packetlistenerplayout.a(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return Objects.toStringHelper(this).add("action", this.a).add("entries", this.b).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class SyntheticClass_1 {
|
||||||
|
|
||||||
|
static final int[] a = new int[PacketPlayOutPlayerInfo.EnumPlayerInfoAction.values().length];
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
PacketPlayOutPlayerInfo.SyntheticClass_1.a[PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER.ordinal()] = 1;
|
||||||
|
} catch (NoSuchFieldError ignored) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
PacketPlayOutPlayerInfo.SyntheticClass_1.a[PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_GAME_MODE.ordinal()] = 2;
|
||||||
|
} catch (NoSuchFieldError ignored) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
PacketPlayOutPlayerInfo.SyntheticClass_1.a[PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_LATENCY.ordinal()] = 3;
|
||||||
|
} catch (NoSuchFieldError ignored) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
PacketPlayOutPlayerInfo.SyntheticClass_1.a[PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_DISPLAY_NAME.ordinal()] = 4;
|
||||||
|
} catch (NoSuchFieldError ignored) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
PacketPlayOutPlayerInfo.SyntheticClass_1.a[PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER.ordinal()] = 5;
|
||||||
|
} catch (NoSuchFieldError ignored) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PlayerInfoData {
|
||||||
|
|
||||||
|
private final int b;
|
||||||
|
private final WorldSettings.EnumGamemode c;
|
||||||
|
private final GameProfile d;
|
||||||
|
private final IChatBaseComponent e;
|
||||||
|
|
||||||
|
public PlayerInfoData(GameProfile gameprofile, int i, WorldSettings.EnumGamemode worldsettings_enumgamemode, IChatBaseComponent ichatbasecomponent) {
|
||||||
|
this.d = gameprofile;
|
||||||
|
this.b = i;
|
||||||
|
this.c = worldsettings_enumgamemode;
|
||||||
|
this.e = ichatbasecomponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameProfile a() {
|
||||||
|
return this.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int b() {
|
||||||
|
return this.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WorldSettings.EnumGamemode c() {
|
||||||
|
return this.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IChatBaseComponent d() {
|
||||||
|
return this.e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return Objects.toStringHelper(this)
|
||||||
|
.add("latency", this.b)
|
||||||
|
.add("gameMode", this.c)
|
||||||
|
.add("profile", this.d)
|
||||||
|
.add("displayName", this.e == null ? null : IChatBaseComponent.ChatSerializer.a(this.e)).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EnumPlayerInfoAction {
|
||||||
|
|
||||||
|
ADD_PLAYER, UPDATE_GAME_MODE, UPDATE_LATENCY, UPDATE_DISPLAY_NAME, REMOVE_PLAYER;
|
||||||
|
|
||||||
|
EnumPlayerInfoAction() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImHacking start
|
||||||
|
public GameProfile getPlayer() {
|
||||||
|
return this.b.get(this.b.size() - 1).d;
|
||||||
|
}
|
||||||
|
// ImHacking end
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class PacketPlayOutScoreboardTeam implements Packet<PacketListenerPlayOut> {
|
||||||
|
|
||||||
|
public String a = "";
|
||||||
|
public String b = "";
|
||||||
|
public String c = "";
|
||||||
|
public String d = "";
|
||||||
|
public String e;
|
||||||
|
public int f;
|
||||||
|
public Collection<String> g;
|
||||||
|
public int h;
|
||||||
|
public int i;
|
||||||
|
|
||||||
|
public PacketPlayOutScoreboardTeam() {
|
||||||
|
this.e = ScoreboardTeamBase.EnumNameTagVisibility.ALWAYS.e;
|
||||||
|
this.f = -1;
|
||||||
|
this.g = Lists.newArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketPlayOutScoreboardTeam(ScoreboardTeam scoreboardteam, int i) {
|
||||||
|
this.e = ScoreboardTeamBase.EnumNameTagVisibility.ALWAYS.e;
|
||||||
|
this.f = -1;
|
||||||
|
this.g = Lists.newArrayList();
|
||||||
|
this.a = scoreboardteam.getName();
|
||||||
|
this.h = i;
|
||||||
|
|
||||||
|
if (i == 0 || i == 2) {
|
||||||
|
this.b = scoreboardteam.getDisplayName();
|
||||||
|
this.c = scoreboardteam.getPrefix();
|
||||||
|
this.d = scoreboardteam.getSuffix();
|
||||||
|
this.i = scoreboardteam.packOptionData();
|
||||||
|
this.e = scoreboardteam.getNameTagVisibility().e;
|
||||||
|
this.f = scoreboardteam.l().b();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
this.g.addAll(scoreboardteam.getPlayerNameSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketPlayOutScoreboardTeam(ScoreboardTeam scoreboardteam, Collection<String> collection, int i) {
|
||||||
|
this.e = ScoreboardTeamBase.EnumNameTagVisibility.ALWAYS.e;
|
||||||
|
this.f = -1;
|
||||||
|
this.g = Lists.newArrayList();
|
||||||
|
if (i != 3 && i != 4) {
|
||||||
|
throw new IllegalArgumentException("Method must be join or leave for player constructor");
|
||||||
|
} else if (collection != null && !collection.isEmpty()) {
|
||||||
|
this.h = i;
|
||||||
|
this.a = scoreboardteam.getName();
|
||||||
|
this.g.addAll(collection);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Players cannot be null/empty");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
this.a = packetdataserializer.c(16);
|
||||||
|
this.h = packetdataserializer.readByte();
|
||||||
|
if (this.h == 0 || this.h == 2) {
|
||||||
|
this.b = packetdataserializer.c(32);
|
||||||
|
this.c = packetdataserializer.c(16);
|
||||||
|
this.d = packetdataserializer.c(16);
|
||||||
|
this.i = packetdataserializer.readByte();
|
||||||
|
this.e = packetdataserializer.c(32);
|
||||||
|
this.f = packetdataserializer.readByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.h == 0 || this.h == 3 || this.h == 4) {
|
||||||
|
int i = packetdataserializer.e();
|
||||||
|
|
||||||
|
for (int j = 0; j < i; ++j) {
|
||||||
|
this.g.add(packetdataserializer.c(40));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.a(this.a);
|
||||||
|
packetdataserializer.writeByte(this.h);
|
||||||
|
|
||||||
|
if (this.h == 0 || this.h == 2) {
|
||||||
|
packetdataserializer.a(this.b);
|
||||||
|
packetdataserializer.a(this.c);
|
||||||
|
packetdataserializer.a(this.d);
|
||||||
|
packetdataserializer.writeByte(this.i);
|
||||||
|
packetdataserializer.a(this.e);
|
||||||
|
packetdataserializer.writeByte(this.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.h == 0 || this.h == 3 || this.h == 4) {
|
||||||
|
packetdataserializer.b(this.g.size());
|
||||||
|
Iterator iterator = this.g.iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
String s = (String) iterator.next();
|
||||||
|
|
||||||
|
packetdataserializer.a(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketListenerPlayOut packetlistenerplayout) {
|
||||||
|
packetlistenerplayout.a(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class PacketPlayOutSpawnEntity implements Packet<PacketListenerPlayOut> {
|
||||||
|
|
||||||
|
public int a;
|
||||||
|
public int b;
|
||||||
|
public int c;
|
||||||
|
public int d;
|
||||||
|
private int e;
|
||||||
|
private int f;
|
||||||
|
private int g;
|
||||||
|
private int h;
|
||||||
|
private int i;
|
||||||
|
private int j;
|
||||||
|
private int k;
|
||||||
|
|
||||||
|
public PacketPlayOutSpawnEntity() {}
|
||||||
|
|
||||||
|
public PacketPlayOutSpawnEntity(Entity entity, int i) {
|
||||||
|
this(entity, i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketPlayOutSpawnEntity(Entity entity, int i, int j) {
|
||||||
|
this.a = entity.getId();
|
||||||
|
this.b = MathHelper.floor(entity.locX * 32.0D);
|
||||||
|
this.c = MathHelper.floor(entity.locY * 32.0D);
|
||||||
|
this.d = MathHelper.floor(entity.locZ * 32.0D);
|
||||||
|
this.h = MathHelper.d(entity.pitch * 256.0F / 360.0F);
|
||||||
|
this.i = MathHelper.d(entity.yaw * 256.0F / 360.0F);
|
||||||
|
this.j = i;
|
||||||
|
this.k = j;
|
||||||
|
if (j > 0) {
|
||||||
|
double d0 = entity.motX;
|
||||||
|
double d1 = entity.motY;
|
||||||
|
double d2 = entity.motZ;
|
||||||
|
double d3 = 3.9D;
|
||||||
|
|
||||||
|
if (d0 < -d3) {
|
||||||
|
d0 = -d3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d1 < -d3) {
|
||||||
|
d1 = -d3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d2 < -d3) {
|
||||||
|
d2 = -d3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d0 > d3) {
|
||||||
|
d0 = d3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d1 > d3) {
|
||||||
|
d1 = d3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d2 > d3) {
|
||||||
|
d2 = d3;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.e = (int) (d0 * 8000.0D);
|
||||||
|
this.f = (int) (d1 * 8000.0D);
|
||||||
|
this.g = (int) (d2 * 8000.0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
this.a = packetdataserializer.e();
|
||||||
|
this.j = packetdataserializer.readByte();
|
||||||
|
this.b = packetdataserializer.readInt();
|
||||||
|
this.c = packetdataserializer.readInt();
|
||||||
|
this.d = packetdataserializer.readInt();
|
||||||
|
this.h = packetdataserializer.readByte();
|
||||||
|
this.i = packetdataserializer.readByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.b(this.a);
|
||||||
|
packetdataserializer.writeByte(this.j);
|
||||||
|
switch (this.k) {
|
||||||
|
case 0: {
|
||||||
|
this.d -= 32;
|
||||||
|
this.i = 128;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
this.b += 32;
|
||||||
|
this.i = 64;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
this.d += 32;
|
||||||
|
this.i = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
this.b -= 32;
|
||||||
|
this.i = 192;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packetdataserializer.writeInt(this.b);
|
||||||
|
packetdataserializer.writeInt(this.c);
|
||||||
|
packetdataserializer.writeInt(this.d);
|
||||||
|
packetdataserializer.writeByte(this.h);
|
||||||
|
packetdataserializer.writeByte(this.i);
|
||||||
|
packetdataserializer.writeInt(this.k);
|
||||||
|
if (this.k > 0) {
|
||||||
|
packetdataserializer.writeShort(this.e);
|
||||||
|
packetdataserializer.writeShort(this.f);
|
||||||
|
packetdataserializer.writeShort(this.g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b_old(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.b(this.a);
|
||||||
|
packetdataserializer.writeByte(this.j);
|
||||||
|
packetdataserializer.writeInt(this.b);
|
||||||
|
packetdataserializer.writeInt(this.c);
|
||||||
|
packetdataserializer.writeInt(this.d);
|
||||||
|
packetdataserializer.writeByte(this.h);
|
||||||
|
packetdataserializer.writeByte(this.i);
|
||||||
|
packetdataserializer.writeInt(this.k);
|
||||||
|
if (this.k > 0) {
|
||||||
|
packetdataserializer.writeShort(this.e);
|
||||||
|
packetdataserializer.writeShort(this.f);
|
||||||
|
packetdataserializer.writeShort(this.g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketListenerPlayOut packetlistenerplayout) {
|
||||||
|
packetlistenerplayout.a(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(int i) {
|
||||||
|
this.b = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(int i) {
|
||||||
|
this.c = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void c(int i) {
|
||||||
|
this.d = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void d(int i) {
|
||||||
|
this.e = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void e(int i) {
|
||||||
|
this.f = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void f(int i) {
|
||||||
|
this.g = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class PacketPlayOutSpawnEntityLiving implements Packet<PacketListenerPlayOut> {
|
||||||
|
|
||||||
|
public int id;
|
||||||
|
public int type;
|
||||||
|
public int x;
|
||||||
|
public int y;
|
||||||
|
public int z;
|
||||||
|
public int motionX;
|
||||||
|
public int motionY;
|
||||||
|
public int motionZ;
|
||||||
|
public byte yaw;
|
||||||
|
public byte pitch;
|
||||||
|
public byte headYaw;
|
||||||
|
public DataWatcher l;
|
||||||
|
public List<DataWatcher.WatchableObject> m;
|
||||||
|
|
||||||
|
public PacketPlayOutSpawnEntityLiving() {}
|
||||||
|
|
||||||
|
public PacketPlayOutSpawnEntityLiving(EntityLiving entityliving) {
|
||||||
|
this.id = entityliving.getId();
|
||||||
|
this.type = (byte) EntityTypes.a(entityliving);
|
||||||
|
this.x = MathHelper.floor(entityliving.locX * 32.0D);
|
||||||
|
this.y = MathHelper.floor(entityliving.locY * 32.0D);
|
||||||
|
this.z = MathHelper.floor(entityliving.locZ * 32.0D);
|
||||||
|
this.yaw = (byte) ((int) (entityliving.yaw * 256.0F / 360.0F));
|
||||||
|
this.pitch = (byte) ((int) (entityliving.pitch * 256.0F / 360.0F));
|
||||||
|
this.headYaw = (byte) ((int) (entityliving.aK * 256.0F / 360.0F));
|
||||||
|
double d0 = 3.9D;
|
||||||
|
double d1 = entityliving.motX;
|
||||||
|
double d2 = entityliving.motY;
|
||||||
|
double d3 = entityliving.motZ;
|
||||||
|
|
||||||
|
if (d1 < -d0) {
|
||||||
|
d1 = -d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d2 < -d0) {
|
||||||
|
d2 = -d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d3 < -d0) {
|
||||||
|
d3 = -d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d1 > d0) {
|
||||||
|
d1 = d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d2 > d0) {
|
||||||
|
d2 = d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d3 > d0) {
|
||||||
|
d3 = d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.motionX = (int) (d1 * 8000.0D);
|
||||||
|
this.motionY = (int) (d2 * 8000.0D);
|
||||||
|
this.motionZ = (int) (d3 * 8000.0D);
|
||||||
|
this.l = entityliving.getDataWatcher();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
this.id = packetdataserializer.e();
|
||||||
|
this.type = packetdataserializer.readByte() & 255;
|
||||||
|
this.x = packetdataserializer.readInt();
|
||||||
|
this.y = packetdataserializer.readInt();
|
||||||
|
this.z = packetdataserializer.readInt();
|
||||||
|
this.yaw = packetdataserializer.readByte();
|
||||||
|
this.pitch = packetdataserializer.readByte();
|
||||||
|
this.headYaw = packetdataserializer.readByte();
|
||||||
|
this.motionX = packetdataserializer.readShort();
|
||||||
|
this.motionY = packetdataserializer.readShort();
|
||||||
|
this.motionZ = packetdataserializer.readShort();
|
||||||
|
this.m = DataWatcher.b(packetdataserializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.b(this.id);
|
||||||
|
packetdataserializer.writeByte(this.type & 255);
|
||||||
|
packetdataserializer.writeInt(this.x);
|
||||||
|
packetdataserializer.writeInt(this.y);
|
||||||
|
packetdataserializer.writeInt(this.z);
|
||||||
|
packetdataserializer.writeByte(this.yaw);
|
||||||
|
packetdataserializer.writeByte(this.pitch);
|
||||||
|
packetdataserializer.writeByte(this.headYaw);
|
||||||
|
packetdataserializer.writeShort(this.motionX);
|
||||||
|
packetdataserializer.writeShort(this.motionY);
|
||||||
|
packetdataserializer.writeShort(this.motionZ);
|
||||||
|
this.l.a(packetdataserializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketListenerPlayOut packetlistenerplayout) {
|
||||||
|
packetlistenerplayout.a(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class PacketPlayOutSpawnEntityWeather implements Packet<PacketListenerPlayOut> {
|
||||||
|
|
||||||
|
private int a;
|
||||||
|
private int b;
|
||||||
|
private int c;
|
||||||
|
private int d;
|
||||||
|
private int e;
|
||||||
|
|
||||||
|
public PacketPlayOutSpawnEntityWeather() {}
|
||||||
|
|
||||||
|
public PacketPlayOutSpawnEntityWeather(Entity entity) {
|
||||||
|
this.a = entity.getId();
|
||||||
|
this.b = MathHelper.floor(entity.locX * 32.0D);
|
||||||
|
this.c = MathHelper.floor(entity.locY * 32.0D);
|
||||||
|
this.d = MathHelper.floor(entity.locZ * 32.0D);
|
||||||
|
if (entity instanceof EntityLightning) {
|
||||||
|
this.e = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
this.a = packetdataserializer.e();
|
||||||
|
this.e = packetdataserializer.readByte();
|
||||||
|
this.b = packetdataserializer.readInt();
|
||||||
|
this.c = packetdataserializer.readInt();
|
||||||
|
this.d = packetdataserializer.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.b(this.a);
|
||||||
|
packetdataserializer.writeByte(this.e);
|
||||||
|
packetdataserializer.writeInt(this.b);
|
||||||
|
packetdataserializer.writeInt(this.c);
|
||||||
|
packetdataserializer.writeInt(this.d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketListenerPlayOut packetlistenerplayout) {
|
||||||
|
packetlistenerplayout.a(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class PacketPlayOutWorldParticles implements Packet<PacketListenerPlayOut> {
|
||||||
|
|
||||||
|
public EnumParticle a;
|
||||||
|
public float b;
|
||||||
|
public float c;
|
||||||
|
public float d;
|
||||||
|
public float e;
|
||||||
|
public float f;
|
||||||
|
public float g;
|
||||||
|
public float h;
|
||||||
|
public int i;
|
||||||
|
public boolean j;
|
||||||
|
public int[] k;
|
||||||
|
|
||||||
|
public PacketPlayOutWorldParticles() {}
|
||||||
|
|
||||||
|
public PacketPlayOutWorldParticles(EnumParticle enumparticle, boolean flag, float f, float f1, float f2, float f3, float f4, float f5, float f6, int i, int... aint) {
|
||||||
|
this.a = enumparticle;
|
||||||
|
this.j = flag;
|
||||||
|
this.b = f;
|
||||||
|
this.c = f1;
|
||||||
|
this.d = f2;
|
||||||
|
this.e = f3;
|
||||||
|
this.f = f4;
|
||||||
|
this.g = f5;
|
||||||
|
this.h = f6;
|
||||||
|
this.i = i;
|
||||||
|
this.k = aint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
this.a = EnumParticle.a(packetdataserializer.readInt());
|
||||||
|
if (this.a == null) {
|
||||||
|
this.a = EnumParticle.BARRIER;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.j = packetdataserializer.readBoolean();
|
||||||
|
this.b = packetdataserializer.readFloat();
|
||||||
|
this.c = packetdataserializer.readFloat();
|
||||||
|
this.d = packetdataserializer.readFloat();
|
||||||
|
this.e = packetdataserializer.readFloat();
|
||||||
|
this.f = packetdataserializer.readFloat();
|
||||||
|
this.g = packetdataserializer.readFloat();
|
||||||
|
this.h = packetdataserializer.readFloat();
|
||||||
|
this.i = packetdataserializer.readInt();
|
||||||
|
int i = this.a.d();
|
||||||
|
|
||||||
|
this.k = new int[i];
|
||||||
|
|
||||||
|
for (int j = 0; j < i; ++j) {
|
||||||
|
this.k[j] = packetdataserializer.e();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||||
|
packetdataserializer.writeInt(this.a.c());
|
||||||
|
packetdataserializer.writeBoolean(this.j);
|
||||||
|
packetdataserializer.writeFloat(this.b);
|
||||||
|
packetdataserializer.writeFloat(this.c);
|
||||||
|
packetdataserializer.writeFloat(this.d);
|
||||||
|
packetdataserializer.writeFloat(this.e);
|
||||||
|
packetdataserializer.writeFloat(this.f);
|
||||||
|
packetdataserializer.writeFloat(this.g);
|
||||||
|
packetdataserializer.writeFloat(this.h);
|
||||||
|
packetdataserializer.writeInt(this.i);
|
||||||
|
|
||||||
|
int i = this.a.d();
|
||||||
|
for (int j = 0; j < i; ++j) {
|
||||||
|
packetdataserializer.b(this.k[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PacketListenerPlayOut packetlistenerplayout) {
|
||||||
|
packetlistenerplayout.a(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -216,4 +216,20 @@ public class PathfinderNormal extends PathfinderAbstract {
|
||||||
public boolean e() {
|
public boolean e() {
|
||||||
return this.h;
|
return this.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getB() {
|
||||||
|
return this.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getC() {
|
||||||
|
return this.g;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getD() {
|
||||||
|
return this.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getE() {
|
||||||
|
return this.h;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,13 @@ public class PlayerChunkMap {
|
||||||
public static int getFurthestViewableBlock(int i) {
|
public static int getFurthestViewableBlock(int i) {
|
||||||
return i * 16 - 16;
|
return i * 16 - 16;
|
||||||
}
|
}
|
||||||
|
public void resend(int chunkX, int chunkZ) {
|
||||||
|
PlayerChunk chunk = this.a(chunkX, chunkZ, false);
|
||||||
|
|
||||||
|
if (chunk != null) {
|
||||||
|
chunk.resend();
|
||||||
|
}
|
||||||
|
}
|
||||||
class PlayerChunk {
|
class PlayerChunk {
|
||||||
|
|
||||||
private final List<EntityPlayer> b = Lists.newArrayList();
|
private final List<EntityPlayer> b = Lists.newArrayList();
|
||||||
|
@ -372,7 +378,13 @@ public class PlayerChunkMap {
|
||||||
this.location = new ChunkCoordIntPair(i, j);
|
this.location = new ChunkCoordIntPair(i, j);
|
||||||
PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(i, j, loadedRunnable); // CraftBukkit
|
PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(i, j, loadedRunnable); // CraftBukkit
|
||||||
}
|
}
|
||||||
|
public void resend() {
|
||||||
|
if (this.dirtyCount == 0) {
|
||||||
|
PlayerChunkMap.this.e.add(this);
|
||||||
|
}
|
||||||
|
this.dirtyCount = 64;
|
||||||
|
this.f = 0xFFFF;
|
||||||
|
}
|
||||||
public void a(final EntityPlayer entityplayer) { // CraftBukkit - added final to argument
|
public void a(final EntityPlayer entityplayer) { // CraftBukkit - added final to argument
|
||||||
if (this.b.contains(entityplayer)) {
|
if (this.b.contains(entityplayer)) {
|
||||||
PlayerChunkMap.a.debug("Failed to add player. {} already is in chunk {}, {}", new Object[] { entityplayer, Integer.valueOf(this.location.x), Integer.valueOf(this.location.z)});
|
PlayerChunkMap.a.debug("Failed to add player. {} already is in chunk {}, {}", new Object[] { entityplayer, Integer.valueOf(this.location.x), Integer.valueOf(this.location.z)});
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.eSpigot;
|
||||||
|
import com.elevatemc.spigot.handler.MovementHandler;
|
||||||
|
import com.elevatemc.spigot.handler.PacketHandler;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.primitives.Doubles;
|
import com.google.common.primitives.Doubles;
|
||||||
import com.google.common.primitives.Floats;
|
import com.google.common.primitives.Floats;
|
||||||
|
@ -263,6 +266,26 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||||
double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2);
|
double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2);
|
||||||
float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch());
|
float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch());
|
||||||
|
|
||||||
|
if (packetplayinflying.hasPos && delta > 0.0D && this.checkMovement && !this.player.dead) {
|
||||||
|
for (MovementHandler handler : eSpigot.getInstance().getMovementHandlers()) {
|
||||||
|
try {
|
||||||
|
handler.handleUpdateLocation(player, to, from, packetplayinflying);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packetplayinflying.hasLook && deltaAngle > 0.0F && this.checkMovement && !this.player.dead) {
|
||||||
|
for (MovementHandler handler : eSpigot.getInstance().getMovementHandlers()) {
|
||||||
|
try {
|
||||||
|
handler.handleUpdateRotation(player, to, from, packetplayinflying);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((delta > 1f / 256 || deltaAngle > 10f) && (this.checkMovement && !this.player.dead)) {
|
if ((delta > 1f / 256 || deltaAngle > 10f) && (this.checkMovement && !this.player.dead)) {
|
||||||
this.lastPosX = to.getX();
|
this.lastPosX = to.getX();
|
||||||
this.lastPosY = to.getY();
|
this.lastPosY = to.getY();
|
||||||
|
@ -920,7 +943,12 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.networkManager.handle(packet);
|
// Loop through normal handlers
|
||||||
|
for (PacketHandler handler : eSpigot.getInstance().getPacketHandlers()) {
|
||||||
|
handler.handleSentPacket(this, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.networkManager.a((EnumProtocol) packet);
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
CrashReport crashreport = CrashReport.a(throwable, "Sending packet");
|
CrashReport crashreport = CrashReport.a(throwable, "Sending packet");
|
||||||
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Packet being sent");
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Packet being sent");
|
||||||
|
|
|
@ -890,10 +890,11 @@ public abstract class PlayerList {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (++this.u > 600) {
|
// ImHacking - Useless feature.
|
||||||
this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_LATENCY, this.players));
|
/*if (++this.u > 600) {
|
||||||
|
this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_LATENCY, (EntityPlayer) this.players));
|
||||||
this.u = 0;
|
this.u = 0;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ public abstract class TileEntity {
|
||||||
private static Map<String, Class<? extends TileEntity>> f = Maps.newHashMap();
|
private static Map<String, Class<? extends TileEntity>> f = Maps.newHashMap();
|
||||||
private static Map<Class<? extends TileEntity>, String> g = Maps.newHashMap();
|
private static Map<Class<? extends TileEntity>, String> g = Maps.newHashMap();
|
||||||
protected World world;
|
protected World world;
|
||||||
protected BlockPosition position;
|
public BlockPosition position;
|
||||||
protected boolean d;
|
protected boolean d;
|
||||||
private int h;
|
private int h;
|
||||||
protected Block e;
|
protected Block e;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.craftbukkit.CraftServer;
|
import org.bukkit.craftbukkit.CraftServer;
|
||||||
import org.bukkit.craftbukkit.CraftWorld;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
@ -2042,6 +2043,30 @@ public abstract class World implements IBlockAccess {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImHacking start
|
||||||
|
public boolean boundingBoxContainsMaterials(AxisAlignedBB boundingBox, Set<Block> matching) {
|
||||||
|
int i = MathHelper.floor(boundingBox.a);
|
||||||
|
int j = MathHelper.floor(boundingBox.d + 1.0D);
|
||||||
|
int k = MathHelper.floor(boundingBox.b);
|
||||||
|
int l = MathHelper.floor(boundingBox.e + 1.0D);
|
||||||
|
int i1 = MathHelper.floor(boundingBox.c);
|
||||||
|
int j1 = MathHelper.floor(boundingBox.f + 1.0D);
|
||||||
|
BlockPosition.MutableBlockPosition blockPosition = new BlockPosition.MutableBlockPosition();
|
||||||
|
|
||||||
|
for (int k1 = i; k1 < j; ++k1) {
|
||||||
|
for (int l1 = k; l1 < l; ++l1) {
|
||||||
|
for (int i2 = i1; i2 < j1; ++i2) {
|
||||||
|
if (matching.contains(this.getType(blockPosition.c(k1, l1, i2)).getBlock())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// ImHacking end
|
||||||
|
|
||||||
public boolean b(AxisAlignedBB axisalignedbb, Material material) {
|
public boolean b(AxisAlignedBB axisalignedbb, Material material) {
|
||||||
int i = MathHelper.floor(axisalignedbb.a);
|
int i = MathHelper.floor(axisalignedbb.a);
|
||||||
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
||||||
|
@ -3171,11 +3196,11 @@ public abstract class World implements IBlockAccess {
|
||||||
|
|
||||||
return blockposition;
|
return blockposition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void B(BlockPosition blockposition) {
|
public void B(BlockPosition blockposition) {
|
||||||
this.worldData.setSpawn(blockposition);
|
this.worldData.setSpawn(new Location(getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean a(EntityHuman entityhuman, BlockPosition blockposition) {
|
public boolean a(EntityHuman entityhuman, BlockPosition blockposition) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package net.minecraft.server;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.event.weather.ThunderChangeEvent;
|
import org.bukkit.event.weather.ThunderChangeEvent;
|
||||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
@ -13,9 +14,11 @@ public class WorldData {
|
||||||
private long b;
|
private long b;
|
||||||
private WorldType c;
|
private WorldType c;
|
||||||
private String d;
|
private String d;
|
||||||
private int e;
|
private double e;
|
||||||
private int f;
|
private double f;
|
||||||
private int g;
|
private double g;
|
||||||
|
private float yaw;
|
||||||
|
private float pitch;
|
||||||
private long h;
|
private long h;
|
||||||
private long i;
|
private long i;
|
||||||
private long j;
|
private long j;
|
||||||
|
@ -108,6 +111,15 @@ public class WorldData {
|
||||||
this.e = nbttagcompound.getInt("SpawnX");
|
this.e = nbttagcompound.getInt("SpawnX");
|
||||||
this.f = nbttagcompound.getInt("SpawnY");
|
this.f = nbttagcompound.getInt("SpawnY");
|
||||||
this.g = nbttagcompound.getInt("SpawnZ");
|
this.g = nbttagcompound.getInt("SpawnZ");
|
||||||
|
// ImHacking Start - Add yaw and pitch to spawns
|
||||||
|
if (nbttagcompound.hasKey("SpawnYaw")) {
|
||||||
|
this.yaw = nbttagcompound.getFloat("SpawnYaw");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbttagcompound.hasKey("SpawnPitch")) {
|
||||||
|
this.pitch = nbttagcompound.getFloat("SpawnPitch");
|
||||||
|
}
|
||||||
|
// ImHacking End
|
||||||
this.h = nbttagcompound.getLong("Time");
|
this.h = nbttagcompound.getLong("Time");
|
||||||
if (nbttagcompound.hasKeyOfType("DayTime", 99)) {
|
if (nbttagcompound.hasKeyOfType("DayTime", 99)) {
|
||||||
this.i = nbttagcompound.getLong("DayTime");
|
this.i = nbttagcompound.getLong("DayTime");
|
||||||
|
@ -292,9 +304,13 @@ public class WorldData {
|
||||||
nbttagcompound.setString("generatorOptions", this.d);
|
nbttagcompound.setString("generatorOptions", this.d);
|
||||||
nbttagcompound.setInt("GameType", this.u.getId());
|
nbttagcompound.setInt("GameType", this.u.getId());
|
||||||
nbttagcompound.setBoolean("MapFeatures", this.v);
|
nbttagcompound.setBoolean("MapFeatures", this.v);
|
||||||
nbttagcompound.setInt("SpawnX", this.e);
|
nbttagcompound.setDouble("SpawnX", this.e);
|
||||||
nbttagcompound.setInt("SpawnY", this.f);
|
nbttagcompound.setDouble("SpawnY", this.f);
|
||||||
nbttagcompound.setInt("SpawnZ", this.g);
|
nbttagcompound.setDouble("SpawnZ", this.g);
|
||||||
|
// ImHacking Start
|
||||||
|
nbttagcompound.setFloat("SpawnYaw", this.yaw);
|
||||||
|
nbttagcompound.setFloat("SpawnPitch", this.pitch);
|
||||||
|
// ImHacking End
|
||||||
nbttagcompound.setLong("Time", this.h);
|
nbttagcompound.setLong("Time", this.h);
|
||||||
nbttagcompound.setLong("DayTime", this.i);
|
nbttagcompound.setLong("DayTime", this.i);
|
||||||
nbttagcompound.setLong("SizeOnDisk", this.k);
|
nbttagcompound.setLong("SizeOnDisk", this.k);
|
||||||
|
@ -334,15 +350,15 @@ public class WorldData {
|
||||||
return this.b;
|
return this.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int c() {
|
public double c() {
|
||||||
return this.e;
|
return this.e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int d() {
|
public double d() {
|
||||||
return this.f;
|
return this.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int e() {
|
public double e() {
|
||||||
return this.g;
|
return this.g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,11 +382,15 @@ public class WorldData {
|
||||||
this.i = i;
|
this.i = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSpawn(BlockPosition blockposition) {
|
// ImHacking Start - Add yaw and pitch to spawns
|
||||||
this.e = blockposition.getX();
|
public void setSpawn(Location location) {
|
||||||
this.f = blockposition.getY();
|
this.e = location.getX();
|
||||||
this.g = blockposition.getZ();
|
this.f = location.getY();
|
||||||
|
this.g = location.getZ();
|
||||||
|
this.yaw = location.getYaw();
|
||||||
|
this.pitch = location.getPitch();
|
||||||
}
|
}
|
||||||
|
// ImHacking End
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.n;
|
return this.n;
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
public abstract class WorldProvider {
|
||||||
|
|
||||||
|
public static final float[] a = new float[]{1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F};
|
||||||
|
|
||||||
|
protected World b;
|
||||||
|
private WorldType type;
|
||||||
|
private String i;
|
||||||
|
protected WorldChunkManager c;
|
||||||
|
protected boolean d;
|
||||||
|
public boolean e;
|
||||||
|
protected final float[] f = new float[16];
|
||||||
|
protected int dimension;
|
||||||
|
private final float[] j = new float[4];
|
||||||
|
|
||||||
|
public WorldProvider() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void a(World var1) {
|
||||||
|
this.b = var1;
|
||||||
|
this.type = var1.getWorldData().getType();
|
||||||
|
this.i = var1.getWorldData().getGeneratorOptions();
|
||||||
|
this.b();
|
||||||
|
this.a();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void a() {
|
||||||
|
float var1 = 0.0F;
|
||||||
|
|
||||||
|
for(int var2 = 0; var2 <= 15; ++var2) {
|
||||||
|
float var3 = 1.0F - (float)var2 / 15.0F;
|
||||||
|
this.f[var2] = (1.0F - var3) / (var3 * 3.0F + 1.0F) * (1.0F - var1) + var1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void b() {
|
||||||
|
WorldType var1 = this.b.getWorldData().getType();
|
||||||
|
if (var1 == WorldType.FLAT) {
|
||||||
|
WorldGenFlatInfo var2 = WorldGenFlatInfo.a(this.b.getWorldData().getGeneratorOptions());
|
||||||
|
this.c = new WorldChunkManagerHell(BiomeBase.getBiome(var2.a(), BiomeBase.ad), 0.5F);
|
||||||
|
} else if (var1 == WorldType.DEBUG_ALL_BLOCK_STATES) {
|
||||||
|
this.c = new WorldChunkManagerHell(BiomeBase.PLAINS, 0.0F);
|
||||||
|
} else {
|
||||||
|
this.c = new WorldChunkManager(this.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public IChunkProvider getChunkProvider() {
|
||||||
|
if (this.type == WorldType.FLAT) {
|
||||||
|
return new ChunkProviderFlat(this.b, this.b.getSeed(), this.b.getWorldData().shouldGenerateMapFeatures(), this.i);
|
||||||
|
} else if (this.type == WorldType.DEBUG_ALL_BLOCK_STATES) {
|
||||||
|
return new ChunkProviderDebug(this.b);
|
||||||
|
} else {
|
||||||
|
return this.type == WorldType.CUSTOMIZED ? new ChunkProviderGenerate(this.b, this.b.getSeed(), this.b.getWorldData().shouldGenerateMapFeatures(), this.i) : new ChunkProviderGenerate(this.b, this.b.getSeed(), this.b.getWorldData().shouldGenerateMapFeatures(), this.i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canSpawn(int var1, int var2) {
|
||||||
|
return this.b.c(new BlockPosition(var1, 0, var2)) == Blocks.GRASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float a(long var1, float var3) {
|
||||||
|
int var4 = (int)(var1 % 24000L);
|
||||||
|
float var5 = ((float)var4 + var3) / 24000.0F - 0.25F;
|
||||||
|
if (var5 < 0.0F) {
|
||||||
|
++var5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var5 > 1.0F) {
|
||||||
|
--var5;
|
||||||
|
}
|
||||||
|
|
||||||
|
float var6 = var5;
|
||||||
|
var5 = 1.0F - (float)((Math.cos((double)var5 * 3.141592653589793D) + 1.0D) / 2.0D);
|
||||||
|
var5 = var6 + (var5 - var6) / 3.0F;
|
||||||
|
return var5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int a(long var1) {
|
||||||
|
return (int)(var1 / 24000L % 8L + 8L) % 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean d() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean e() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WorldProvider byDimension(int var0) {
|
||||||
|
if (var0 == -1) {
|
||||||
|
return new WorldProviderHell();
|
||||||
|
} else if (var0 == 0) {
|
||||||
|
return new WorldProviderNormal();
|
||||||
|
} else {
|
||||||
|
return var0 == 1 ? new WorldProviderTheEnd() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPosition h() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSeaLevel() {
|
||||||
|
return this.type == WorldType.FLAT ? 4 : this.b.F() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
public abstract String getSuffix();
|
||||||
|
|
||||||
|
public WorldChunkManager m() {
|
||||||
|
return this.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean n() {
|
||||||
|
return this.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean o() {
|
||||||
|
return this.e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] p() {
|
||||||
|
return this.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDimension() {
|
||||||
|
return this.dimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WorldBorder getWorldBorder() {
|
||||||
|
return new WorldBorder();
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ import org.apache.logging.log4j.Logger;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.WeatherType;
|
import org.bukkit.WeatherType;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.craftbukkit.util.LongHash;
|
import org.bukkit.craftbukkit.util.LongHash;
|
||||||
|
@ -33,8 +34,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||||
private final MinecraftServer server;
|
private final MinecraftServer server;
|
||||||
public EntityTracker tracker;
|
public EntityTracker tracker;
|
||||||
private final PlayerChunkMap manager;
|
private final PlayerChunkMap manager;
|
||||||
// private final Set<NextTickListEntry> L = Sets.newHashSet(); // PAIL: Rename nextTickListHash
|
private final HashTreeSet<NextTickListEntry> M = new HashTreeSet<>(); // CraftBukkit - HashTreeSet // PAIL: Rename nextTickList
|
||||||
private final HashTreeSet<NextTickListEntry> M = new HashTreeSet<NextTickListEntry>(); // CraftBukkit - HashTreeSet // PAIL: Rename nextTickList
|
|
||||||
private final Map<UUID, Entity> entitiesByUUID = Maps.newHashMap();
|
private final Map<UUID, Entity> entitiesByUUID = Maps.newHashMap();
|
||||||
public ChunkProviderServer chunkProviderServer;
|
public ChunkProviderServer chunkProviderServer;
|
||||||
public boolean savingDisabled;
|
public boolean savingDisabled;
|
||||||
|
@ -876,9 +876,11 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||||
|
|
||||||
private void b(WorldSettings worldsettings) {
|
private void b(WorldSettings worldsettings) {
|
||||||
if (!this.worldProvider.e()) {
|
if (!this.worldProvider.e()) {
|
||||||
this.worldData.setSpawn(BlockPosition.ZERO.up(this.worldProvider.getSeaLevel()));
|
BlockPosition position = BlockPosition.ZERO.up(this.worldProvider.getSeaLevel());
|
||||||
|
this.worldData.setSpawn(new Location(getWorld(), position.getX(), position.getY(), position.getZ()));
|
||||||
} else if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
|
} else if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
|
||||||
this.worldData.setSpawn(BlockPosition.ZERO.up());
|
BlockPosition position = BlockPosition.ZERO.up();
|
||||||
|
this.worldData.setSpawn(new Location(getWorld(), position.getX(), position.getY(), position.getZ()));
|
||||||
} else {
|
} else {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
WorldChunkManager worldchunkmanager = this.worldProvider.m();
|
WorldChunkManager worldchunkmanager = this.worldProvider.m();
|
||||||
|
@ -898,7 +900,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||||
if (spawn.getWorld() != ((WorldServer) this).getWorld()) {
|
if (spawn.getWorld() != ((WorldServer) this).getWorld()) {
|
||||||
throw new IllegalStateException("Cannot set spawn point for " + this.worldData.getName() + " to be in another world (" + spawn.getWorld().getName() + ")");
|
throw new IllegalStateException("Cannot set spawn point for " + this.worldData.getName() + " to be in another world (" + spawn.getWorld().getName() + ")");
|
||||||
} else {
|
} else {
|
||||||
this.worldData.setSpawn(new BlockPosition(spawn.getBlockX(), spawn.getBlockY(), spawn.getBlockZ()));
|
this.worldData.setSpawn(spawn);
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -924,7 +926,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.worldData.setSpawn(new BlockPosition(i, j, k));
|
this.worldData.setSpawn(new Location(getWorld(), i, j, k));
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
if (worldsettings.c()) {
|
if (worldsettings.c()) {
|
||||||
this.l();
|
this.l();
|
||||||
|
@ -937,8 +939,8 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||||
WorldGenBonusChest worldgenbonuschest = new WorldGenBonusChest(WorldServer.U, 10);
|
WorldGenBonusChest worldgenbonuschest = new WorldGenBonusChest(WorldServer.U, 10);
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
int j = this.worldData.c() + this.random.nextInt(6) - this.random.nextInt(6);
|
int j = (int) this.worldData.c() + this.random.nextInt(6) - this.random.nextInt(6);
|
||||||
int k = this.worldData.e() + this.random.nextInt(6) - this.random.nextInt(6);
|
int k = (int) this.worldData.e() + this.random.nextInt(6) - this.random.nextInt(6);
|
||||||
BlockPosition blockposition = this.r(new BlockPosition(j, 0, k)).up();
|
BlockPosition blockposition = this.r(new BlockPosition(j, 0, k)).up();
|
||||||
|
|
||||||
if (worldgenbonuschest.generate(this, this.random, blockposition)) {
|
if (worldgenbonuschest.generate(this, this.random, blockposition)) {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package org.bukkit.craftbukkit;
|
package org.bukkit.craftbukkit;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import net.minecraft.server.*;
|
import net.minecraft.server.*;
|
||||||
|
|
||||||
|
@ -10,8 +12,10 @@ import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.ChunkSnapshot;
|
import org.bukkit.ChunkSnapshot;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
|
||||||
public class CraftChunk implements Chunk {
|
public class CraftChunk implements Chunk {
|
||||||
private WeakReference<net.minecraft.server.Chunk> weakChunk;
|
private WeakReference<net.minecraft.server.Chunk> weakChunk;
|
||||||
|
@ -24,7 +28,7 @@ public class CraftChunk implements Chunk {
|
||||||
|
|
||||||
public CraftChunk(net.minecraft.server.Chunk chunk) {
|
public CraftChunk(net.minecraft.server.Chunk chunk) {
|
||||||
if (!(chunk instanceof EmptyChunk)) {
|
if (!(chunk instanceof EmptyChunk)) {
|
||||||
this.weakChunk = new WeakReference<net.minecraft.server.Chunk>(chunk);
|
this.weakChunk = new WeakReference<>(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
worldServer = (WorldServer) getHandle().world;
|
worldServer = (WorldServer) getHandle().world;
|
||||||
|
@ -310,4 +314,78 @@ public class CraftChunk implements Chunk {
|
||||||
static {
|
static {
|
||||||
Arrays.fill(emptySkyLight, (byte) 0xFF);
|
Arrays.fill(emptySkyLight, (byte) 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.techcable.tacospigot.event.entity.ChunkSnapshot takeSnapshot() {
|
||||||
|
net.minecraft.server.Chunk handle = getHandle();
|
||||||
|
com.elevatemc.spigot.chunk.CraftChunkSnapshot snap = new com.elevatemc.spigot.chunk.CraftChunkSnapshot();
|
||||||
|
|
||||||
|
// save chunk sections to snapshot
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
if (handle.getSections()[i] != null) {
|
||||||
|
snap.getSections()[i] = handle.getSections()[i].createSnapshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// save tile entities to snapshot
|
||||||
|
for (Map.Entry<BlockPosition, TileEntity> entry : handle.tileEntities.entrySet()) {
|
||||||
|
NBTTagCompound nbt = new NBTTagCompound();
|
||||||
|
entry.getValue().b(nbt); // writeToNBT
|
||||||
|
snap.getTileEntities().add(nbt);
|
||||||
|
}
|
||||||
|
return snap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreSnapshot(net.techcable.tacospigot.event.entity.ChunkSnapshot snapshot) {
|
||||||
|
com.elevatemc.spigot.chunk.CraftChunkSnapshot snap = (com.elevatemc.spigot.chunk.CraftChunkSnapshot) snapshot;
|
||||||
|
net.minecraft.server.Chunk handle = getHandle();
|
||||||
|
|
||||||
|
// add chunk sections from snapshot
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
if (snap.getSections()[i] == null) {
|
||||||
|
handle.getSections()[i] = null;
|
||||||
|
} else {
|
||||||
|
handle.getSections()[i] = new ChunkSection(i << 4, !worldServer.worldProvider.e);
|
||||||
|
handle.getSections()[i].restoreSnapshot(snap.getSections()[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear tile entities currently in the chunk
|
||||||
|
for (TileEntity tileEntity : handle.tileEntities.values()) {
|
||||||
|
if (tileEntity instanceof IInventory) {
|
||||||
|
for (HumanEntity h : new ArrayList<> (((IInventory) tileEntity).getViewers())) {
|
||||||
|
if (h instanceof CraftHumanEntity) {
|
||||||
|
((CraftHumanEntity) h).getHandle().closeInventory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
worldServer.a(tileEntity);
|
||||||
|
}
|
||||||
|
handle.tileEntities.clear();
|
||||||
|
|
||||||
|
// add tile entities from snapshot
|
||||||
|
for (NBTTagCompound nbt : snap.getTileEntities()) {
|
||||||
|
// deserialize nbt to new tile entity instance
|
||||||
|
TileEntity tileEntity = TileEntity.c(nbt);
|
||||||
|
// TODO: might have to fix this
|
||||||
|
// move the tile entity into this chunk's space
|
||||||
|
tileEntity.position = new BlockPosition(
|
||||||
|
(tileEntity.position.getX() & 15) | handle.locX << 4,
|
||||||
|
tileEntity.position.getY(),
|
||||||
|
(tileEntity.position.getZ() & 15) | handle.locX << 4
|
||||||
|
);
|
||||||
|
|
||||||
|
// add it
|
||||||
|
handle.a(tileEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle.q = true; // needs saving flag
|
||||||
|
worldServer.getPlayerChunkMap().resend(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
Arrays.fill(emptySkyLight, (byte) 0xFF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,11 +106,35 @@ public class CraftWorld implements World {
|
||||||
BlockPosition spawn = world.getSpawn();
|
BlockPosition spawn = world.getSpawn();
|
||||||
return new Location(this, spawn.getX(), spawn.getY(), spawn.getZ());
|
return new Location(this, spawn.getX(), spawn.getY(), spawn.getZ());
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public boolean setSpawnLocation(Location location) {
|
||||||
|
Location previousLocation = getSpawnLocation();
|
||||||
|
world.worldData.setSpawn(location);
|
||||||
|
|
||||||
|
// Notify anyone who's listening.
|
||||||
|
SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation);
|
||||||
|
server.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
public boolean setSpawnLocation(int x, int y, int z) {
|
public boolean setSpawnLocation(int x, int y, int z) {
|
||||||
try {
|
try {
|
||||||
Location previousLocation = getSpawnLocation();
|
Location previousLocation = getSpawnLocation();
|
||||||
world.worldData.setSpawn(new BlockPosition(x, y, z));
|
world.worldData.setSpawn(new Location(this, x, y, z));
|
||||||
|
|
||||||
|
// Notify anyone who's listening.
|
||||||
|
SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation);
|
||||||
|
server.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public boolean setSpawnLocation(double x, double y, double z, float yaw, float pitch) {
|
||||||
|
try {
|
||||||
|
Location previousLocation = getSpawnLocation();
|
||||||
|
world.worldData.setSpawn(new Location(this, x, y, z, yaw, pitch));
|
||||||
|
|
||||||
// Notify anyone who's listening.
|
// Notify anyone who's listening.
|
||||||
SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation);
|
SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.bukkit.craftbukkit.entity;
|
package org.bukkit.craftbukkit.entity;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.event.PlayerHealthChangeEvent;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
|
@ -1382,7 +1383,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealHealth(double health) {
|
public void setRealHealth(double health) {
|
||||||
|
double previous = this.health; // ImHacking;
|
||||||
|
|
||||||
this.health = health;
|
this.health = health;
|
||||||
|
|
||||||
|
// ImHacking Start - Player Health Change Event
|
||||||
|
if (previous != health) {
|
||||||
|
Bukkit.getPluginManager().callEvent(new PlayerHealthChangeEvent(this, previous, getHealth()));
|
||||||
|
}
|
||||||
|
// ImHacking End
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateScaledHealth() {
|
public void updateScaledHealth() {
|
||||||
|
|
Loading…
Reference in New Issue