So MANY PATCHES
This commit is contained in:
parent
c829d884d8
commit
c518d8dd6d
@ -89,7 +89,7 @@
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.15</version>
|
||||
<version>1.30</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -1166,4 +1166,10 @@ public final class Bukkit {
|
||||
{
|
||||
return server.spigot();
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
public static String getPermissionMessage() {
|
||||
return server.getPermissionMessage();
|
||||
}
|
||||
// KigPaper end
|
||||
}
|
||||
|
@ -1007,4 +1007,11 @@ public interface Server extends PluginMessageRecipient {
|
||||
}
|
||||
|
||||
Spigot spigot();
|
||||
|
||||
// KigPaper start
|
||||
/**
|
||||
* @return the server's no permission message
|
||||
*/
|
||||
String getPermissionMessage();
|
||||
// KigPaper end
|
||||
}
|
||||
|
@ -208,4 +208,17 @@ public enum Sound {
|
||||
VILLAGER_IDLE,
|
||||
VILLAGER_NO,
|
||||
VILLAGER_YES,
|
||||
// KigPaper start - Guardian sounds
|
||||
GUARDIAN_IDLE,
|
||||
GUARDIAN_IDLE_LAND,
|
||||
GUARDIAN_IDLE_ELDER,
|
||||
GUARDIAN_HIT,
|
||||
GUARDIAN_HIT_LAND,
|
||||
GUARDIAN_HIT_ELDER,
|
||||
GUARDIAN_DEATH,
|
||||
GUARDIAN_DEATH_LAND,
|
||||
GUARDIAN_DEATH_ELDER,
|
||||
GUARDIAN_FLOP,
|
||||
GUARDIAN_CURSE
|
||||
// KigPaper end
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ public abstract class Command {
|
||||
}
|
||||
|
||||
if (permissionMessage == null) {
|
||||
target.sendMessage(ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error.");
|
||||
target.sendMessage(Bukkit.getServer().getPermissionMessage());
|
||||
} else if (permissionMessage.length() != 0) {
|
||||
for (String line : permissionMessage.replace("<permission>", permission).split("\n")) {
|
||||
target.sendMessage(line);
|
||||
|
@ -2,6 +2,7 @@ package org.bukkit.entity;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import org.bukkit.Achievement;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Effect;
|
||||
@ -1203,6 +1204,14 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
|
||||
// Paper - Undeprecate
|
||||
public void resetTitle();
|
||||
|
||||
// KigPaper start
|
||||
/**
|
||||
+ * Sends a message to the player's actionbar.
|
||||
+ * @param message the message to send
|
||||
+ */
|
||||
void sendActionbarMessage(BaseComponent... message);
|
||||
// KigPaper end
|
||||
|
||||
// TacoSpigot start
|
||||
/**
|
||||
* Request that the player's client download and switch resource packs.
|
||||
|
@ -7,6 +7,7 @@ import org.bukkit.entity.Player;
|
||||
*/
|
||||
public abstract class MapRenderer {
|
||||
|
||||
private boolean drawCursors = true; // KigPaper
|
||||
private boolean contextual;
|
||||
|
||||
/**
|
||||
@ -53,4 +54,20 @@ public abstract class MapRenderer {
|
||||
*/
|
||||
abstract public void render(MapView map, MapCanvas canvas, Player player);
|
||||
|
||||
// KigPaper start
|
||||
/**
|
||||
* Returns whether this renderer should draw cursors. Implementors should respect this choice.
|
||||
*/
|
||||
public boolean getDrawCursors() {
|
||||
return drawCursors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to draw cursors
|
||||
* @param drawCursors whether this renderer should draw cursors
|
||||
*/
|
||||
public void setDrawCursors(boolean drawCursors) {
|
||||
this.drawCursors = drawCursors;
|
||||
}
|
||||
// KigPaper end
|
||||
}
|
||||
|
@ -133,6 +133,16 @@
|
||||
<artifactId>velocity-native</artifactId>
|
||||
<version>1.1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lz4</groupId>
|
||||
<artifactId>lz4-java</artifactId>
|
||||
<version>1.8.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.luben</groupId>
|
||||
<artifactId>zstd-jni</artifactId>
|
||||
<version>1.5.2-3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- required until fixed plexus-compiler-eclipse is deployed -->
|
||||
@ -144,7 +154,7 @@
|
||||
<!-- PaperSpigot - Repo for gitdescribe -->
|
||||
<pluginRepository>
|
||||
<id>destroystokyo</id>
|
||||
<url>https://ci.destroystokyo.com/plugin/repository/everything/</url>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
|
@ -6,6 +6,8 @@ import com.elevatemc.spigot.handler.MovementHandler;
|
||||
import com.elevatemc.spigot.handler.PacketHandler;
|
||||
import com.elevatemc.spigot.util.YamlConfig;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import com.elevatemc.spigot.knockback.KnockbackHandler;
|
||||
@ -13,14 +15,11 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class eSpigot {
|
||||
|
||||
|
||||
private final Set<PacketHandler> packetHandlers = new HashSet<>();
|
||||
private final Set<MovementHandler> movementHandlers = new HashSet<>();
|
||||
public static final ScheduledExecutorService EXECUTOR_SERVICE =
|
||||
|
@ -11,7 +11,8 @@ public enum eSpigotFeature {
|
||||
NATURAL_MOB_SPAWNING(false),
|
||||
SHOW_HIDDEN_PLAYERS_IN_TAB(true),
|
||||
MOB_AI(false),
|
||||
FIX_SPRINT_EAT_EXPLOIT(true);
|
||||
FIX_SPRINT_EAT_EXPLOIT(true),
|
||||
OBFUSCATE_HEALTH(true);
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
|
@ -13,7 +13,7 @@ public class NamePriorityThreadFactory implements ThreadFactory {
|
||||
|
||||
private final int priority;
|
||||
private int idCounter = 0;
|
||||
private String name = "gSpigotThread";
|
||||
private String name = "eSpigotThread";
|
||||
private boolean isDaemon = false;
|
||||
private Queue<WeakReference<Thread>> createdThreadList;
|
||||
|
||||
|
@ -10,7 +10,6 @@ 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;
|
||||
@ -54,7 +53,7 @@ public class ThreadingManager {
|
||||
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...");
|
||||
log.warn("eSpigot is still waiting for NBT files to be written to disk. " + this.nbtFiles.getTaskCount() + " to go...");
|
||||
} catch(InterruptedException e) {}
|
||||
}
|
||||
if(!this.cachedThreadPool.isTerminated()) {
|
||||
@ -65,7 +64,7 @@ public class ThreadingManager {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(this.cachedThreadPoolFactory.getActiveCount() > 0) {
|
||||
log.warn("gSpigot is still waiting for " + this.cachedThreadPoolFactory.getActiveCount() + " async threads to finish.");
|
||||
log.warn("eSpigot 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) {
|
||||
@ -177,7 +176,7 @@ public class ThreadingManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkTickTime(float tickTime) {
|
||||
public static boolean checkTickTime(float tickTime) {
|
||||
if(tickTime > 45.0F) {
|
||||
if(timerDelay > 40) {
|
||||
timerDelay--;
|
||||
|
@ -0,0 +1,25 @@
|
||||
// KigPaper
|
||||
package com.elevatemc.spigot.util;
|
||||
|
||||
import net.minecraft.server.EnumParticle;
|
||||
import org.bukkit.Effect;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
public class Dictionary {
|
||||
public static final EnumMap<Effect, EnumParticle> EFFECT_TO_PARTICLE = new EnumMap<>(Effect.class);
|
||||
|
||||
static {
|
||||
String tmp;
|
||||
for (EnumParticle p : EnumParticle.values()) {
|
||||
tmp = p.b().replace("_", "");
|
||||
for (Effect e : Effect.values()) {
|
||||
// This is pretty much the original code, but we only call it once / effect & matching particle
|
||||
if (e.getName() != null && e.getName().startsWith(tmp)) {
|
||||
EFFECT_TO_PARTICLE.put(e, p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.elevatemc.spigot.world;
|
||||
|
||||
import co.aikar.timings.SpigotTimings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.world.WorldSaveEvent;
|
||||
|
||||
import net.minecraft.server.ExceptionWorldConflict;
|
||||
import net.minecraft.server.FileIOThread;
|
||||
import net.minecraft.server.IProgressUpdate;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.RegionFileCache;
|
||||
import net.minecraft.server.WorldServer;
|
||||
|
||||
public class AutoSaveJob {
|
||||
|
||||
public enum JobDetail {
|
||||
WORLD_SAVE,
|
||||
WORLD_SAVEEVENT,
|
||||
}
|
||||
|
||||
private WorldServer worldserver;
|
||||
private JobDetail jobDetail;
|
||||
|
||||
public AutoSaveJob(JobDetail detail, WorldServer worldserver) {
|
||||
this.jobDetail = detail;
|
||||
this.worldserver = worldserver;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if the job shall be removed from the autosave queue
|
||||
* @throws ExceptionWorldConflict
|
||||
*/
|
||||
|
||||
public boolean process() throws ExceptionWorldConflict {
|
||||
if(this.isJob(JobDetail.WORLD_SAVE) && this.worldserver != null) {
|
||||
SpigotTimings.worldSaveTimer.startTiming();
|
||||
MinecraftServer.getServer().info("[AutoSave] Saving world " + this.worldserver.getWorld().getName());
|
||||
this.worldserver.save(true, (IProgressUpdate) null);
|
||||
FileIOThread.a().setNoDelay(true);
|
||||
SpigotTimings.worldSaveTimer.stopTiming();
|
||||
} else if(this.isJob(JobDetail.WORLD_SAVEEVENT) && this.worldserver != null) {
|
||||
if(FileIOThread.a().isDone()) {
|
||||
SpigotTimings.worldSaveTimer.startTiming();
|
||||
FileIOThread.a().setNoDelay(false);
|
||||
RegionFileCache.a();
|
||||
Bukkit.getPluginManager().callEvent(new WorldSaveEvent(this.worldserver.getWorld()));
|
||||
SpigotTimings.worldSaveTimer.stopTiming();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.worldserver = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isJob(JobDetail detail) {
|
||||
if(this.jobDetail != null) {
|
||||
return this.jobDetail.equals(detail);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,413 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BiomeDecorator {
|
||||
|
||||
protected World a;
|
||||
protected Random b;
|
||||
protected BlockPosition c;
|
||||
protected CustomWorldSettingsFinal d;
|
||||
protected WorldGenerator e = new WorldGenClay(4);
|
||||
protected WorldGenerator f;
|
||||
protected WorldGenerator g;
|
||||
protected WorldGenerator h;
|
||||
protected WorldGenerator i;
|
||||
protected WorldGenerator j;
|
||||
protected WorldGenerator k;
|
||||
protected WorldGenerator l;
|
||||
protected WorldGenerator m;
|
||||
protected WorldGenerator n;
|
||||
protected WorldGenerator o;
|
||||
protected WorldGenerator p;
|
||||
protected WorldGenerator q;
|
||||
protected WorldGenerator r;
|
||||
protected WorldGenFlowers s;
|
||||
protected WorldGenerator t;
|
||||
protected WorldGenerator u;
|
||||
protected WorldGenerator v;
|
||||
protected WorldGenerator w;
|
||||
protected WorldGenerator x;
|
||||
protected WorldGenerator y;
|
||||
protected int z;
|
||||
protected int A;
|
||||
protected int B;
|
||||
protected int C;
|
||||
protected int D;
|
||||
protected int E;
|
||||
protected int F;
|
||||
protected int G;
|
||||
protected int H;
|
||||
protected int I;
|
||||
protected int J;
|
||||
protected int K;
|
||||
public boolean L;
|
||||
|
||||
public BiomeDecorator() {
|
||||
this.f = new WorldGenSand(Blocks.SAND, 7);
|
||||
this.g = new WorldGenSand(Blocks.GRAVEL, 6);
|
||||
this.s = new WorldGenFlowers(Blocks.YELLOW_FLOWER, BlockFlowers.EnumFlowerVarient.DANDELION);
|
||||
this.t = new WorldGenMushrooms(Blocks.BROWN_MUSHROOM);
|
||||
this.u = new WorldGenMushrooms(Blocks.RED_MUSHROOM);
|
||||
this.v = new WorldGenHugeMushroom();
|
||||
this.w = new WorldGenReed();
|
||||
this.x = new WorldGenCactus();
|
||||
this.y = new WorldGenWaterLily();
|
||||
this.B = 2;
|
||||
this.C = 1;
|
||||
this.H = 1;
|
||||
this.I = 3;
|
||||
this.J = 1;
|
||||
this.L = true;
|
||||
}
|
||||
|
||||
// Migot start
|
||||
protected BiomeDecorator createShallowCopy() {
|
||||
return new BiomeDecorator(this);
|
||||
}
|
||||
|
||||
protected BiomeDecorator(BiomeDecorator decorator) {
|
||||
this.f = decorator.f;
|
||||
this.g = decorator.g;
|
||||
this.s = decorator.s;
|
||||
this.t = decorator.t;
|
||||
this.u = decorator.u;
|
||||
this.v = decorator.v;
|
||||
this.w = decorator.w;
|
||||
this.x = decorator.x;
|
||||
this.y = decorator.y;
|
||||
this.z = decorator.z;
|
||||
this.A = decorator.A;
|
||||
this.B = decorator.B;
|
||||
this.C = decorator.C;
|
||||
this.D = decorator.D;
|
||||
this.E = decorator.E;
|
||||
this.F = decorator.F;
|
||||
this.G = decorator.G;
|
||||
this.H = decorator.H;
|
||||
this.I = decorator.I;
|
||||
this.J = decorator.J;
|
||||
this.K = decorator.K;
|
||||
this.L = decorator.L;
|
||||
}
|
||||
// Migot end
|
||||
|
||||
public void a(World world, Random random, BiomeBase biomebase, BlockPosition blockposition) {
|
||||
if (this.a != null) {
|
||||
// Migot start
|
||||
BiomeDecorator decorator = this.createShallowCopy();
|
||||
decorator.a = world;
|
||||
String s = world.getWorldData().getGeneratorOptions();
|
||||
if (s != null) {
|
||||
decorator.d = CustomWorldSettingsFinal.CustomWorldSettings.a(s).b();
|
||||
} else {
|
||||
decorator.d = CustomWorldSettingsFinal.CustomWorldSettings.a("").b();
|
||||
}
|
||||
decorator.b = random;
|
||||
decorator.c = blockposition;
|
||||
decorator.h = new WorldGenMinable(Blocks.DIRT.getBlockData(), decorator.d.I);
|
||||
decorator.i = new WorldGenMinable(Blocks.GRAVEL.getBlockData(), decorator.d.M);
|
||||
decorator.j = new WorldGenMinable(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, BlockStone.EnumStoneVariant.GRANITE), decorator.d.Q);
|
||||
decorator.k = new WorldGenMinable(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, BlockStone.EnumStoneVariant.DIORITE), decorator.d.U);
|
||||
decorator.l = new WorldGenMinable(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, BlockStone.EnumStoneVariant.ANDESITE), decorator.d.Y);
|
||||
decorator.m = new WorldGenMinable(Blocks.COAL_ORE.getBlockData(), decorator.d.ac);
|
||||
decorator.n = new WorldGenMinable(Blocks.IRON_ORE.getBlockData(), decorator.d.ag);
|
||||
decorator.o = new WorldGenMinable(Blocks.GOLD_ORE.getBlockData(), decorator.d.ak);
|
||||
decorator.p = new WorldGenMinable(Blocks.REDSTONE_ORE.getBlockData(), decorator.d.ao);
|
||||
decorator.q = new WorldGenMinable(Blocks.DIAMOND_ORE.getBlockData(), decorator.d.as);
|
||||
decorator.r = new WorldGenMinable(Blocks.LAPIS_ORE.getBlockData(), decorator.d.aw);
|
||||
decorator.a(biomebase);
|
||||
decorator.a = null;
|
||||
decorator.b = null;
|
||||
// Migot end
|
||||
} else {
|
||||
this.a = world;
|
||||
String s = world.getWorldData().getGeneratorOptions();
|
||||
|
||||
if (s != null) {
|
||||
this.d = CustomWorldSettingsFinal.CustomWorldSettings.a(s).b();
|
||||
} else {
|
||||
this.d = CustomWorldSettingsFinal.CustomWorldSettings.a("").b();
|
||||
}
|
||||
|
||||
this.b = random;
|
||||
this.c = blockposition;
|
||||
this.h = new WorldGenMinable(Blocks.DIRT.getBlockData(), this.d.I);
|
||||
this.i = new WorldGenMinable(Blocks.GRAVEL.getBlockData(), this.d.M);
|
||||
this.j = new WorldGenMinable(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, BlockStone.EnumStoneVariant.GRANITE), this.d.Q);
|
||||
this.k = new WorldGenMinable(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, BlockStone.EnumStoneVariant.DIORITE), this.d.U);
|
||||
this.l = new WorldGenMinable(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, BlockStone.EnumStoneVariant.ANDESITE), this.d.Y);
|
||||
this.m = new WorldGenMinable(Blocks.COAL_ORE.getBlockData(), this.d.ac);
|
||||
this.n = new WorldGenMinable(Blocks.IRON_ORE.getBlockData(), this.d.ag);
|
||||
this.o = new WorldGenMinable(Blocks.GOLD_ORE.getBlockData(), this.d.ak);
|
||||
this.p = new WorldGenMinable(Blocks.REDSTONE_ORE.getBlockData(), this.d.ao);
|
||||
this.q = new WorldGenMinable(Blocks.DIAMOND_ORE.getBlockData(), this.d.as);
|
||||
this.r = new WorldGenMinable(Blocks.LAPIS_ORE.getBlockData(), this.d.aw);
|
||||
this.a(biomebase);
|
||||
this.a = null;
|
||||
this.b = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void a(BiomeBase biomebase) {
|
||||
this.a();
|
||||
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
|
||||
for (i = 0; i < this.I; ++i) {
|
||||
j = this.b.nextInt(16) + 8;
|
||||
k = this.b.nextInt(16) + 8;
|
||||
this.f.generate(this.a, this.b, this.a.r(this.c.a(j, 0, k)));
|
||||
}
|
||||
|
||||
for (i = 0; i < this.J; ++i) {
|
||||
j = this.b.nextInt(16) + 8;
|
||||
k = this.b.nextInt(16) + 8;
|
||||
this.e.generate(this.a, this.b, this.a.r(this.c.a(j, 0, k)));
|
||||
}
|
||||
|
||||
for (i = 0; i < this.H; ++i) {
|
||||
j = this.b.nextInt(16) + 8;
|
||||
k = this.b.nextInt(16) + 8;
|
||||
this.g.generate(this.a, this.b, this.a.r(this.c.a(j, 0, k)));
|
||||
}
|
||||
|
||||
i = this.A;
|
||||
if (this.b.nextInt(10) == 0) {
|
||||
++i;
|
||||
}
|
||||
|
||||
int l;
|
||||
BlockPosition blockposition;
|
||||
|
||||
for (j = 0; j < i; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
WorldGenTreeAbstract worldgentreeabstract = biomebase.a(this.b);
|
||||
|
||||
worldgentreeabstract.e();
|
||||
blockposition = this.a.getHighestBlockYAt(this.c.a(k, 0, l));
|
||||
if (worldgentreeabstract.generate(this.a, this.b, blockposition)) {
|
||||
worldgentreeabstract.a(this.a, this.b, blockposition);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < this.K; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
this.v.generate(this.a, this.b, this.a.getHighestBlockYAt(this.c.a(k, 0, l)));
|
||||
}
|
||||
|
||||
BlockPosition blockposition1;
|
||||
int i1;
|
||||
int j1;
|
||||
|
||||
for (j = 0; j < this.B; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() + 32;
|
||||
if (i1 > 0) {
|
||||
j1 = this.b.nextInt(i1);
|
||||
blockposition1 = this.c.a(k, j1, l);
|
||||
BlockFlowers.EnumFlowerVarient blockflowers_enumflowervarient = biomebase.a(this.b, blockposition1);
|
||||
BlockFlowers blockflowers = blockflowers_enumflowervarient.a().a();
|
||||
|
||||
if (blockflowers.getMaterial() != Material.AIR) {
|
||||
this.s.a(blockflowers, blockflowers_enumflowervarient);
|
||||
this.s.generate(this.a, this.b, blockposition1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < this.C; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2;
|
||||
if (i1 > 0) {
|
||||
j1 = this.b.nextInt(i1);
|
||||
biomebase.b(this.b).generate(this.a, this.b, this.c.a(k, j1, l));
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < this.D; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2;
|
||||
if (i1 > 0) {
|
||||
j1 = this.b.nextInt(i1);
|
||||
(new WorldGenDeadBush()).generate(this.a, this.b, this.c.a(k, j1, l));
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < this.z; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2;
|
||||
if (i1 > 0) {
|
||||
j1 = this.b.nextInt(i1);
|
||||
|
||||
BlockPosition blockposition2;
|
||||
|
||||
for (blockposition1 = this.c.a(k, j1, l); blockposition1.getY() > 0; blockposition1 = blockposition2) {
|
||||
blockposition2 = blockposition1.down();
|
||||
if (!this.a.isEmpty(blockposition2)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.y.generate(this.a, this.b, blockposition1);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < this.E; ++j) {
|
||||
if (this.b.nextInt(4) == 0) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
BlockPosition blockposition3 = this.a.getHighestBlockYAt(this.c.a(k, 0, l));
|
||||
|
||||
this.t.generate(this.a, this.b, blockposition3);
|
||||
}
|
||||
|
||||
if (this.b.nextInt(8) == 0) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2;
|
||||
if (i1 > 0) {
|
||||
j1 = this.b.nextInt(i1);
|
||||
blockposition1 = this.c.a(k, j1, l);
|
||||
this.u.generate(this.a, this.b, blockposition1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.b.nextInt(4) == 0) {
|
||||
j = this.b.nextInt(16) + 8;
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.a.getHighestBlockYAt(this.c.a(j, 0, k)).getY() * 2;
|
||||
if (l > 0) {
|
||||
i1 = this.b.nextInt(l);
|
||||
this.t.generate(this.a, this.b, this.c.a(j, i1, k));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.b.nextInt(8) == 0) {
|
||||
j = this.b.nextInt(16) + 8;
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.a.getHighestBlockYAt(this.c.a(j, 0, k)).getY() * 2;
|
||||
if (l > 0) {
|
||||
i1 = this.b.nextInt(l);
|
||||
this.u.generate(this.a, this.b, this.c.a(j, i1, k));
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < this.F; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2;
|
||||
if (i1 > 0) {
|
||||
j1 = this.b.nextInt(i1);
|
||||
this.w.generate(this.a, this.b, this.c.a(k, j1, l));
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 10; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2;
|
||||
if (i1 > 0) {
|
||||
j1 = this.b.nextInt(i1);
|
||||
this.w.generate(this.a, this.b, this.c.a(k, j1, l));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.b.nextInt(32) == 0) {
|
||||
j = this.b.nextInt(16) + 8;
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.a.getHighestBlockYAt(this.c.a(j, 0, k)).getY() * 2;
|
||||
if (l > 0) {
|
||||
i1 = this.b.nextInt(l);
|
||||
(new WorldGenPumpkin()).generate(this.a, this.b, this.c.a(j, i1, k));
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < this.G; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2;
|
||||
if (i1 > 0) {
|
||||
j1 = this.b.nextInt(i1);
|
||||
this.x.generate(this.a, this.b, this.c.a(k, j1, l));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.L) {
|
||||
for (j = 0; j < 50; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.b.nextInt(248) + 8;
|
||||
if (i1 > 0) {
|
||||
j1 = this.b.nextInt(i1);
|
||||
blockposition1 = this.c.a(k, j1, l);
|
||||
(new WorldGenLiquids(Blocks.FLOWING_WATER)).generate(this.a, this.b, blockposition1);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 20; ++j) {
|
||||
k = this.b.nextInt(16) + 8;
|
||||
l = this.b.nextInt(16) + 8;
|
||||
i1 = this.b.nextInt(this.b.nextInt(this.b.nextInt(240) + 8) + 8);
|
||||
blockposition = this.c.a(k, i1, l);
|
||||
(new WorldGenLiquids(Blocks.FLOWING_LAVA)).generate(this.a, this.b, blockposition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void a(int i, WorldGenerator worldgenerator, int j, int k) {
|
||||
int l;
|
||||
|
||||
if (k < j) {
|
||||
l = j;
|
||||
j = k;
|
||||
k = l;
|
||||
} else if (k == j) {
|
||||
if (j < 255) {
|
||||
++k;
|
||||
} else {
|
||||
--j;
|
||||
}
|
||||
}
|
||||
|
||||
for (l = 0; l < i; ++l) {
|
||||
BlockPosition blockposition = this.c.a(this.b.nextInt(16), this.b.nextInt(k - j) + j, this.b.nextInt(16));
|
||||
|
||||
worldgenerator.generate(this.a, this.b, blockposition);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void b(int i, WorldGenerator worldgenerator, int j, int k) {
|
||||
for (int l = 0; l < i; ++l) {
|
||||
BlockPosition blockposition = this.c.a(this.b.nextInt(16), this.b.nextInt(k) + this.b.nextInt(k) + j - k, this.b.nextInt(16));
|
||||
|
||||
worldgenerator.generate(this.a, this.b, blockposition);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void a() {
|
||||
this.a(this.d.J, this.h, this.d.K, this.d.L);
|
||||
this.a(this.d.N, this.i, this.d.O, this.d.P);
|
||||
this.a(this.d.V, this.k, this.d.W, this.d.X);
|
||||
this.a(this.d.R, this.j, this.d.S, this.d.T);
|
||||
this.a(this.d.Z, this.l, this.d.aa, this.d.ab);
|
||||
this.a(this.d.ad, this.m, this.d.ae, this.d.af);
|
||||
this.a(this.d.ah, this.n, this.d.ai, this.d.aj);
|
||||
this.a(this.d.al, this.o, this.d.am, this.d.an);
|
||||
this.a(this.d.ap, this.p, this.d.aq, this.d.ar);
|
||||
this.a(this.d.at, this.q, this.d.au, this.d.av);
|
||||
this.b(this.d.ax, this.r, this.d.ay, this.d.az);
|
||||
}
|
||||
}
|
@ -8,6 +8,18 @@ public class BiomeTheEndDecorator extends BiomeDecorator {
|
||||
this.M = new WorldGenEnder(Blocks.END_STONE);
|
||||
}
|
||||
|
||||
// Migot start
|
||||
public BiomeTheEndDecorator(BiomeTheEndDecorator decorator) {
|
||||
super(decorator);
|
||||
this.M = decorator.M;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BiomeDecorator createShallowCopy() {
|
||||
return new BiomeTheEndDecorator(this);
|
||||
}
|
||||
// Migot end
|
||||
|
||||
protected void a(BiomeBase biomebase) {
|
||||
this.a();
|
||||
if (this.b.nextInt(5) == 0) {
|
||||
|
@ -4,6 +4,7 @@ import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
|
||||
public class BlockCactus extends Block {
|
||||
|
||||
@ -64,7 +65,10 @@ public class BlockCactus extends Block {
|
||||
|
||||
public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) {
|
||||
if (!this.e(world, blockposition)) {
|
||||
world.setAir(blockposition, true);
|
||||
org.bukkit.block.Block bukkit = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
BlockPhysicsEvent event = new BlockPhysicsEvent(bukkit, bukkit.getTypeId());
|
||||
world.getServer().getPluginManager().callEvent(event);
|
||||
if(!event.isCancelled()) world.setAir(blockposition, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -64,10 +64,16 @@ public class BlockRedstoneWire extends Block {
|
||||
}
|
||||
|
||||
private IBlockData e(World world, BlockPosition blockposition, IBlockData iblockdata) {
|
||||
// Migot start
|
||||
ArrayList arraylist;
|
||||
synchronized(this.R) {
|
||||
iblockdata = this.a(world, blockposition, blockposition, iblockdata);
|
||||
ArrayList arraylist = Lists.newArrayList(this.R);
|
||||
arraylist = Lists.newArrayList(this.R);
|
||||
|
||||
this.R.clear();
|
||||
}
|
||||
// Migot end
|
||||
|
||||
Iterator iterator = arraylist.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
|
@ -50,6 +50,19 @@ public class Chunk {
|
||||
private int v;
|
||||
private ConcurrentLinkedQueue<BlockPosition> w;
|
||||
protected gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot
|
||||
|
||||
// Migot start
|
||||
private boolean unloaded = false;
|
||||
|
||||
public boolean wasUnloaded() {
|
||||
return this.unloaded;
|
||||
}
|
||||
|
||||
public void markAsUnloaded() {
|
||||
this.unloaded = true;
|
||||
}
|
||||
// Migot end
|
||||
|
||||
// PaperSpigot start - Asynchronous light updates
|
||||
public AtomicInteger pendingLightUpdates = new AtomicInteger();
|
||||
public long lightUpdateTime;
|
||||
@ -1061,7 +1074,7 @@ public class Chunk {
|
||||
if (this.r && this.world.getTime() != this.lastSaved || this.q) {
|
||||
return true;
|
||||
}
|
||||
} else if (this.r && this.world.getTime() >= this.lastSaved + MinecraftServer.getServer().autosavePeriod * 4) { // Spigot - Only save if we've passed 2 auto save intervals without modification
|
||||
} else if (this.r && this.world.getTime() >= 600L) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -36,13 +36,27 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
public LongSet unloadQueue = new LongArraySet(); // CraftBukkit - LongHashSet // TacoSpigot - LongHashSet -> HashArraySet
|
||||
public Chunk emptyChunk;
|
||||
public IChunkProvider chunkProvider;
|
||||
private IChunkLoader chunkLoader;
|
||||
public IChunkLoader chunkLoader; // KigPaper - private -> public
|
||||
public boolean forceChunkLoad = false; // CraftBukkit - true -> false
|
||||
public Long2ObjectMap<Chunk> chunks = new Long2ObjectOpenHashMap<Chunk>(4096, 0.5f); // TacoSpigot - use trove Long2ObjectOpenHashMap instead of craftbukkit implementation (using inital capacity and load factor chosen by Amaranth in an old impl)
|
||||
public WorldServer world;
|
||||
|
||||
// Migot start
|
||||
private ChunkRegionLoader checkedRegionLoader = null;
|
||||
|
||||
public boolean doesChunkExist(int x, int z) {
|
||||
if(this.checkedRegionLoader == null && this.chunkLoader instanceof ChunkRegionLoader) {
|
||||
this.checkedRegionLoader = (ChunkRegionLoader) this.chunkLoader;
|
||||
}
|
||||
if(this.checkedRegionLoader != null) {
|
||||
return this.checkedRegionLoader.chunkExists(this.world, x, z);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Migot end
|
||||
|
||||
public ChunkProviderServer(WorldServer worldserver, IChunkLoader ichunkloader, IChunkProvider ichunkprovider) {
|
||||
this.emptyChunk = new EmptyChunk(worldserver, 0, 0);
|
||||
this.emptyChunk = new EmptyChunk(worldserver, Integer.MIN_VALUE, Integer.MIN_VALUE); // Migot
|
||||
this.world = worldserver;
|
||||
this.chunkLoader = ichunkloader;
|
||||
this.chunkProvider = ichunkprovider;
|
||||
@ -347,7 +361,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
this.saveChunk(chunk);
|
||||
chunk.f(false);
|
||||
++i;
|
||||
if (i == 24 && !flag && false) { // Spigot
|
||||
if (i == 24 && !flag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -381,6 +395,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
if (!event.isCancelled()) {
|
||||
|
||||
if (chunk != null) {
|
||||
chunk.markAsUnloaded(); // Migot
|
||||
chunk.removeEntities();
|
||||
this.saveChunk(chunk);
|
||||
this.saveChunkNOP(chunk);
|
||||
|
@ -17,8 +17,10 @@ import org.apache.logging.log4j.Logger;
|
||||
public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
|
||||
|
||||
private static final Logger a = LogManager.getLogger();
|
||||
private Map<ChunkCoordIntPair, NBTTagCompound> b = new ConcurrentHashMap();
|
||||
private Set<ChunkCoordIntPair> c = Collections.newSetFromMap(new ConcurrentHashMap());
|
||||
// KigPaper start - make public
|
||||
public Map<ChunkCoordIntPair, NBTTagCompound> b = new ConcurrentHashMap();
|
||||
public Set<ChunkCoordIntPair> c = Collections.newSetFromMap(new ConcurrentHashMap());
|
||||
// KigPaper end
|
||||
private final File d;
|
||||
private boolean e = false;
|
||||
|
||||
@ -29,6 +31,14 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
|
||||
// CraftBukkit start
|
||||
public boolean chunkExists(World world, int i, int j) {
|
||||
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
|
||||
// Migot start
|
||||
return this.chunkExists(world, chunkcoordintpair);
|
||||
}
|
||||
|
||||
public boolean chunkExists(World world, ChunkCoordIntPair chunkcoordintpair) {
|
||||
int i = chunkcoordintpair.x;
|
||||
int j = chunkcoordintpair.z;
|
||||
// Migot end
|
||||
|
||||
if (this.c.contains(chunkcoordintpair)) {
|
||||
if (this.b.containsKey(chunkcoordintpair)) {
|
||||
@ -62,14 +72,16 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
|
||||
NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.get(chunkcoordintpair);
|
||||
|
||||
if (nbttagcompound == null) {
|
||||
DataInputStream datainputstream = RegionFileCache.c(this.d, i, j);
|
||||
|
||||
// KigPaper - use try-with-resources
|
||||
// While this is always a ByteArrayInputStream (which does nothing on close), this is not something to be relied upon.
|
||||
try (DataInputStream datainputstream = RegionFileCache.c(this.d, i, j)) {
|
||||
if (datainputstream == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
nbttagcompound = NBTCompressedStreamTools.a(datainputstream);
|
||||
}
|
||||
}
|
||||
|
||||
return this.a(world, i, j, nbttagcompound);
|
||||
}
|
||||
@ -175,10 +187,10 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
|
||||
}
|
||||
|
||||
private void b(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException {
|
||||
DataOutputStream dataoutputstream = RegionFileCache.d(this.d, chunkcoordintpair.x, chunkcoordintpair.z);
|
||||
|
||||
// KigPaper - use try-with-resources
|
||||
try (DataOutputStream dataoutputstream = RegionFileCache.d(this.d, chunkcoordintpair.x, chunkcoordintpair.z)) {
|
||||
NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream);
|
||||
dataoutputstream.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void b(World world, Chunk chunk) throws IOException {}
|
||||
|
@ -9,7 +9,7 @@ public class ContainerWorkbench extends Container {
|
||||
|
||||
public InventoryCrafting craftInventory; // CraftBukkit - move initialization into constructor
|
||||
public IInventory resultInventory; // CraftBukkit - move initialization into constructor
|
||||
private World g;
|
||||
public World g; // KigPaper - make public
|
||||
private BlockPosition h;
|
||||
// CraftBukkit start
|
||||
private CraftInventoryView bukkitEntity = null;
|
||||
|
@ -124,7 +124,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
|
||||
this.propertyManager = new PropertyManager(this.options); // CraftBukkit - CLI argument support
|
||||
this.p = new EULA(new File("eula.txt"));
|
||||
// Spigot Start
|
||||
boolean eulaAgreed = Boolean.getBoolean( "com.mojang.eula.agree" );
|
||||
boolean eulaAgreed = true;
|
||||
if ( eulaAgreed )
|
||||
{
|
||||
System.err.println( "You have used the Spigot command line EULA agreement flag." );
|
||||
|
@ -148,6 +148,9 @@ public class EnchantmentManager {
|
||||
EnchantmentManager.b.a = 0;
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
EnchantmentManager.b.b = null;
|
||||
// KigPaper end
|
||||
return (EnchantmentManager.b.a + 1 >> 1) + EnchantmentManager.a.nextInt((EnchantmentManager.b.a >> 1) + 1);
|
||||
}
|
||||
|
||||
@ -169,6 +172,10 @@ public class EnchantmentManager {
|
||||
a((EnchantmentManager.EnchantmentModifier) EnchantmentManager.d, entityliving.bA());
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
EnchantmentManager.d.a = null;
|
||||
EnchantmentManager.d.b = null;
|
||||
// KigPaper end
|
||||
}
|
||||
|
||||
public static void b(EntityLiving entityliving, Entity entity) {
|
||||
@ -182,6 +189,10 @@ public class EnchantmentManager {
|
||||
a((EnchantmentManager.EnchantmentModifier) EnchantmentManager.e, entityliving.bA());
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
EnchantmentManager.e.a = null;
|
||||
EnchantmentManager.e.b = null;
|
||||
// KigPaper end
|
||||
}
|
||||
|
||||
public static int a(EntityLiving entityliving) {
|
||||
|
@ -1,13 +1,11 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
// CraftBukkit start
|
||||
import com.elevatemc.spigot.util.FastRandom;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@ -36,6 +34,7 @@ import org.bukkit.plugin.PluginManager;
|
||||
// CraftBukkit end
|
||||
|
||||
// PaperSpigot start
|
||||
import org.github.paperspigot.PaperSpigotConfig;
|
||||
import org.spigotmc.event.entity.EntityDismountEvent;
|
||||
// PaperSpigot end
|
||||
|
||||
@ -49,7 +48,7 @@ public abstract class Entity implements ICommandListener {
|
||||
// CraftBukikt end
|
||||
|
||||
private static final AxisAlignedBB a = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
|
||||
private static int entityCount;
|
||||
private static int entityCount = 1;
|
||||
private int id;
|
||||
public double j;
|
||||
public boolean k;
|
||||
@ -121,10 +120,6 @@ public abstract class Entity implements ICommandListener {
|
||||
public int portalCooldown;
|
||||
protected boolean ak;
|
||||
|
||||
public final boolean inPortal() {
|
||||
return this.ak;
|
||||
} // Paper - OBFHELPER
|
||||
|
||||
protected int al;
|
||||
public int dimension;
|
||||
protected BlockPosition an;
|
||||
@ -163,6 +158,16 @@ public abstract class Entity implements ICommandListener {
|
||||
public void inactiveTick() { }
|
||||
// Spigot end
|
||||
|
||||
// Migot start
|
||||
private int targetDimension;
|
||||
private boolean isInLava;
|
||||
private int lastLavaCheck = Integer.MIN_VALUE;
|
||||
|
||||
public int getTargetDimension() {
|
||||
return this.targetDimension;
|
||||
}
|
||||
// Migot end
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
@ -191,6 +196,7 @@ public abstract class Entity implements ICommandListener {
|
||||
this.setPosition(0.0D, 0.0D, 0.0D);
|
||||
if (world != null) {
|
||||
this.dimension = world.worldProvider.getDimension();
|
||||
this.targetDimension = this.dimension; // Migot
|
||||
// Spigot start
|
||||
this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, world.spigotConfig);
|
||||
} else {
|
||||
@ -304,7 +310,7 @@ public abstract class Entity implements ICommandListener {
|
||||
this.lastZ = this.locZ;
|
||||
this.lastPitch = this.pitch;
|
||||
this.lastYaw = this.yaw;
|
||||
if (!this.world.isClientSide && this.world instanceof WorldServer) {
|
||||
if (!this.world.isClientSide && this.world instanceof WorldServer && !(this instanceof EntityProjectile) && !(this instanceof EntityArrow) && !(this instanceof EntityFireball)) { // Migot
|
||||
this.world.methodProfiler.a("portal");
|
||||
MinecraftServer minecraftserver = ((WorldServer) this.world).getMinecraftServer();
|
||||
int i = this.L();
|
||||
@ -842,10 +848,12 @@ public abstract class Entity implements ICommandListener {
|
||||
BlockPosition blockposition1 = new BlockPosition(this.getBoundingBox().d - 0.001D, this.getBoundingBox().e - 0.001D, this.getBoundingBox().f - 0.001D);
|
||||
|
||||
if (this.world.areChunksLoadedBetween(blockposition, blockposition1)) {
|
||||
for (int i = blockposition.getX(); i <= blockposition1.getX(); ++i) {
|
||||
for (int j = blockposition.getY(); j <= blockposition1.getY(); ++j) {
|
||||
// KigPaper - Start - invert loop
|
||||
for (int i = blockposition1.getY(); i >= blockposition.getY(); --i) {
|
||||
// KigPaper - End
|
||||
for (int j = blockposition.getX(); j <= blockposition1.getX(); ++j) {
|
||||
for (int k = blockposition.getZ(); k <= blockposition1.getZ(); ++k) {
|
||||
BlockPosition blockposition2 = new BlockPosition(i, j, k);
|
||||
BlockPosition blockposition2 = new BlockPosition(j, i, k);
|
||||
IBlockData iblockdata = this.world.getType(blockposition2);
|
||||
|
||||
try {
|
||||
@ -898,6 +906,19 @@ public abstract class Entity implements ICommandListener {
|
||||
protected void a(double d0, boolean flag, Block block, BlockPosition blockposition) {
|
||||
if (flag) {
|
||||
if (this.fallDistance > 0.0F) {
|
||||
// KigPaper start - run again if we need accurate detection at high falling speeds
|
||||
if (PaperSpigotConfig.accurateBlockCollisions) {
|
||||
try {
|
||||
this.checkBlockCollisions();
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.a(throwable, "Checking entity block collision");
|
||||
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being checked for collision");
|
||||
|
||||
this.appendEntityCrashDetails(crashreportsystemdetails);
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
}
|
||||
// KigPaper end
|
||||
if (block != null) {
|
||||
block.fallOn(this.world, blockposition, this, this.fallDistance);
|
||||
} else {
|
||||
@ -943,7 +964,36 @@ public abstract class Entity implements ICommandListener {
|
||||
}
|
||||
|
||||
public boolean W() {
|
||||
if (this.world.a(this.getBoundingBox().grow(0.0D, -0.4000000059604645D, 0.0D).shrink(0.001D, 0.001D, 0.001D), Material.WATER, this)) {
|
||||
AxisAlignedBB boundingBox = this.getBoundingBox();
|
||||
// KigPaper start
|
||||
if (PaperSpigotConfig.accurateBlockCollisions && this instanceof EntityPlayer) {
|
||||
// Account for vertical speed in minY
|
||||
AxisAlignedBB tmp = new AxisAlignedBB(boundingBox.a, boundingBox.b + this.motY / 2, boundingBox.c, boundingBox.d, boundingBox.e, boundingBox.f);
|
||||
|
||||
boolean useTmp = true;
|
||||
int tmpX = MathHelper.floor(tmp.a);
|
||||
int tmpMaxX = MathHelper.floor(tmp.d);
|
||||
int tmpY = MathHelper.floor(tmp.b);
|
||||
int tmpMaxY = MathHelper.floor(tmp.e);
|
||||
int tmpZ = MathHelper.floor(tmp.c);
|
||||
int tmpMaxZ = MathHelper.floor(tmp.f);
|
||||
BlockPosition.MutableBlockPosition blockPosition = new BlockPosition.MutableBlockPosition();
|
||||
Block block;
|
||||
for (int x = tmpX; x <= tmpMaxX; ++x) {
|
||||
for (int y = tmpY; y <= tmpMaxY; ++y) {
|
||||
for (int z = tmpZ; z <= tmpMaxZ; ++z) {
|
||||
block = world.getType(blockPosition.c(x, y, z)).getBlock();
|
||||
|
||||
if (block.getMaterial().isSolid() || world.getType(blockPosition.c(x, Math.max(y - 1, 0), z)).getBlock().getMaterial().isSolid()) {
|
||||
useTmp = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (useTmp) boundingBox = tmp;
|
||||
}
|
||||
// KigPaper end
|
||||
if (this.world.a(boundingBox.grow(0.0D, -0.4000000059604645D, 0.0D).shrink(0.001D, 0.001D, 0.001D), Material.WATER, this)) {
|
||||
if (!this.inWater && !this.justCreated) {
|
||||
this.X();
|
||||
}
|
||||
@ -1029,7 +1079,12 @@ public abstract class Entity implements ICommandListener {
|
||||
}
|
||||
|
||||
public boolean ab() {
|
||||
return this.world.a(this.getBoundingBox().grow(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA);
|
||||
int currentTick = MinecraftServer.currentTick;
|
||||
if (this.lastLavaCheck != currentTick) {
|
||||
this.lastLavaCheck = currentTick;
|
||||
this.isInLava = this.world.a(this.getBoundingBox().grow(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA);
|
||||
}
|
||||
return this.isInLava;
|
||||
}
|
||||
|
||||
public void a(float f, float f1, float f2) {
|
||||
@ -1649,7 +1704,7 @@ public abstract class Entity implements ICommandListener {
|
||||
this.vehicle = null;
|
||||
} else {
|
||||
// CraftBukkit start
|
||||
if ((this.bukkitEntity instanceof LivingEntity) && (entity.getBukkitEntity() instanceof Vehicle) && entity.world.isChunkLoaded((int) entity.locX >> 4, (int) entity.locZ >> 4, true)) {
|
||||
if ((this.bukkitEntity instanceof LivingEntity) && (entity.getBukkitEntity() instanceof Vehicle) && entity.world.isChunkLoaded(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4, true)) { // Migot - fix rounding error
|
||||
// It's possible to move from one vehicle to another. We need to check if they're already in a vehicle, and fire an exit event if they are.
|
||||
VehicleExitEvent exitEvent = null;
|
||||
if (this.vehicle != null && this.vehicle.getBukkitEntity() instanceof Vehicle) {
|
||||
@ -1986,6 +2041,15 @@ public abstract class Entity implements ICommandListener {
|
||||
}
|
||||
|
||||
public void c(int i) {
|
||||
// Migot start - Entities will be queued and teleported after all worlds have been ticked
|
||||
if(i != this.dimension) {
|
||||
this.targetDimension = i;
|
||||
this.world.queueEntityForDimensionChange(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void changeDimension(int i) {
|
||||
// Migot end
|
||||
if (!this.world.isClientSide && !this.dead) {
|
||||
this.world.methodProfiler.a("changeDimension");
|
||||
MinecraftServer minecraftserver = MinecraftServer.getServer();
|
||||
@ -2015,9 +2079,11 @@ public abstract class Entity implements ICommandListener {
|
||||
return;
|
||||
}
|
||||
exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo();
|
||||
if(exit != null) { // Migot
|
||||
this.teleportTo(exit, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void teleportTo(Location exit, boolean portal) {
|
||||
if (true) {
|
||||
|
@ -231,6 +231,8 @@ public class EntityArrow extends Entity implements IProjectile {
|
||||
if (!((EntityPlayer) shooter).getBukkitEntity().canSee(((EntityPlayer) movingobjectposition.entity).getBukkitEntity())) {
|
||||
movingobjectposition = null;
|
||||
}
|
||||
} else if (movingobjectposition != null && movingobjectposition.entity instanceof EntityArmorStand && movingobjectposition.entity.isInvisible()) {
|
||||
movingobjectposition = null;
|
||||
}
|
||||
// PaperSpigot end
|
||||
// TacoSpigot start - call better event
|
||||
@ -290,7 +292,9 @@ public class EntityArrow extends Entity implements IProjectile {
|
||||
}
|
||||
|
||||
if (this.shooter != null && movingobjectposition.entity != this.shooter && movingobjectposition.entity instanceof EntityHuman && this.shooter instanceof EntityPlayer) {
|
||||
((EntityPlayer) this.shooter).playerConnection.sendPacket(new PacketPlayOutGameStateChange(6, 0.0F));
|
||||
EntityPlayer shooter = (EntityPlayer) this.shooter;
|
||||
shooter.p(movingobjectposition.entity); // KigPaper - set attacked entity (used for wolf pathfinding)
|
||||
shooter.playerConnection.sendPacket(new PacketPlayOutGameStateChange(6, 0.0F));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ public abstract class EntityCreature extends EntityInsentient {
|
||||
|
||||
public void setSearchResult(PathSearchJobEntity pathSearchJobEntity, Entity target, PathEntity pathentity) {
|
||||
this.queuingManager.checkLastSearchResult(pathSearchJobEntity);
|
||||
if (this.goalTarget != null && this.goalTarget.equals(target)) {
|
||||
if (this.getGoalTarget() != null && this.getGoalTarget().equals(target)) {
|
||||
this.returnedPathEntity = pathentity;
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ public class EntityEnderman extends EntityMonster {
|
||||
return false;
|
||||
} else {
|
||||
Vec3D vec3d = entityhuman.d(1.0F).a();
|
||||
Vec3D vec3d1 = new Vec3D(this.locX - entityhuman.locX, this.getBoundingBox().b + (double) (this.length / 2.0F) - (entityhuman.locY + (double) entityhuman.getHeadHeight()), this.locZ - entityhuman.locZ);
|
||||
Vec3D vec3d1 = new Vec3D(this.locX - entityhuman.locX, (this.locY + (double) this.getHeadHeight()) - (entityhuman.locY + (double) entityhuman.getHeadHeight()), this.locZ - entityhuman.locZ); // Migot
|
||||
double d0 = vec3d1.b();
|
||||
|
||||
vec3d1 = vec3d1.a();
|
||||
@ -145,7 +145,7 @@ public class EntityEnderman extends EntityMonster {
|
||||
}
|
||||
|
||||
protected boolean b(Entity entity) {
|
||||
Vec3D vec3d = new Vec3D(this.locX - entity.locX, this.getBoundingBox().b + (double) (this.length / 2.0F) - entity.locY + (double) entity.getHeadHeight(), this.locZ - entity.locZ);
|
||||
Vec3D vec3d = new Vec3D(this.locX - entity.locX, this.locY + (double) this.getHeadHeight() - entity.locY + (double) entity.getHeadHeight(), this.locZ - entity.locZ); // Migot
|
||||
|
||||
vec3d = vec3d.a();
|
||||
double d0 = 16.0D;
|
||||
|
@ -59,11 +59,28 @@ public class EntityExperienceOrb extends Entity {
|
||||
this.j(this.locX, (this.getBoundingBox().b + this.getBoundingBox().e) / 2.0D, this.locZ);
|
||||
double d0 = 8.0D;
|
||||
|
||||
// Migot start
|
||||
EntityHuman foundTarget = null;
|
||||
if (this.targetTime < this.a - 20 + this.getId() % 100) {
|
||||
if (this.targetPlayer == null || this.targetPlayer.h(this) > d0 * d0) {
|
||||
this.targetPlayer = this.world.findNearbyPlayer(this, d0);
|
||||
foundTarget = this.world.findNearbyPlayer(this, d0);
|
||||
if(foundTarget == null) {
|
||||
this.targetPlayer = foundTarget;
|
||||
} else if(foundTarget != null && !foundTarget.equals(this.targetPlayer)) {
|
||||
// CraftBukkit start
|
||||
EntityTargetEvent event = CraftEventFactory.callEntityTargetEvent(this, foundTarget, EntityTargetEvent.TargetReason.CLOSEST_PLAYER);
|
||||
Entity target = event.getTarget() == null ? null : ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle();
|
||||
if(!event.isCancelled()) {
|
||||
if(target == null) {
|
||||
this.targetPlayer = null;
|
||||
} else if(target instanceof EntityHuman) {
|
||||
this.targetPlayer = (EntityHuman) target;
|
||||
}
|
||||
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
}
|
||||
// Migot end
|
||||
this.targetTime = this.a;
|
||||
}
|
||||
|
||||
|
@ -192,6 +192,8 @@ public class EntityFishingHook extends Entity {
|
||||
if (!((EntityPlayer) owner).getBukkitEntity().canSee(((EntityPlayer) movingobjectposition.entity).getBukkitEntity())) {
|
||||
movingobjectposition = null;
|
||||
}
|
||||
} else if (movingobjectposition != null && movingobjectposition.entity instanceof EntityArmorStand && movingobjectposition.entity.isInvisible()) {
|
||||
movingobjectposition = null;
|
||||
}
|
||||
// PaperSpigot end
|
||||
|
||||
@ -360,9 +362,6 @@ public class EntityFishingHook extends Entity {
|
||||
this.motY *= (double) f2;
|
||||
this.motZ *= (double) f2;
|
||||
this.setPosition(this.locX, this.locY, this.locZ);
|
||||
if (inPortal()) {
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@ -25,7 +26,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||
private Navigation navigation;
|
||||
public PathfinderGoalSelector goalSelector;
|
||||
public PathfinderGoalSelector targetSelector;
|
||||
public EntityLiving goalTarget;
|
||||
private WeakReference<EntityLiving> goalTarget; // KigPaper - wrap in WeakReference
|
||||
private EntitySenses bk;
|
||||
private ItemStack[] equipment = new ItemStack[5];
|
||||
public float[] dropChances = new float[5];
|
||||
@ -86,7 +87,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||
}
|
||||
|
||||
public EntityLiving getGoalTarget() {
|
||||
return this.goalTarget;
|
||||
return this.goalTarget == null ? null : this.goalTarget.get(); // KigPaper - WeakReference
|
||||
}
|
||||
|
||||
public void setGoalTarget(EntityLiving entityliving) {
|
||||
@ -119,7 +120,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||
entityliving = null;
|
||||
}
|
||||
}
|
||||
this.goalTarget = entityliving;
|
||||
this.goalTarget = new WeakReference<>(entityliving); // KigPaper - WeakReference
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
@ -277,6 +278,11 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||
|
||||
nbttagcompound.set("Leash", nbttagcompound1);
|
||||
}
|
||||
// Migot start
|
||||
else if (this.bq != null) {
|
||||
nbttagcompound.set("Leash", this.bq);
|
||||
}
|
||||
// Migot end
|
||||
|
||||
if (this.ce()) {
|
||||
nbttagcompound.setBoolean("NoAI", this.ce());
|
||||
@ -889,11 +895,12 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||
EntityLiving entityliving = (EntityLiving) iterator.next();
|
||||
|
||||
if (entityliving.getUniqueID().equals(uuid)) {
|
||||
this.bp = entityliving;
|
||||
this.setLeashHolder(entityliving, true); // Migot
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (this.bq.hasKeyOfType("X", 99) && this.bq.hasKeyOfType("Y", 99) && this.bq.hasKeyOfType("Z", 99)) {
|
||||
}
|
||||
if (this.bp == null && this.bq.hasKeyOfType("X", 99) && this.bq.hasKeyOfType("Y", 99) && this.bq.hasKeyOfType("Z", 99)) { // Migot
|
||||
BlockPosition blockposition = new BlockPosition(this.bq.getInt("X"), this.bq.getInt("Y"), this.bq.getInt("Z"));
|
||||
EntityLeash entityleash = EntityLeash.b(this.world, blockposition);
|
||||
|
||||
@ -901,8 +908,9 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||
entityleash = EntityLeash.a(this.world, blockposition);
|
||||
}
|
||||
|
||||
this.bp = entityleash;
|
||||
} else {
|
||||
this.setLeashHolder(entityleash, true); // Migot
|
||||
}
|
||||
if (this.bp == null) { // Migot
|
||||
this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit
|
||||
this.unleash(false, true);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import com.google.common.collect.Lists;
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
import org.bukkit.craftbukkit.util.CraftPotionUtil;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
|
||||
@ -1786,7 +1787,10 @@ public abstract class EntityLiving extends Entity {
|
||||
// CraftBukkit end
|
||||
// PaperSpigot start - make dismountEvent cancellable
|
||||
EntityDismountEvent dismountEvent = new EntityDismountEvent(this.getBukkitEntity(), this.vehicle.getBukkitEntity()); // Spigot
|
||||
// KigPaper - only trigger EntityDismountEvent if the dismount was triggered by sneaking
|
||||
if(!(this.bukkitEntity instanceof Player) || ((Player) this.bukkitEntity).isSneaking()) {
|
||||
Bukkit.getPluginManager().callEvent(dismountEvent);
|
||||
}
|
||||
if (dismountEvent.isCancelled()) return;
|
||||
// PaperSpigot end
|
||||
|
||||
|
@ -523,6 +523,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||||
}
|
||||
|
||||
public void c(int i) {
|
||||
// Migot Start
|
||||
super.c(i);
|
||||
}
|
||||
|
||||
public void changeDimension(int i) {
|
||||
// Migot end
|
||||
// PaperSpigot start - Allow configurable end portal credits
|
||||
boolean endPortal = this.dimension == 1 && i == 1;
|
||||
if (endPortal) {
|
||||
@ -563,7 +569,6 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||||
this.bN = -1;
|
||||
}
|
||||
// PaperSpigot end
|
||||
|
||||
}
|
||||
|
||||
public boolean a(EntityPlayer entityplayer) {
|
||||
|
@ -158,6 +158,8 @@ public abstract class EntityProjectile extends Entity implements IProjectile {
|
||||
if (!((EntityPlayer) shooter).getBukkitEntity().canSee(((EntityPlayer) movingobjectposition.entity).getBukkitEntity())) {
|
||||
movingobjectposition = null;
|
||||
}
|
||||
} else if (movingobjectposition != null && movingobjectposition.entity instanceof EntityArmorStand && movingobjectposition.entity.isInvisible()) {
|
||||
movingobjectposition = null;
|
||||
}
|
||||
// PaperSpigot end
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.elevatemc.spigot.eSpigotFeature;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@ -275,8 +273,35 @@ public class EntityTrackerEntry {
|
||||
DataWatcher datawatcher = this.tracker.getDataWatcher();
|
||||
|
||||
if (datawatcher.a()) {
|
||||
if (eSpigotFeature.OBFUSCATE_HEALTH.isEnabled()) {
|
||||
List<DataWatcher.WatchableObject> changedMetadata = datawatcher.b();
|
||||
Iterator<DataWatcher.WatchableObject> iter = changedMetadata.iterator();
|
||||
boolean found = false;
|
||||
|
||||
while (iter.hasNext()) {
|
||||
DataWatcher.WatchableObject watchable = iter.next();
|
||||
if (watchable.a() == 6) {
|
||||
iter.remove();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
changedMetadata.add(new DataWatcher.WatchableObject(3, 6, 1.0F));
|
||||
}
|
||||
|
||||
PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(this.tracker.getId(), changedMetadata);
|
||||
|
||||
// Beanes - Broadcast the modified metadata packet to everyone
|
||||
this.broadcast(metadataPacket);
|
||||
|
||||
// Beanes - Send the correct metadata packet to the player
|
||||
if (this.tracker instanceof EntityPlayer)
|
||||
((EntityPlayer) this.tracker).playerConnection.sendPacket(new PacketPlayOutEntityMetadata(this.tracker.getId(), datawatcher, false));
|
||||
} else {
|
||||
this.broadcastIncludingSelf(new PacketPlayOutEntityMetadata(this.tracker.getId(), datawatcher, false));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.tracker instanceof EntityLiving) {
|
||||
AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap();
|
||||
@ -405,7 +430,13 @@ public class EntityTrackerEntry {
|
||||
|
||||
// CraftBukkit start - Fix for nonsensical head yaw
|
||||
this.i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F);
|
||||
this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i));
|
||||
// KigPaper
|
||||
if (this.tracker instanceof EntityLiving) {
|
||||
this.i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F);
|
||||
// CraftBukkit what the fuck were you thinking?
|
||||
//this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i)); // KigPaper
|
||||
entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i));
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
if (this.tracker instanceof EntityLiving) {
|
||||
|
@ -12,6 +12,16 @@ public class FileIOThread implements Runnable {
|
||||
private volatile long d;
|
||||
private volatile boolean e;
|
||||
|
||||
// Migot start
|
||||
public boolean isDone() {
|
||||
return this.c == this.d;
|
||||
}
|
||||
|
||||
public void setNoDelay(boolean active) {
|
||||
this.e = active;
|
||||
}
|
||||
// Migot end
|
||||
|
||||
private FileIOThread() {
|
||||
Thread thread = new Thread(this, "File IO Thread");
|
||||
|
||||
|
@ -1,63 +1,115 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
// Migot start
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
// Migot end
|
||||
|
||||
public class IntCache {
|
||||
|
||||
private static int a = 256;
|
||||
private static List<int[]> b = Lists.newArrayList();
|
||||
private static List<int[]> c = Lists.newArrayList();
|
||||
private static List<int[]> d = Lists.newArrayList();
|
||||
private static List<int[]> e = Lists.newArrayList();
|
||||
// Migot start - Refactored IntCache to be thread local instead of static
|
||||
private static final ThreadLocal<IntCache> caches = new ThreadLocal<IntCache>() {
|
||||
@Override
|
||||
protected IntCache initialValue() {
|
||||
IntCache cache = new IntCache();
|
||||
synchronized(allCaches) {
|
||||
allCaches.add(new WeakReference<IntCache>(cache));
|
||||
}
|
||||
return new IntCache();
|
||||
}
|
||||
};
|
||||
|
||||
public static synchronized int[] a(int i) {
|
||||
private static List<WeakReference<IntCache>> allCaches = new ArrayList<WeakReference<IntCache>>();
|
||||
|
||||
private int a = 256;
|
||||
private List<int[]> b = Lists.newArrayList();
|
||||
private List<int[]> c = Lists.newArrayList();
|
||||
private List<int[]> d = Lists.newArrayList();
|
||||
private List<int[]> e = Lists.newArrayList();
|
||||
|
||||
public static int[] a(int i) {
|
||||
return caches.get().aNonStatic(i);
|
||||
}
|
||||
|
||||
public int[] aNonStatic(int i) {
|
||||
int[] aint;
|
||||
|
||||
if (i <= 256) {
|
||||
if (IntCache.b.isEmpty()) {
|
||||
if (this.b.isEmpty()) {
|
||||
aint = new int[256];
|
||||
if (c.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.c.add(aint);
|
||||
if (c.size() < org.spigotmc.SpigotConfig.intCacheLimit) this.c.add(aint);
|
||||
return aint;
|
||||
} else {
|
||||
aint = (int[]) IntCache.b.remove(IntCache.b.size() - 1);
|
||||
if (c.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.c.add(aint);
|
||||
aint = (int[]) this.b.remove(this.b.size() - 1);
|
||||
if (c.size() < org.spigotmc.SpigotConfig.intCacheLimit) this.c.add(aint);
|
||||
return aint;
|
||||
}
|
||||
} else if (i > IntCache.a) {
|
||||
IntCache.a = i;
|
||||
IntCache.d.clear();
|
||||
IntCache.e.clear();
|
||||
aint = new int[IntCache.a];
|
||||
if (e.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.e.add(aint);
|
||||
} else if (i > this.a) {
|
||||
this.a = i;
|
||||
this.d.clear();
|
||||
this.e.clear();
|
||||
aint = new int[this.a];
|
||||
if (e.size() < org.spigotmc.SpigotConfig.intCacheLimit) this.e.add(aint);
|
||||
return aint;
|
||||
} else if (IntCache.d.isEmpty()) {
|
||||
aint = new int[IntCache.a];
|
||||
if (e.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.e.add(aint);
|
||||
} else if (this.d.isEmpty()) {
|
||||
aint = new int[this.a];
|
||||
if (e.size() < org.spigotmc.SpigotConfig.intCacheLimit) this.e.add(aint);
|
||||
return aint;
|
||||
} else {
|
||||
aint = (int[]) IntCache.d.remove(IntCache.d.size() - 1);
|
||||
if (e.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.e.add(aint);
|
||||
aint = (int[]) this.d.remove(this.d.size() - 1);
|
||||
if (e.size() < org.spigotmc.SpigotConfig.intCacheLimit) this.e.add(aint);
|
||||
return aint;
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void a() {
|
||||
if (!IntCache.d.isEmpty()) {
|
||||
IntCache.d.remove(IntCache.d.size() - 1);
|
||||
public static void a() {
|
||||
caches.get().aNonStatic();
|
||||
}
|
||||
|
||||
if (!IntCache.b.isEmpty()) {
|
||||
IntCache.b.remove(IntCache.b.size() - 1);
|
||||
public void aNonStatic() {
|
||||
if (!this.d.isEmpty()) {
|
||||
this.d.remove(this.d.size() - 1);
|
||||
}
|
||||
|
||||
IntCache.d.addAll(IntCache.e);
|
||||
IntCache.b.addAll(IntCache.c);
|
||||
IntCache.e.clear();
|
||||
IntCache.c.clear();
|
||||
if (!this.b.isEmpty()) {
|
||||
this.b.remove(this.b.size() - 1);
|
||||
}
|
||||
|
||||
public static synchronized String b() {
|
||||
return "cache: " + IntCache.d.size() + ", tcache: " + IntCache.b.size() + ", allocated: " + IntCache.e.size() + ", tallocated: " + IntCache.c.size();
|
||||
this.d.addAll(this.e);
|
||||
this.b.addAll(this.c);
|
||||
this.e.clear();
|
||||
this.c.clear();
|
||||
}
|
||||
|
||||
public static String b() {
|
||||
int cache = 0;
|
||||
int tcache = 0;
|
||||
int allocated = 0;
|
||||
int tallocated = 0;
|
||||
int numberOfCaches;
|
||||
|
||||
synchronized(allCaches) {
|
||||
numberOfCaches = allCaches.size();
|
||||
Iterator<WeakReference<IntCache>> iter = allCaches.iterator();
|
||||
while(iter.hasNext()) {
|
||||
WeakReference<IntCache> reference = iter.next();
|
||||
IntCache intcache = reference.get();
|
||||
if(intcache != null) {
|
||||
cache += intcache.d.size();
|
||||
tcache += intcache.b.size();
|
||||
allocated += intcache.e.size();
|
||||
tallocated += intcache.c.size();
|
||||
} else {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return String.valueOf(numberOfCaches) + " IntCaches. In Total => cache: " + cache + ", tcache: " + tcache + ", allocated: " + allocated + ", tallocated: " + tallocated;
|
||||
}
|
||||
// Migot end
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import co.aikar.timings.SpigotTimings;
|
||||
import com.elevatemc.spigot.threading.ThreadingManager;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
@ -10,6 +11,7 @@ import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.GameProfileRepository;
|
||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
import com.elevatemc.spigot.world.AutoSaveJob;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@ -91,6 +93,49 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
|
||||
public int autosavePeriod;
|
||||
public double[] recentTps = new double[3]; // PaperSpigot - Fine have your darn compat with bad plugins
|
||||
|
||||
// Migot start
|
||||
private LinkedList<AutoSaveJob> autoSaveWorlds = new LinkedList<AutoSaveJob>();
|
||||
private int autoSaveDelay = 0;
|
||||
private boolean autoSaveOrdered = false;
|
||||
|
||||
private void queueWorldsForAutoSave() {
|
||||
if (!this.N) {
|
||||
this.autoSaveWorlds.clear();
|
||||
for (int j = 0; j < this.worlds.size(); ++j) {
|
||||
WorldServer worldserver = this.worlds.get(j);
|
||||
if(worldserver != null) {
|
||||
this.autoSaveWorlds.add(new AutoSaveJob(AutoSaveJob.JobDetail.WORLD_SAVE, worldserver));
|
||||
this.autoSaveWorlds.add(new AutoSaveJob(AutoSaveJob.JobDetail.WORLD_SAVEEVENT, worldserver));
|
||||
}
|
||||
}
|
||||
int queuesize = this.autoSaveWorlds.size() / 2;
|
||||
this.autoSaveDelay = 0;
|
||||
this.autoSaveOrdered = true;
|
||||
this.info("[AutoSave] " + queuesize + " worlds - Starting ...");
|
||||
}
|
||||
}
|
||||
|
||||
private void autoSaveNextWorld() throws ExceptionWorldConflict {
|
||||
if(!this.autoSaveWorlds.isEmpty()) {
|
||||
if(this.autoSaveDelay++ > 20) { // delay of 1 seconds between checks of the auto-save job queue
|
||||
this.autoSaveDelay = 0;
|
||||
if(this.autoSaveWorlds.getFirst().process()) {
|
||||
this.autoSaveWorlds.removeFirst();
|
||||
}
|
||||
}
|
||||
} else if(this.autoSaveOrdered){
|
||||
this.info("[AutoSave] Done.");
|
||||
this.autoSaveOrdered = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelHeavyCalculationsForAllWorlds(boolean cancel) {
|
||||
for(WorldServer ws: this.worlds) {
|
||||
ws.cancelHeavyCalculations(cancel);
|
||||
}
|
||||
}
|
||||
// Migot end
|
||||
|
||||
private ServerConnection q; // Spigot
|
||||
private String serverIp;
|
||||
private int u = -1;
|
||||
@ -128,9 +173,12 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
|
||||
// CraftBukkit start
|
||||
private boolean hasStopped = false;
|
||||
|
||||
private final ThreadingManager threadingManager;
|
||||
|
||||
public MinecraftServer(OptionSet options, Proxy proxy, File file1) {
|
||||
io.netty.util.ResourceLeakDetector.setEnabled(false); // Spigot - disable
|
||||
this.e = proxy;
|
||||
this.threadingManager = new ThreadingManager();
|
||||
MinecraftServer.l = this;
|
||||
// this.universe = file; // CraftBukkit
|
||||
// this.q = new ServerConnection(this); // Spigot
|
||||
@ -634,6 +682,8 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
|
||||
this.Z.c();
|
||||
}
|
||||
//Spigot end
|
||||
|
||||
this.threadingManager.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@ -687,17 +737,17 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
|
||||
if (wait > 0L) {
|
||||
if (catchupTime < 2E6) {
|
||||
wait += Math.abs(catchupTime);
|
||||
}
|
||||
if (wait < catchupTime) {
|
||||
} else /* KigPaper */ if (wait < catchupTime) {
|
||||
catchupTime -= wait;
|
||||
wait = 0L;
|
||||
} else if (catchupTime > 2E6) {
|
||||
} else /*if (catchupTime > 2E6)*/ { // KigPaper
|
||||
wait -= catchupTime;
|
||||
catchupTime = 0L;
|
||||
}
|
||||
}
|
||||
if (wait > 0L) {
|
||||
Thread.sleep(1L);
|
||||
curTime = System.nanoTime(); // KigPaper
|
||||
wait = MinecraftServer.TICK_TIME - (curTime - lastTick);
|
||||
}
|
||||
|
||||
@ -790,19 +840,24 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
|
||||
if (file.isFile()) {
|
||||
ByteBuf bytebuf = Unpooled.buffer();
|
||||
|
||||
ByteBuf faviconBuffer = null; // KigPaper
|
||||
try {
|
||||
BufferedImage bufferedimage = ImageIO.read(file);
|
||||
|
||||
Validate.validState(bufferedimage.getWidth() == 64, "Must be 64 pixels wide");
|
||||
Validate.validState(bufferedimage.getHeight() == 64, "Must be 64 pixels high");
|
||||
ImageIO.write(bufferedimage, "PNG", new ByteBufOutputStream(bytebuf));
|
||||
ByteBuf bytebuf1 = Base64.encode(bytebuf);
|
||||
//ByteBuf bytebuf1 = Base64.encode(bytebuf); // KigPaper
|
||||
faviconBuffer = Base64.encode(bytebuf);
|
||||
|
||||
serverping.setFavicon("data:image/png;base64," + bytebuf1.toString(Charsets.UTF_8));
|
||||
serverping.setFavicon("data:image/png;base64," + faviconBuffer.toString(Charsets.UTF_8));
|
||||
} catch (Exception exception) {
|
||||
MinecraftServer.LOGGER.error("Couldn't load server icon", exception);
|
||||
} finally {
|
||||
bytebuf.release();
|
||||
// KigPaper start
|
||||
if(faviconBuffer != null) faviconBuffer.release();
|
||||
// KigPaper end
|
||||
}
|
||||
}
|
||||
|
||||
@ -846,24 +901,23 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
|
||||
}
|
||||
|
||||
if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
|
||||
SpigotTimings.worldSaveTimer.startTiming(); // Spigot
|
||||
//SpigotTimings.worldSaveTimer.startTiming(); // Spigot // Migot - moved to com.elevatemc.spigot.world.AutoSaveJob
|
||||
this.methodProfiler.a("save");
|
||||
this.v.savePlayers();
|
||||
// Spigot Start
|
||||
// We replace this with saving each individual world as this.saveChunks(...) is broken,
|
||||
// and causes the main thread to sleep for random amounts of time depending on chunk activity
|
||||
// Also pass flag to only save modified chunks
|
||||
server.playerCommandState = true;
|
||||
for (World world : worlds) {
|
||||
world.getWorld().save(false);
|
||||
}
|
||||
server.playerCommandState = false;
|
||||
// this.saveChunks(true);
|
||||
// Spigot End
|
||||
this.queueWorldsForAutoSave(); // Migot
|
||||
this.methodProfiler.b();
|
||||
SpigotTimings.worldSaveTimer.stopTiming(); // Spigot
|
||||
//SpigotTimings.worldSaveTimer.stopTiming(); // Spigot // Migot - moved to com.elevatemc.spigot.world.AutoSaveJob
|
||||
}
|
||||
|
||||
// Migot start
|
||||
if(this.autoSaveOrdered) {
|
||||
this.autoSaveNextWorld();
|
||||
}
|
||||
|
||||
long tickTime = System.nanoTime() - i;
|
||||
ThreadingManager.checkTickTime(tickTime);
|
||||
// Migot end
|
||||
|
||||
this.methodProfiler.a("tallying");
|
||||
this.h[this.ticks % 100] = System.nanoTime() - i;
|
||||
this.methodProfiler.b();
|
||||
@ -1013,6 +1067,12 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
|
||||
// this.i[i][this.ticks % 100] = System.nanoTime() - j; // CraftBukkit
|
||||
}
|
||||
|
||||
// Migot start
|
||||
for(i = 0; i < this.worlds.size(); ++i) {
|
||||
this.worlds.get(i).processDimensionChangeQueue();
|
||||
}
|
||||
// Migot end
|
||||
|
||||
this.methodProfiler.c("connection");
|
||||
SpigotTimings.connectionTimer.startTiming(); // Spigot
|
||||
this.aq().c();
|
||||
@ -1083,7 +1143,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return "1.8.8";
|
||||
return "1.8.9";
|
||||
}
|
||||
|
||||
public int I() {
|
||||
@ -1118,7 +1178,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
|
||||
}
|
||||
|
||||
public String getServerModName() {
|
||||
return "TacoSpigot"; // TacoSpigot - TacoSpigot // PaperSpigot - PaperSpigot > // Spigot - Spigot > // CraftBukkit - cb > vanilla!
|
||||
return "eSpigot"; // eSpigot - eSpigot // TacoSpigot - TacoSpigot // PaperSpigot - PaperSpigot > // Spigot - Spigot > // CraftBukkit - cb > vanilla!
|
||||
}
|
||||
|
||||
public CrashReport b(CrashReport crashreport) {
|
||||
|
@ -30,6 +30,7 @@ public abstract class MobSpawnerAbstract {
|
||||
private int requiredPlayerRange = 16;
|
||||
private int spawnRange = 4;
|
||||
private int tickDelay = 0; // PaperSpigot
|
||||
private int spawningPenalty = 0; // Migot
|
||||
|
||||
public MobSpawnerAbstract() {}
|
||||
|
||||
@ -138,6 +139,14 @@ public abstract class MobSpawnerAbstract {
|
||||
if (flag) {
|
||||
this.h();
|
||||
}
|
||||
// Migot start
|
||||
else {
|
||||
this.spawnDelay += this.spawningPenalty;
|
||||
if(this.spawningPenalty < 40) {
|
||||
this.spawningPenalty++;
|
||||
}
|
||||
}
|
||||
// Migot end
|
||||
}
|
||||
|
||||
}
|
||||
@ -238,6 +247,8 @@ public abstract class MobSpawnerAbstract {
|
||||
this.spawnDelay = this.minSpawnDelay + this.a().random.nextInt(i);
|
||||
}
|
||||
|
||||
this.spawningPenalty = 0; // Migot
|
||||
|
||||
if (this.mobs.size() > 0) {
|
||||
this.a((MobSpawnerAbstract.a) WeightedRandom.a(this.a().random, this.mobs));
|
||||
}
|
||||
|
@ -16,6 +16,21 @@ public abstract class NBTBase {
|
||||
|
||||
public abstract byte getTypeId();
|
||||
|
||||
// Migot start
|
||||
protected static java.util.concurrent.ConcurrentHashMap<String, String> storedStrings = new java.util.concurrent.ConcurrentHashMap<String, String>(16, 0.75f, 2);
|
||||
|
||||
public static String getStoredString(String name, boolean store) {
|
||||
String str = storedStrings.get(name);
|
||||
if(str == null) {
|
||||
if(store) {
|
||||
storedStrings.put(name, name);
|
||||
}
|
||||
str = name;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
// Migot end
|
||||
|
||||
protected NBTBase() {}
|
||||
|
||||
protected static NBTBase createTag(byte b0) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
@ -10,42 +11,46 @@ import java.util.Map.Entry;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class NBTTagCompound extends NBTBase {
|
||||
|
||||
private it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, NBTBase> map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound
|
||||
|
||||
public NBTTagCompound() {
|
||||
}
|
||||
public NBTTagCompound() {}
|
||||
|
||||
public NBTTagCompound(it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, NBTBase> map)
|
||||
{
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
void write(DataOutput var1) throws IOException {
|
||||
Iterator var2 = this.map.keySet().iterator();
|
||||
void write(DataOutput dataoutput) throws IOException {
|
||||
Iterator iterator = this.map.keySet().iterator();
|
||||
|
||||
while(var2.hasNext()) {
|
||||
String var3 = (String)var2.next();
|
||||
NBTBase var4 = (NBTBase)this.map.get(var3);
|
||||
a(var3, var4, var1);
|
||||
while (iterator.hasNext()) {
|
||||
String s = (String) iterator.next();
|
||||
NBTBase nbtbase = (NBTBase) this.map.get(s);
|
||||
|
||||
a(s, nbtbase, dataoutput);
|
||||
}
|
||||
|
||||
var1.writeByte(0);
|
||||
dataoutput.writeByte(0);
|
||||
}
|
||||
|
||||
void load(DataInput var1, int var2, NBTReadLimiter var3) throws IOException {
|
||||
var3.a(384L);
|
||||
if (var2 > 512) {
|
||||
void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
|
||||
nbtreadlimiter.a(384L);
|
||||
if (i > 512) {
|
||||
throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
|
||||
} else {
|
||||
this.map.clear();
|
||||
|
||||
byte var4;
|
||||
while((var4 = a(var1, var3)) != 0) {
|
||||
String var5 = b(var1, var3);
|
||||
var3.a((long)(224 + 16 * var5.length()));
|
||||
NBTBase var6 = a(var4, var5, var1, var2 + 1, var3);
|
||||
if (this.map.put(var5, var6) != null) {
|
||||
var3.a(288L);
|
||||
byte b0;
|
||||
|
||||
while ((b0 = a(datainput, nbtreadlimiter)) != 0) {
|
||||
String s = getStoredString(b(datainput, nbtreadlimiter), true); // Migot
|
||||
|
||||
nbtreadlimiter.a((long) (224 + 16 * s.length()));
|
||||
NBTBase nbtbase = a(b0, s, datainput, i + 1, nbtreadlimiter);
|
||||
|
||||
if (this.map.put(s, nbtbase) != null) {
|
||||
nbtreadlimiter.a(288L);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,214 +62,228 @@ public class NBTTagCompound extends NBTBase {
|
||||
}
|
||||
|
||||
public byte getTypeId() {
|
||||
return 10;
|
||||
return (byte) 10;
|
||||
}
|
||||
|
||||
public void set(String var1, NBTBase var2) {
|
||||
this.map.put(var1, var2);
|
||||
public void set(String s, NBTBase nbtbase) {
|
||||
this.map.put(s, nbtbase);
|
||||
}
|
||||
|
||||
public void setByte(String var1, byte var2) {
|
||||
this.map.put(var1, new NBTTagByte(var2));
|
||||
public void setByte(String s, byte b0) {
|
||||
this.map.put(s, new NBTTagByte(b0));
|
||||
}
|
||||
|
||||
public void setShort(String var1, short var2) {
|
||||
this.map.put(var1, new NBTTagShort(var2));
|
||||
public void setShort(String s, short short0) {
|
||||
this.map.put(s, new NBTTagShort(short0));
|
||||
}
|
||||
|
||||
public void setInt(String var1, int var2) {
|
||||
this.map.put(var1, new NBTTagInt(var2));
|
||||
public void setInt(String s, int i) {
|
||||
this.map.put(s, new NBTTagInt(i));
|
||||
}
|
||||
|
||||
public void setLong(String var1, long var2) {
|
||||
this.map.put(var1, new NBTTagLong(var2));
|
||||
public void setLong(String s, long i) {
|
||||
this.map.put(s, new NBTTagLong(i));
|
||||
}
|
||||
|
||||
public void setFloat(String var1, float var2) {
|
||||
this.map.put(var1, new NBTTagFloat(var2));
|
||||
public void setFloat(String s, float f) {
|
||||
this.map.put(s, new NBTTagFloat(f));
|
||||
}
|
||||
|
||||
public void setDouble(String var1, double var2) {
|
||||
this.map.put(var1, new NBTTagDouble(var2));
|
||||
public void setDouble(String s, double d0) {
|
||||
this.map.put(s, new NBTTagDouble(d0));
|
||||
}
|
||||
|
||||
public void setString(String var1, String var2) {
|
||||
this.map.put(var1, new NBTTagString(var2));
|
||||
public void setString(String s, String s1) {
|
||||
this.map.put(s, new NBTTagString(s1));
|
||||
}
|
||||
|
||||
public void setByteArray(String var1, byte[] var2) {
|
||||
this.map.put(var1, new NBTTagByteArray(var2));
|
||||
public void setByteArray(String s, byte[] abyte) {
|
||||
this.map.put(s, new NBTTagByteArray(abyte));
|
||||
}
|
||||
|
||||
public void setIntArray(String var1, int[] var2) {
|
||||
this.map.put(var1, new NBTTagIntArray(var2));
|
||||
public void setIntArray(String s, int[] aint) {
|
||||
this.map.put(s, new NBTTagIntArray(aint));
|
||||
}
|
||||
|
||||
public void setBoolean(String var1, boolean var2) {
|
||||
this.setByte(var1, (byte)(var2 ? 1 : 0));
|
||||
public void setBoolean(String s, boolean flag) {
|
||||
this.setByte(s, (byte) (flag ? 1 : 0));
|
||||
}
|
||||
|
||||
public NBTBase get(String var1) {
|
||||
return (NBTBase)this.map.get(var1);
|
||||
public NBTBase get(String s) {
|
||||
return (NBTBase) this.map.get(s);
|
||||
}
|
||||
|
||||
public byte b(String var1) {
|
||||
NBTBase var2 = (NBTBase)this.map.get(var1);
|
||||
return var2 != null ? var2.getTypeId() : 0;
|
||||
public byte b(String s) {
|
||||
NBTBase nbtbase = (NBTBase) this.map.get(s);
|
||||
|
||||
return nbtbase != null ? nbtbase.getTypeId() : 0;
|
||||
}
|
||||
|
||||
public boolean hasKey(String var1) {
|
||||
return this.map.containsKey(var1);
|
||||
public boolean hasKey(String s) {
|
||||
return this.map.containsKey(s);
|
||||
}
|
||||
|
||||
public boolean hasKeyOfType(String var1, int var2) {
|
||||
byte var3 = this.b(var1);
|
||||
if (var3 == var2) {
|
||||
public boolean hasKeyOfType(String s, int i) {
|
||||
byte b0 = this.b(s);
|
||||
|
||||
if (b0 == i) {
|
||||
return true;
|
||||
} else if (var2 != 99) {
|
||||
if (var3 > 0) {
|
||||
} else if (i != 99) {
|
||||
if (b0 > 0) {
|
||||
;
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return var3 == 1 || var3 == 2 || var3 == 3 || var3 == 4 || var3 == 5 || var3 == 6;
|
||||
return b0 == 1 || b0 == 2 || b0 == 3 || b0 == 4 || b0 == 5 || b0 == 6;
|
||||
}
|
||||
}
|
||||
|
||||
public byte getByte(String var1) {
|
||||
public byte getByte(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 99) ? 0 : ((NBTNumber)this.map.get(var1)).f();
|
||||
} catch (ClassCastException var3) {
|
||||
return !this.hasKeyOfType(s, 99) ? 0 : ((NBTBase.NBTNumber) this.map.get(s)).f();
|
||||
} catch (ClassCastException classcastexception) {
|
||||
return (byte) 0;
|
||||
}
|
||||
}
|
||||
|
||||
public short getShort(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(s, 99) ? 0 : ((NBTBase.NBTNumber) this.map.get(s)).e();
|
||||
} catch (ClassCastException classcastexception) {
|
||||
return (short) 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getInt(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(s, 99) ? 0 : ((NBTBase.NBTNumber) this.map.get(s)).d();
|
||||
} catch (ClassCastException classcastexception) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public short getShort(String var1) {
|
||||
public long getLong(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 99) ? 0 : ((NBTNumber)this.map.get(var1)).e();
|
||||
} catch (ClassCastException var3) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getInt(String var1) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 99) ? 0 : ((NBTNumber)this.map.get(var1)).d();
|
||||
} catch (ClassCastException var3) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public long getLong(String var1) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 99) ? 0L : ((NBTNumber)this.map.get(var1)).c();
|
||||
} catch (ClassCastException var3) {
|
||||
return !this.hasKeyOfType(s, 99) ? 0L : ((NBTBase.NBTNumber) this.map.get(s)).c();
|
||||
} catch (ClassCastException classcastexception) {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
public float getFloat(String var1) {
|
||||
public float getFloat(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 99) ? 0.0F : ((NBTNumber)this.map.get(var1)).h();
|
||||
} catch (ClassCastException var3) {
|
||||
return !this.hasKeyOfType(s, 99) ? 0.0F : ((NBTBase.NBTNumber) this.map.get(s)).h();
|
||||
} catch (ClassCastException classcastexception) {
|
||||
return 0.0F;
|
||||
}
|
||||
}
|
||||
|
||||
public double getDouble(String var1) {
|
||||
public double getDouble(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 99) ? 0.0D : ((NBTNumber)this.map.get(var1)).g();
|
||||
} catch (ClassCastException var3) {
|
||||
return !this.hasKeyOfType(s, 99) ? 0.0D : ((NBTBase.NBTNumber) this.map.get(s)).g();
|
||||
} catch (ClassCastException classcastexception) {
|
||||
return 0.0D;
|
||||
}
|
||||
}
|
||||
|
||||
public String getString(String var1) {
|
||||
public String getString(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 8) ? "" : ((NBTBase)this.map.get(var1)).a_();
|
||||
} catch (ClassCastException var3) {
|
||||
return !this.hasKeyOfType(s, 8) ? "" : ((NBTBase) this.map.get(s)).a_();
|
||||
} catch (ClassCastException classcastexception) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getByteArray(String var1) {
|
||||
public byte[] getByteArray(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 7) ? new byte[0] : ((NBTTagByteArray)this.map.get(var1)).c();
|
||||
} catch (ClassCastException var3) {
|
||||
throw new ReportedException(this.a(var1, 7, var3));
|
||||
return !this.hasKeyOfType(s, 7) ? new byte[0] : ((NBTTagByteArray) this.map.get(s)).c();
|
||||
} catch (ClassCastException classcastexception) {
|
||||
throw new ReportedException(this.a(s, 7, classcastexception));
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getIntArray(String var1) {
|
||||
public int[] getIntArray(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 11) ? new int[0] : ((NBTTagIntArray)this.map.get(var1)).c();
|
||||
} catch (ClassCastException var3) {
|
||||
throw new ReportedException(this.a(var1, 11, var3));
|
||||
return !this.hasKeyOfType(s, 11) ? new int[0] : ((NBTTagIntArray) this.map.get(s)).c();
|
||||
} catch (ClassCastException classcastexception) {
|
||||
throw new ReportedException(this.a(s, 11, classcastexception));
|
||||
}
|
||||
}
|
||||
|
||||
public NBTTagCompound getCompound(String var1) {
|
||||
public NBTTagCompound getCompound(String s) {
|
||||
try {
|
||||
return !this.hasKeyOfType(var1, 10) ? new NBTTagCompound() : (NBTTagCompound)this.map.get(var1);
|
||||
} catch (ClassCastException var3) {
|
||||
throw new ReportedException(this.a(var1, 10, var3));
|
||||
return !this.hasKeyOfType(s, 10) ? new NBTTagCompound() : (NBTTagCompound) this.map.get(s);
|
||||
} catch (ClassCastException classcastexception) {
|
||||
throw new ReportedException(this.a(s, 10, classcastexception));
|
||||
}
|
||||
}
|
||||
|
||||
public NBTTagList getList(String var1, int var2) {
|
||||
public NBTTagList getList(String s, int i) {
|
||||
try {
|
||||
if (this.b(var1) != 9) {
|
||||
if (this.b(s) != 9) {
|
||||
return new NBTTagList();
|
||||
} else {
|
||||
NBTTagList var3 = (NBTTagList)this.map.get(var1);
|
||||
return var3.size() > 0 && var3.f() != var2 ? new NBTTagList() : var3;
|
||||
NBTTagList nbttaglist = (NBTTagList) this.map.get(s);
|
||||
|
||||
return nbttaglist.size() > 0 && nbttaglist.f() != i ? new NBTTagList() : nbttaglist;
|
||||
}
|
||||
} catch (ClassCastException var4) {
|
||||
throw new ReportedException(this.a(var1, 9, var4));
|
||||
} catch (ClassCastException classcastexception) {
|
||||
throw new ReportedException(this.a(s, 9, classcastexception));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getBoolean(String var1) {
|
||||
return this.getByte(var1) != 0;
|
||||
public boolean getBoolean(String s) {
|
||||
return this.getByte(s) != 0;
|
||||
}
|
||||
|
||||
public void remove(String var1) {
|
||||
this.map.remove(var1);
|
||||
public void remove(String s) {
|
||||
this.map.remove(s);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder var1 = new StringBuilder("{");
|
||||
StringBuilder stringbuilder = new StringBuilder("{");
|
||||
|
||||
Entry var3;
|
||||
for(Iterator var2 = this.map.entrySet().iterator(); var2.hasNext(); var1.append((String)var3.getKey()).append(':').append(var3.getValue())) {
|
||||
var3 = (Entry)var2.next();
|
||||
if (var1.length() != 1) {
|
||||
var1.append(',');
|
||||
Entry entry;
|
||||
|
||||
for (Iterator iterator = this.map.entrySet().iterator(); iterator.hasNext(); stringbuilder.append((String) entry.getKey()).append(':').append(entry.getValue())) {
|
||||
entry = (Entry) iterator.next();
|
||||
if (stringbuilder.length() != 1) {
|
||||
stringbuilder.append(',');
|
||||
}
|
||||
}
|
||||
|
||||
return var1.append('}').toString();
|
||||
return stringbuilder.append('}').toString();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.map.isEmpty();
|
||||
}
|
||||
|
||||
private CrashReport a(final String var1, final int var2, ClassCastException var3) {
|
||||
CrashReport var4 = CrashReport.a(var3, "Reading NBT data");
|
||||
CrashReportSystemDetails var5 = var4.a("Corrupt NBT tag", 1);
|
||||
var5.a("Tag type found", new Callable<String>() {
|
||||
public String call() throws Exception {
|
||||
return NBTBase.a[((NBTBase)NBTTagCompound.this.map.get(var1)).getTypeId()];
|
||||
private CrashReport a(final String s, final int i, ClassCastException classcastexception) {
|
||||
CrashReport crashreport = CrashReport.a(classcastexception, "Reading NBT data");
|
||||
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Corrupt NBT tag", 1);
|
||||
|
||||
crashreportsystemdetails.a("Tag type found", new Callable() {
|
||||
public String a() throws Exception {
|
||||
return NBTBase.a[((NBTBase) NBTTagCompound.this.map.get(s)).getTypeId()];
|
||||
}
|
||||
|
||||
public Object call() throws Exception {
|
||||
return this.a();
|
||||
}
|
||||
});
|
||||
var5.a("Tag type expected", new Callable<String>() {
|
||||
public String call() throws Exception {
|
||||
return NBTBase.a[var2];
|
||||
crashreportsystemdetails.a("Tag type expected", new Callable() {
|
||||
public String a() throws Exception {
|
||||
return NBTBase.a[i];
|
||||
}
|
||||
|
||||
public Object call() throws Exception {
|
||||
return this.a();
|
||||
}
|
||||
});
|
||||
var5.a("Tag name", var1);
|
||||
return var4;
|
||||
crashreportsystemdetails.a("Tag name", (Object) s);
|
||||
return crashreport;
|
||||
}
|
||||
|
||||
public NBTBase clone() {
|
||||
@ -278,10 +297,12 @@ public class NBTTagCompound extends NBTBase {
|
||||
return new NBTTagCompound(ret);
|
||||
}
|
||||
|
||||
public boolean equals(Object var1) {
|
||||
if (super.equals(var1)) {
|
||||
NBTTagCompound var2 = (NBTTagCompound)var1;
|
||||
return this.map.entrySet().equals(var2.map.entrySet());
|
||||
|
||||
public boolean equals(Object object) {
|
||||
if (super.equals(object)) {
|
||||
NBTTagCompound nbttagcompound = (NBTTagCompound) object;
|
||||
|
||||
return this.map.entrySet().equals(nbttagcompound.map.entrySet());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -291,52 +312,55 @@ public class NBTTagCompound extends NBTBase {
|
||||
return super.hashCode() ^ this.map.hashCode();
|
||||
}
|
||||
|
||||
private static void a(String var0, NBTBase var1, DataOutput var2) throws IOException {
|
||||
var2.writeByte(var1.getTypeId());
|
||||
if (var1.getTypeId() != 0) {
|
||||
var2.writeUTF(var0);
|
||||
var1.write(var2);
|
||||
private static void a(String s, NBTBase nbtbase, DataOutput dataoutput) throws IOException {
|
||||
dataoutput.writeByte(nbtbase.getTypeId());
|
||||
if (nbtbase.getTypeId() != 0) {
|
||||
dataoutput.writeUTF(s);
|
||||
nbtbase.write(dataoutput);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte a(DataInput var0, NBTReadLimiter var1) throws IOException {
|
||||
return var0.readByte();
|
||||
private static byte a(DataInput datainput, NBTReadLimiter nbtreadlimiter) throws IOException {
|
||||
return datainput.readByte();
|
||||
}
|
||||
|
||||
private static String b(DataInput var0, NBTReadLimiter var1) throws IOException {
|
||||
return var0.readUTF();
|
||||
private static String b(DataInput datainput, NBTReadLimiter nbtreadlimiter) throws IOException {
|
||||
return datainput.readUTF();
|
||||
}
|
||||
|
||||
static NBTBase a(byte var0, String var1, DataInput var2, int var3, NBTReadLimiter var4) throws IOException {
|
||||
NBTBase var5 = NBTBase.createTag(var0);
|
||||
static NBTBase a(byte b0, String s, DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
|
||||
NBTBase nbtbase = NBTBase.createTag(b0);
|
||||
|
||||
try {
|
||||
var5.load(var2, var3, var4);
|
||||
return var5;
|
||||
} catch (IOException var9) {
|
||||
CrashReport var7 = CrashReport.a(var9, "Loading NBT data");
|
||||
CrashReportSystemDetails var8 = var7.a("NBT Tag");
|
||||
var8.a("Tag name", var1);
|
||||
var8.a("Tag type", var0);
|
||||
throw new ReportedException(var7);
|
||||
nbtbase.load(datainput, i, nbtreadlimiter);
|
||||
return nbtbase;
|
||||
} catch (IOException ioexception) {
|
||||
CrashReport crashreport = CrashReport.a(ioexception, "Loading NBT data");
|
||||
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("NBT Tag");
|
||||
|
||||
crashreportsystemdetails.a("Tag name", (Object) s);
|
||||
crashreportsystemdetails.a("Tag type", (Object) Byte.valueOf(b0));
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
}
|
||||
|
||||
public void a(NBTTagCompound var1) {
|
||||
Iterator var2 = var1.map.keySet().iterator();
|
||||
public void a(NBTTagCompound nbttagcompound) {
|
||||
Iterator iterator = nbttagcompound.map.keySet().iterator();
|
||||
|
||||
while(var2.hasNext()) {
|
||||
String var3 = (String)var2.next();
|
||||
NBTBase var4 = (NBTBase)var1.map.get(var3);
|
||||
if (var4.getTypeId() == 10) {
|
||||
if (this.hasKeyOfType(var3, 10)) {
|
||||
NBTTagCompound var5 = this.getCompound(var3);
|
||||
var5.a((NBTTagCompound)var4);
|
||||
while (iterator.hasNext()) {
|
||||
String s = (String) iterator.next();
|
||||
NBTBase nbtbase = (NBTBase) nbttagcompound.map.get(s);
|
||||
|
||||
if (nbtbase.getTypeId() == 10) {
|
||||
if (this.hasKeyOfType(s, 10)) {
|
||||
NBTTagCompound nbttagcompound1 = this.getCompound(s);
|
||||
|
||||
nbttagcompound1.a((NBTTagCompound) nbtbase);
|
||||
} else {
|
||||
this.set(var3, var4.clone());
|
||||
this.set(s, nbtbase.clone());
|
||||
}
|
||||
} else {
|
||||
this.set(var3, var4.clone());
|
||||
this.set(s, nbtbase.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,65 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class NBTTagString extends NBTBase {
|
||||
|
||||
private String data;
|
||||
|
||||
public NBTTagString() {
|
||||
this.data = "";
|
||||
}
|
||||
|
||||
public NBTTagString(String s) {
|
||||
this.data = s;
|
||||
if (s == null) {
|
||||
throw new IllegalArgumentException("Empty string not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
void write(DataOutput dataoutput) throws IOException {
|
||||
dataoutput.writeUTF(this.data);
|
||||
}
|
||||
|
||||
void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
|
||||
nbtreadlimiter.a(288L);
|
||||
this.data = getStoredString(datainput.readUTF(), true); // Migot
|
||||
nbtreadlimiter.a((long) (16 * this.data.length()));
|
||||
}
|
||||
|
||||
public byte getTypeId() {
|
||||
return (byte) 8;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "\"" + this.data.replace("\"", "\\\"") + "\"";
|
||||
}
|
||||
|
||||
public NBTBase clone() {
|
||||
return new NBTTagString(this.data);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.data.isEmpty();
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
if (!super.equals(object)) {
|
||||
return false;
|
||||
} else {
|
||||
NBTTagString nbttagstring = (NBTTagString) object;
|
||||
|
||||
return this.data == null && nbttagstring.data == null || this.data != null && this.data.equals(nbttagstring.data);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return super.hashCode() ^ this.data.hashCode();
|
||||
}
|
||||
|
||||
public String a_() {
|
||||
return this.data;
|
||||
}
|
||||
}
|
@ -387,6 +387,7 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet> {
|
||||
}
|
||||
|
||||
public void close(IChatBaseComponent ichatbasecomponent) {
|
||||
this.i.clear(); // KigPaper
|
||||
// Spigot Start
|
||||
this.preparing = false;
|
||||
// Spigot End
|
||||
|
@ -249,6 +249,28 @@ public class PacketDataSerializer extends ByteBuf {
|
||||
}
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
public String readCappedString(int maxLength) {
|
||||
int toRead = this.e();
|
||||
|
||||
if (toRead > maxLength * 4) {
|
||||
throw new DecoderException("The received encoded string buffer length is longer than maximum allowed (" + toRead + " > " + maxLength * 4 + ")");
|
||||
} else if (toRead < 0) {
|
||||
throw new DecoderException("The received encoded string buffer length is less than zero! Weird string!");
|
||||
} else {
|
||||
int len = Math.min(toRead, maxLength);
|
||||
String s = new String(this.readBytes(len).array(), Charsets.UTF_8);
|
||||
|
||||
int remaining = toRead - len;
|
||||
if (remaining > 0) {
|
||||
this.skipBytes(remaining);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
// KigPaper end
|
||||
|
||||
public PacketDataSerializer a(String s) {
|
||||
byte[] abyte = s.getBytes(Charsets.UTF_8);
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PacketPlayInBlockPlace implements Packet<PacketListenerPlayIn> {
|
||||
@ -33,7 +35,12 @@ public class PacketPlayInBlockPlace implements Packet<PacketListenerPlayIn> {
|
||||
timestamp = System.currentTimeMillis(); // CraftBukkit
|
||||
this.b = packetdataserializer.c();
|
||||
this.c = packetdataserializer.readUnsignedByte();
|
||||
this.d = packetdataserializer.i();
|
||||
// KigPaper start - don't parse itemstack
|
||||
// this.d = packetdataserializer.i();
|
||||
// Consume everything and leave 3 bytes at the end
|
||||
if (packetdataserializer.readableBytes() < 3) throw new DecoderException("Expected 3 facing bytes");
|
||||
packetdataserializer.skipBytes(packetdataserializer.readableBytes() - 3);
|
||||
// KigPaper end
|
||||
this.e = (float) packetdataserializer.readUnsignedByte() / 16.0F;
|
||||
this.f = (float) packetdataserializer.readUnsignedByte() / 16.0F;
|
||||
this.g = (float) packetdataserializer.readUnsignedByte() / 16.0F;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import org.github.paperspigot.PaperSpigotConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PacketPlayInChat implements Packet<PacketListenerPlayIn> {
|
||||
@ -17,7 +19,7 @@ public class PacketPlayInChat implements Packet<PacketListenerPlayIn> {
|
||||
}
|
||||
|
||||
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||
this.a = packetdataserializer.c(100);
|
||||
this.a = PaperSpigotConfig.kickChatMessageLength ? packetdataserializer.c(100) : packetdataserializer.readCappedString(100); // KigPaper
|
||||
}
|
||||
|
||||
public void b(PacketDataSerializer packetdataserializer) throws IOException {
|
||||
|
@ -5,6 +5,7 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@ -13,6 +14,7 @@ public class PacketPlayOutEntityMetadata implements Packet<PacketListenerPlayOut
|
||||
|
||||
public int a;
|
||||
public List<DataWatcher.WatchableObject> b;
|
||||
private boolean found = false; // MineHQ
|
||||
|
||||
public PacketPlayOutEntityMetadata() {}
|
||||
|
||||
@ -23,7 +25,11 @@ public class PacketPlayOutEntityMetadata implements Packet<PacketListenerPlayOut
|
||||
} else {
|
||||
this.b = datawatcher.b();
|
||||
}
|
||||
}
|
||||
|
||||
public PacketPlayOutEntityMetadata(int i, List<DataWatcher.WatchableObject> list) {
|
||||
this.a = i;
|
||||
this.b = list;
|
||||
}
|
||||
|
||||
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||
@ -39,5 +45,4 @@ public class PacketPlayOutEntityMetadata implements Packet<PacketListenerPlayOut
|
||||
public void a(PacketListenerPlayOut packetlistenerplayout) {
|
||||
packetlistenerplayout.a(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package net.minecraft.server;
|
||||
public class PathfinderGoalSwell extends PathfinderGoal {
|
||||
|
||||
EntityCreeper a;
|
||||
EntityLiving b;
|
||||
//EntityLiving b; // KigPaper
|
||||
|
||||
public PathfinderGoalSwell(EntityCreeper entitycreeper) {
|
||||
this.a = entitycreeper;
|
||||
@ -18,19 +18,21 @@ public class PathfinderGoalSwell extends PathfinderGoal {
|
||||
|
||||
public void c() {
|
||||
this.a.getNavigation().n();
|
||||
this.b = this.a.getGoalTarget();
|
||||
// this.b = this.a.getGoalTarget(); // KigPaper
|
||||
}
|
||||
|
||||
public void d() {
|
||||
this.b = null;
|
||||
//this.b = null; // KigPaper
|
||||
}
|
||||
|
||||
public void e() {
|
||||
if (this.b == null) {
|
||||
// KigPaper - use Entity GoalTarget
|
||||
EntityLiving target = this.a.getGoalTarget();
|
||||
if (target == null) {
|
||||
this.a.a(-1);
|
||||
} else if (this.a.h(this.b) > 49.0D) {
|
||||
} else if (this.a.h(target) > 49.0D) {
|
||||
this.a.a(-1);
|
||||
} else if (!this.a.getEntitySenses().a(this.b)) {
|
||||
} else if (!this.a.getEntitySenses().a(target)) {
|
||||
this.a.a(-1);
|
||||
} else {
|
||||
this.a.a(1);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import com.elevatemc.spigot.threading.ThreadingManager;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import java.io.DataInputStream;
|
||||
@ -96,10 +97,15 @@ public class PersistentCollection {
|
||||
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
||||
|
||||
nbttagcompound1.set("data", nbttagcompound);
|
||||
// Migot start
|
||||
/*
|
||||
FileOutputStream fileoutputstream = new FileOutputStream(file);
|
||||
|
||||
NBTCompressedStreamTools.a(nbttagcompound1, (OutputStream) fileoutputstream);
|
||||
fileoutputstream.close();
|
||||
*/
|
||||
ThreadingManager.saveNBTFileStatic((NBTTagCompound) (nbttagcompound1.clone()), file);
|
||||
// Migot end
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
|
@ -92,6 +92,7 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
private double q;
|
||||
private boolean checkMovement = true;
|
||||
private boolean processedDisconnect; // CraftBukkit - added
|
||||
private boolean disconnecting; // KigPaper - added
|
||||
|
||||
public PlayerConnection(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) {
|
||||
this.minecraftServer = minecraftserver;
|
||||
@ -107,6 +108,7 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
private final org.bukkit.craftbukkit.CraftServer server;
|
||||
private int lastTick = MinecraftServer.currentTick;
|
||||
private int lastDropTick = MinecraftServer.currentTick;
|
||||
private int lastBookTick = MinecraftServer.currentTick;
|
||||
private int dropCount = 0;
|
||||
private static final int SURVIVAL_PLACE_DISTANCE_SQUARED = 6 * 6;
|
||||
private static final int CREATIVE_PLACE_DISTANCE_SQUARED = 7 * 7;
|
||||
@ -163,6 +165,8 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
}
|
||||
|
||||
public void disconnect(String s) {
|
||||
// KigPaper - if already disconnecting, do nothing
|
||||
if(disconnecting) return;
|
||||
// CraftBukkit start - fire PlayerKickEvent
|
||||
String leaveMessage = EnumChatFormat.YELLOW + this.player.getName() + " left the game.";
|
||||
|
||||
@ -176,6 +180,9 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
// Do not kick the player
|
||||
return;
|
||||
}
|
||||
// KigPaper - mark the player as disconnecting, so all other disconnect requests are ignored.
|
||||
disconnecting = true;
|
||||
|
||||
// Send the possibly modified leave message
|
||||
s = event.getReason();
|
||||
// CraftBukkit end
|
||||
@ -805,6 +812,7 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
if (itemstack != null && itemstack.count == 0) {
|
||||
this.player.inventory.items[this.player.inventory.itemInHandIndex] = null;
|
||||
itemstack = null;
|
||||
always = true; // KigPaper - send update packet
|
||||
}
|
||||
|
||||
if (itemstack == null || itemstack.l() == 0) {
|
||||
@ -815,7 +823,7 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
this.player.activeContainer.b();
|
||||
this.player.g = false;
|
||||
// CraftBukkit - TODO CHECK IF NEEDED -- new if structure might not need 'always'. Kept it in for now, but may be able to remove in future
|
||||
if (!ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack()) || always) {
|
||||
if (!ItemStack.matches(this.player.inventory.getItemInHand(), itemstack) || always) { // KigPaper - use saved itemstack instead of stack from packet
|
||||
this.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, slot.rawSlotIndex, this.player.inventory.getItemInHand()));
|
||||
}
|
||||
}
|
||||
@ -1357,6 +1365,47 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
|
||||
this.player.resetIdleTimer();
|
||||
if (entity != null) {
|
||||
// KigPaper start - allow hitting the vehicle when hitboxes collide / allow the player to hit others if they are being ridden by something
|
||||
if(PaperSpigotConfig.betterVehicleHitboxes) {
|
||||
if (entity instanceof EntityPlayer && entity.vehicle != null && !((EntityPlayer) entity).collidesWithEntities) {
|
||||
// Allow hitting the vehicle when hitboxes collide
|
||||
// Ray trace to see if the player should hit the vehicle instead
|
||||
double maxDist = 3.0;
|
||||
Vec3D look = player.ap();
|
||||
Vec3D eyePos = new Vec3D(player.locX, player.locY + player.getBukkitEntity().getEyeHeight(), player.locZ);
|
||||
Vec3D maxDistLook = eyePos.add(look.a * maxDist, look.b * maxDist, look.c * maxDist);
|
||||
Entity vehicle = entity.vehicle;
|
||||
List<Entity> collisions = worldserver.a(player, player.getBoundingBox()
|
||||
.a(look.a * maxDist, look.b * maxDist, look.c * maxDist) // add coords
|
||||
.grow(1D, 1D, 1D), e -> e == vehicle); // Only check for the vehicle
|
||||
for (Entity match : collisions) {
|
||||
AxisAlignedBB expandedHitbox = match.getBoundingBox().grow(0.1D, 0.1D, 0.1D); // Hit box is collision box + 0.1
|
||||
if (expandedHitbox.a(eyePos) || expandedHitbox.a(eyePos, maxDistLook) != null) {
|
||||
entity = match;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (entity == player.passenger) { // player hit passenger
|
||||
// Allow the player to hit others if they are being ridden by something
|
||||
// Ray trace to see if the player should hit someone else instead
|
||||
double maxDist = 3.0;
|
||||
Vec3D look = player.ap();
|
||||
Vec3D eyePos = new Vec3D(player.locX, player.locY + player.getBukkitEntity().getEyeHeight(), player.locZ);
|
||||
Vec3D maxDistLook = eyePos.add(look.a * maxDist, look.b * maxDist, look.c * maxDist);
|
||||
Entity passenger = entity.passenger;
|
||||
List<Entity> collisions = worldserver.a(player, player.getBoundingBox()
|
||||
.a(look.a * maxDist, look.b * maxDist, look.c * maxDist) // add coords
|
||||
.grow(1D, 1D, 1D), e -> e != passenger); // Don't include passenger
|
||||
for (Entity match : collisions) {
|
||||
AxisAlignedBB expandedHitbox = match.getBoundingBox().grow(0.1D, 0.1D, 0.1D); // Hit box is collision box + 0.1
|
||||
if (expandedHitbox.a(eyePos) || expandedHitbox.a(eyePos, maxDistLook) != null) {
|
||||
entity = match;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// KigPaper end
|
||||
boolean flag = this.player.hasLineOfSight(entity);
|
||||
double d0 = 36.0D;
|
||||
|
||||
@ -1892,7 +1941,6 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void a(PacketPlayInTransaction packetplayintransaction) {
|
||||
@ -2016,7 +2064,13 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
|
||||
try { // CraftBukkit
|
||||
if ("MC|BEdit".equals(packetplayincustompayload.a())) {
|
||||
if (!PaperSpigotConfig.enableBookDeserialization) return; // KigPaper
|
||||
packetdataserializer = new PacketDataSerializer(Unpooled.wrappedBuffer(packetplayincustompayload.b()));
|
||||
if (this.lastBookTick + 20 > MinecraftServer.currentTick) {
|
||||
this.disconnect("Book edited too quickly! (Attempted server crash?)");
|
||||
return;
|
||||
}
|
||||
this.lastBookTick = MinecraftServer.currentTick;
|
||||
|
||||
try {
|
||||
itemstack = packetdataserializer.i();
|
||||
@ -2048,6 +2102,12 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
|
||||
return;
|
||||
} else if ("MC|BSign".equals(packetplayincustompayload.a())) {
|
||||
if (!PaperSpigotConfig.enableBookDeserialization) return; // KigPaper
|
||||
if (this.lastBookTick + 20 > MinecraftServer.currentTick) {
|
||||
this.disconnect("Book edited too quickly! (Attempted server crash?)");
|
||||
return;
|
||||
}
|
||||
this.lastBookTick = MinecraftServer.currentTick;
|
||||
packetdataserializer = new PacketDataSerializer(Unpooled.wrappedBuffer(packetplayincustompayload.b()));
|
||||
|
||||
try {
|
||||
|
@ -28,6 +28,7 @@ import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.TravelAgent;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
@ -38,6 +39,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.github.paperspigot.PaperSpigotConfig;
|
||||
import org.spigotmc.event.player.PlayerSpawnLocationEvent;
|
||||
// CraftBukkit end
|
||||
|
||||
@ -88,11 +90,12 @@ public abstract class PlayerList {
|
||||
|
||||
public void a(NetworkManager networkmanager, EntityPlayer entityplayer) {
|
||||
GameProfile gameprofile = entityplayer.getProfile();
|
||||
boolean loadUserCache = PaperSpigotConfig.savePlayerFiles;
|
||||
UserCache usercache = this.server.getUserCache();
|
||||
GameProfile gameprofile1 = usercache.a(gameprofile.getId());
|
||||
GameProfile gameprofile1 = loadUserCache ? usercache.a(gameprofile.getId()) : null; // KigPaper - only load if savePlayerFiles is enabled
|
||||
String s = gameprofile1 == null ? gameprofile.getName() : gameprofile1.getName();
|
||||
|
||||
usercache.a(gameprofile);
|
||||
if (loadUserCache) usercache.a(gameprofile); // KigPaper - only save if savePlayerFiles is enabled
|
||||
NBTTagCompound nbttagcompound = this.a(entityplayer);
|
||||
// CraftBukkit start - Better rename detection
|
||||
if (nbttagcompound != null && nbttagcompound.hasKey("bukkit")) {
|
||||
@ -272,7 +275,7 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
worldserver1.getPlayerChunkMap().addPlayer(entityplayer);
|
||||
worldserver1.chunkProviderServer.getChunkAt((int) entityplayer.locX >> 4, (int) entityplayer.locZ >> 4);
|
||||
worldserver1.chunkProviderServer.getChunkAt(MathHelper.floor(entityplayer.locX) >> 4, MathHelper.floor(entityplayer.locZ) >> 4); // Migot - fix rounding error
|
||||
}
|
||||
|
||||
public int d() {
|
||||
@ -295,6 +298,7 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
protected void savePlayerFile(EntityPlayer entityplayer) {
|
||||
if (!PaperSpigotConfig.savePlayerFiles) return; // KigPaper
|
||||
this.playerFileData.save(entityplayer);
|
||||
ServerStatisticManager serverstatisticmanager = (ServerStatisticManager) this.o.get(entityplayer.getUniqueID());
|
||||
|
||||
@ -362,7 +366,8 @@ public abstract class PlayerList {
|
||||
// CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleInventoryCloseEvent(entityplayer);
|
||||
|
||||
PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), "\u00A7e" + entityplayer.getName() + " left the game.");
|
||||
Player bukkit = cserver.getPlayer(entityplayer); // KigPaper
|
||||
PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(bukkit, "\u00A7e" + entityplayer.getName() + " left the game.");
|
||||
cserver.getPluginManager().callEvent(playerQuitEvent);
|
||||
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
|
||||
// CraftBukkit end
|
||||
@ -405,6 +410,12 @@ public abstract class PlayerList {
|
||||
|
||||
ChunkIOExecutor.adjustPoolSize(this.getPlayerCount()); // CraftBukkit
|
||||
|
||||
// KigPaper start - fix memory leak
|
||||
CraftingManager craftingManager = CraftingManager.getInstance();
|
||||
CraftInventoryView lastView = (CraftInventoryView) craftingManager.lastCraftView;
|
||||
if (lastView != null && lastView.getHandle() instanceof ContainerPlayer && lastView.getPlayer() == bukkit) craftingManager.lastCraftView = null;
|
||||
// KigPaper end
|
||||
|
||||
return playerQuitEvent.getQuitMessage(); // CraftBukkit
|
||||
}
|
||||
|
||||
@ -599,7 +610,7 @@ public abstract class PlayerList {
|
||||
entityplayer1.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
// CraftBukkit end
|
||||
|
||||
worldserver.chunkProviderServer.getChunkAt((int) entityplayer1.locX >> 4, (int) entityplayer1.locZ >> 4);
|
||||
worldserver.chunkProviderServer.getChunkAt(MathHelper.floor(entityplayer1.locX) >> 4, MathHelper.floor(entityplayer1.locZ) >> 4); // Migot - fix rounding error
|
||||
|
||||
// eSpigot - Don't check for entities
|
||||
while (avoidSuffocation && !worldserver.getCubesNoEntities(entityplayer1, entityplayer1.getBoundingBox()).isEmpty() && entityplayer1.locY < 256.0D) {
|
||||
@ -1060,7 +1071,7 @@ public abstract class PlayerList {
|
||||
EntityPlayer entityplayer = (EntityPlayer) this.players.get(j);
|
||||
|
||||
// CraftBukkit start - Test if player receiving packet can see the source of the packet
|
||||
if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) {
|
||||
if (entityhuman != null && entityplayer != entityhuman && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) {
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
@ -1078,6 +1089,31 @@ public abstract class PlayerList {
|
||||
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
public void sendPacketNearbyIncludingSelf(EntityHuman entityhuman, double d0, double d1, double d2, double d3, int i, Packet packet) {
|
||||
for (int j = 0; j < this.players.size(); ++j) {
|
||||
EntityPlayer entityplayer = (EntityPlayer) this.players.get(j);
|
||||
|
||||
// CraftBukkit start - Test if player receiving packet can see the source of the packet
|
||||
if (entityhuman != null && entityplayer != entityhuman && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) {
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
if (entityplayer.dimension == i) {
|
||||
double d4 = d0 - entityplayer.locX;
|
||||
double d5 = d1 - entityplayer.locY;
|
||||
double d6 = d2 - entityplayer.locZ;
|
||||
|
||||
if (d4 * d4 + d5 * d5 + d6 * d6 < d3 * d3) {
|
||||
entityplayer.playerConnection.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// KigPaper end
|
||||
|
||||
public void savePlayers() {
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
this.savePlayerFile((EntityPlayer) this.players.get(i));
|
||||
|
@ -94,7 +94,13 @@ public class PortalTravelAgent {
|
||||
|
||||
public boolean b(Entity entity, float f) {
|
||||
// CraftBukkit start - Modularize portal search process and entity teleportation
|
||||
BlockPosition found = this.findPortal(entity.locX, entity.locY, entity.locZ, 128);
|
||||
// Migot start
|
||||
BlockPosition found = this.findPortal(entity.locX, entity.locY, entity.locZ, 10);
|
||||
if (found == null) {
|
||||
found = this.findPortal(entity.locX, entity.locY, entity.locZ, 128);
|
||||
}
|
||||
// Migot end
|
||||
|
||||
if (found == null) {
|
||||
return false;
|
||||
}
|
||||
@ -132,28 +138,33 @@ public class PortalTravelAgent {
|
||||
flag1 = false;
|
||||
} else {
|
||||
BlockPosition blockposition = new BlockPosition(x, y, z);
|
||||
// Migot start
|
||||
BlockPosition.MutableBlockPosition mutableblockposition = new BlockPosition.MutableBlockPosition();
|
||||
|
||||
for (int l = -searchRadius; l <= searchRadius; ++l) { // Paper - actually use search radius
|
||||
BlockPosition blockposition1;
|
||||
|
||||
for (int i1 = -searchRadius; i1 <= searchRadius; ++i1) { // Paper - actually use search radius
|
||||
for (BlockPosition blockposition2 = blockposition.a(l, this.a.V() - 1 - blockposition.getY(), i1); blockposition2.getY() >= 0; blockposition2 = blockposition1) {
|
||||
blockposition1 = blockposition2.down();
|
||||
if (this.a.getType(blockposition2).getBlock() == Blocks.PORTAL) {
|
||||
while (this.a.getType(blockposition1 = blockposition2.down()).getBlock() == Blocks.PORTAL) {
|
||||
blockposition2 = blockposition1;
|
||||
int zOffset = 0, yOffset = 0;
|
||||
for (int xDiff = -searchRadius; xDiff <= searchRadius; ++xDiff) {
|
||||
zOffset = (zOffset + 1) % 2;
|
||||
for (int zDiff = -searchRadius + zOffset; zDiff <= searchRadius; zDiff = zDiff + 2) { // skipping every 2nd block in z direction and alternating from row to row in x direction
|
||||
yOffset = (yOffset + 1) % 3;
|
||||
for (int yPos = this.a.V() - (1 + yOffset) ; yPos >= 0; yPos = yPos - 3) { // checking only every 3rd block in y direction and alternating in height in each column
|
||||
mutableblockposition.c(blockposition.getX() + xDiff, yPos, blockposition.getZ() + zDiff);
|
||||
if (this.a.getType(mutableblockposition).getBlock() == Blocks.PORTAL) {
|
||||
int lowestCorrectHeight = mutableblockposition.getY();
|
||||
while (this.a.getType(mutableblockposition.c(mutableblockposition.getX(), mutableblockposition.getY() - 1, mutableblockposition.getZ())).getBlock() == Blocks.PORTAL) {
|
||||
lowestCorrectHeight = mutableblockposition.getY();
|
||||
}
|
||||
|
||||
double d1 = blockposition2.i(blockposition);
|
||||
double d1 = mutableblockposition.c(mutableblockposition.getX(), lowestCorrectHeight, mutableblockposition.getZ()).i(blockposition);
|
||||
|
||||
if (d0 < 0.0D || d1 < d0) {
|
||||
d0 = d1;
|
||||
object = blockposition2;
|
||||
object = new BlockPosition(mutableblockposition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Migot end
|
||||
}
|
||||
|
||||
if (d0 >= 0.0D) {
|
||||
|
@ -1,20 +1,24 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import com.github.luben.zstd.ZstdInputStreamNoFinalizer;
|
||||
import com.github.luben.zstd.ZstdOutputStreamNoFinalizer;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
import net.jpountz.lz4.LZ4Factory;
|
||||
import org.github.paperspigot.PaperSpigotConfig;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.List;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
public class RegionFile {
|
||||
private static final LZ4Factory lz4Factory = LZ4Factory.fastestJavaInstance(); // KigPaper
|
||||
|
||||
private static final byte[] a = new byte[4096]; // Spigot - note: if this ever changes to not be 4096 bytes, update constructor! // PAIL: empty 4k block
|
||||
private final File b;
|
||||
@ -25,6 +29,18 @@ public class RegionFile {
|
||||
private int g;
|
||||
private long h;
|
||||
|
||||
// Migot start
|
||||
private boolean[] existingChunkCache = new boolean[1024];
|
||||
|
||||
private boolean checkExistingChunkCache(int i, int j) {
|
||||
return this.existingChunkCache[i + j * 32];
|
||||
}
|
||||
|
||||
private void addCoordinatesToCache(int i, int j) {
|
||||
this.existingChunkCache[i + j * 32] = true;
|
||||
}
|
||||
// Migot end
|
||||
|
||||
public RegionFile(File file) {
|
||||
this.b = file;
|
||||
this.g = 0;
|
||||
@ -66,8 +82,18 @@ public class RegionFile {
|
||||
|
||||
int k;
|
||||
|
||||
// KigPaper start - Paper-0098
|
||||
ByteBuffer header = ByteBuffer.allocate(8192);
|
||||
while (header.hasRemaining()) {
|
||||
if (this.c.getChannel().read(header) == -1) throw new EOFException();
|
||||
}
|
||||
header.clear();
|
||||
IntBuffer headerAsInts = header.asIntBuffer();
|
||||
// KigPaper end
|
||||
|
||||
for (j = 0; j < 1024; ++j) {
|
||||
k = this.c.readInt();
|
||||
//k = this.c.readInt(); // KigPaper
|
||||
k = headerAsInts.get();
|
||||
this.d[j] = k;
|
||||
if (k != 0 && (k >> 8) + (k & 255) <= this.f.size()) {
|
||||
for (int l = 0; l < (k & 255); ++l) {
|
||||
@ -77,7 +103,8 @@ public class RegionFile {
|
||||
}
|
||||
|
||||
for (j = 0; j < 1024; ++j) {
|
||||
k = this.c.readInt();
|
||||
//k = this.c.readInt(); // KigPaper
|
||||
k = headerAsInts.get();
|
||||
this.e[j] = k;
|
||||
}
|
||||
} catch (IOException ioexception) {
|
||||
@ -91,6 +118,11 @@ public class RegionFile {
|
||||
if (this.d(i, j)) {
|
||||
return false;
|
||||
} else {
|
||||
// Migot start
|
||||
if(checkExistingChunkCache(i, j)) {
|
||||
return true;
|
||||
}
|
||||
// Migot end
|
||||
try {
|
||||
int k = this.e(i, j);
|
||||
|
||||
@ -113,6 +145,7 @@ public class RegionFile {
|
||||
|
||||
byte b0 = this.c.readByte();
|
||||
if (b0 == 1 || b0 == 2) {
|
||||
this.addCoordinatesToCache(i, j); // Migot
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -152,15 +185,34 @@ public class RegionFile {
|
||||
byte b0 = this.c.readByte();
|
||||
byte[] abyte;
|
||||
|
||||
if (b0 == 1) {
|
||||
// KigPaper - add additional compression algorithms, and remove usage of BufferedInputStreams (as they're buffering a byte array)
|
||||
if (b0 == CompressionAlgorithm.NONE.ordinal()) {
|
||||
// KigPaper start - add no decompression
|
||||
abyte = new byte[j1 - 1];
|
||||
this.c.read(abyte);
|
||||
return new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte))));
|
||||
} else if (b0 == 2) {
|
||||
return new DataInputStream(new ByteArrayInputStream(abyte));
|
||||
// KigPaper end
|
||||
} else if (b0 == CompressionAlgorithm.GZIP.ordinal()) {
|
||||
abyte = new byte[j1 - 1];
|
||||
this.c.read(abyte);
|
||||
return new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte))));
|
||||
} else {
|
||||
return new DataInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte)));
|
||||
} else if (b0 == CompressionAlgorithm.ZLIB.ordinal()) {
|
||||
abyte = new byte[j1 - 1];
|
||||
this.c.read(abyte);
|
||||
return new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte)));
|
||||
} else if (b0 == CompressionAlgorithm.LZ4.ordinal()) {
|
||||
// KigPaper start - add LZ4 decompression
|
||||
abyte = new byte[j1 - 1];
|
||||
this.c.read(abyte);
|
||||
|
||||
return new DataInputStream(new LZ4BlockInputStream(new ByteArrayInputStream(abyte), lz4Factory.fastDecompressor()));
|
||||
// KigPaper end
|
||||
} else if (b0 == CompressionAlgorithm.ZSTD.ordinal()) {
|
||||
// KigPaper start - add Zstandard decompression
|
||||
abyte = new byte[j1 - 1];
|
||||
this.c.read(abyte);
|
||||
return new DataInputStream(new ZstdInputStreamNoFinalizer(new ByteArrayInputStream(abyte)));
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -172,9 +224,35 @@ public class RegionFile {
|
||||
}
|
||||
}
|
||||
|
||||
public DataOutputStream b(int i, int j) { // PAIL: getChunkOutputStream
|
||||
public DataOutputStream b(int i, int j) throws IOException { // PAIL: getChunkOutputStream // KigPaper - add throws
|
||||
// PAIL: isInvalidRegion
|
||||
return this.d(i, j) ? null : new DataOutputStream(new java.io.BufferedOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(i, j)))); // Spigot - use a BufferedOutputStream to greatly improve file write performance
|
||||
if (this.d(i, j)) {
|
||||
return null;
|
||||
}
|
||||
// KigPaper start - add alternative compression algorithms
|
||||
ChunkBuffer buffer = new RegionFile.ChunkBuffer(i, j);
|
||||
OutputStream stream;
|
||||
switch (PaperSpigotConfig.regionCompressionAlgorithm) {
|
||||
case NONE:
|
||||
stream = buffer;
|
||||
break;
|
||||
case GZIP:
|
||||
stream = new GZIPOutputStream(buffer); // Normally not supported by the Notchian server
|
||||
break;
|
||||
case ZLIB:
|
||||
stream = new DeflaterOutputStream(buffer);
|
||||
break;
|
||||
case LZ4:
|
||||
stream = new LZ4BlockOutputStream(buffer, 65536, lz4Factory.fastCompressor());
|
||||
break;
|
||||
case ZSTD:
|
||||
stream = new ZstdOutputStreamNoFinalizer(buffer);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedEncodingException("invalid compression algorithm");
|
||||
}
|
||||
return new DataOutputStream(new BufferedOutputStream(stream));
|
||||
// KigPaper end
|
||||
}
|
||||
|
||||
protected synchronized void a(int i, int j, byte[] abyte, int k) {
|
||||
@ -252,9 +330,9 @@ public class RegionFile {
|
||||
}
|
||||
|
||||
private void a(int i, byte[] abyte, int j) throws IOException {
|
||||
this.c.seek((long) (i * 4096));
|
||||
this.c.seek(i * 4096L);
|
||||
this.c.writeInt(j + 1);
|
||||
this.c.writeByte(2);
|
||||
this.c.writeByte(PaperSpigotConfig.regionCompressionAlgorithm.ordinal());
|
||||
this.c.write(abyte, 0, j);
|
||||
}
|
||||
|
||||
@ -304,4 +382,14 @@ public class RegionFile {
|
||||
RegionFile.this.a(this.b, this.c, this.buf, this.count);
|
||||
}
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
public enum CompressionAlgorithm {
|
||||
NONE,
|
||||
GZIP,
|
||||
ZLIB,
|
||||
LZ4, // KigPaper
|
||||
ZSTD // KigPaper
|
||||
}
|
||||
// KigPaper end
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ public class RegionFileCache {
|
||||
return regionfile.a(i & 31, j & 31);
|
||||
}
|
||||
|
||||
public static DataOutputStream d(File file, int i, int j) {
|
||||
public static DataOutputStream d(File file, int i, int j) throws IOException { // KigPaper - add throws
|
||||
RegionFile regionfile = a(file, i, j);
|
||||
|
||||
return regionfile.b(i & 31, j & 31);
|
||||
|
@ -27,6 +27,7 @@ import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.github.paperspigot.PaperSpigotConfig;
|
||||
|
||||
public class ServerConnection {
|
||||
|
||||
@ -68,6 +69,16 @@ public class ServerConnection {
|
||||
this.d = true;
|
||||
}
|
||||
|
||||
// KigPaper start - Paper-0117 by Aikar
|
||||
private final List<NetworkManager> pending = Collections.synchronizedList(Lists.newArrayList());
|
||||
private void addPending() {
|
||||
synchronized (pending) {
|
||||
this.h.addAll(pending);
|
||||
pending.clear();
|
||||
}
|
||||
}
|
||||
// KigPaper end
|
||||
|
||||
public void a(InetAddress inetaddress, int i) throws IOException {
|
||||
List list = this.g;
|
||||
|
||||
@ -98,10 +109,14 @@ public class ServerConnection {
|
||||
;
|
||||
}
|
||||
|
||||
channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyPingHandler(ServerConnection.this)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder(EnumProtocolDirection.SERVERBOUND)).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder(EnumProtocolDirection.CLIENTBOUND));
|
||||
// KigPaper start
|
||||
if(PaperSpigotConfig.nettyReadTimeout) channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30));
|
||||
// KigPaper end
|
||||
channel.pipeline().addLast("legacy_query", new LegacyPingHandler(ServerConnection.this)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder(EnumProtocolDirection.SERVERBOUND)).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder(EnumProtocolDirection.CLIENTBOUND));
|
||||
NetworkManager networkmanager = new NetworkManager(EnumProtocolDirection.SERVERBOUND);
|
||||
|
||||
ServerConnection.this.h.add(networkmanager);
|
||||
//ServerConnection.this.h.add(networkmanager);
|
||||
pending.add(networkmanager); // KigPaper
|
||||
channel.pipeline().addLast("packet_handler", networkmanager);
|
||||
networkmanager.a((PacketListener) (new HandshakeListener(ServerConnection.this.f, networkmanager)));
|
||||
}
|
||||
@ -138,6 +153,7 @@ public class ServerConnection {
|
||||
|
||||
synchronized (this.h) {
|
||||
// Spigot Start
|
||||
addPending(); // KigPaper
|
||||
// This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order
|
||||
if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % org.spigotmc.SpigotConfig.playerShuffle == 0 )
|
||||
{
|
||||
|
@ -81,7 +81,7 @@ public final class SpawnerCreature {
|
||||
long chunkCoords = LongHash.toLong(i1 + l, k + j);
|
||||
if (!this.b.contains(chunkCoords)) {
|
||||
++i;
|
||||
if (!flag3 && worldserver.getWorldBorder().isInBounds(i1 + l, k + j)) {
|
||||
if (!flag3 && worldserver.isChunkLoaded(i1 + l, k + j, true) && worldserver.getWorldBorder().isInBounds(i1 + l, k + j)) { // Migot
|
||||
this.b.add(chunkCoords);
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ public abstract class StructureGenerator extends WorldGenBase {
|
||||
private void a(World world) {
|
||||
if (this.d == null) {
|
||||
// Spigot Start
|
||||
if ( world.spigotConfig.saveStructureInfo && !this.a().equals( "Mineshaft" ) )
|
||||
if ( world.spigotConfig.saveStructureInfo && ( !this.a().equals( "Mineshaft" ) || world.spigotConfig.saveMineshaftStructureInfo ) ) // Migot
|
||||
{
|
||||
this.d = (PersistentStructure) world.a(PersistentStructure.class, this.a());
|
||||
} else
|
||||
|
@ -4,6 +4,7 @@ package net.minecraft.server;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.util.LongHash;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.FurnaceBurnEvent;
|
||||
import org.bukkit.event.inventory.FurnaceSmeltEvent;
|
||||
@ -206,7 +207,7 @@ public class TileEntityFurnace extends TileEntityContainer implements IUpdatePla
|
||||
if (!this.isBurning() && this.cookTime > 0) {
|
||||
this.cookTime = MathHelper.clamp(this.cookTime - 2, 0, this.cookTimeTotal);
|
||||
}
|
||||
} else {
|
||||
} else if (this.items[1] != null && this.items[1].getItem() != Items.BUCKET) { // Migot
|
||||
// CraftBukkit start - Handle multiple elapsed ticks
|
||||
if (this.burnTime <= 0 && this.canBurn()) { // CraftBukkit - == to <=
|
||||
CraftItemStack fuel = CraftItemStack.asCraftMirror(this.items[1]);
|
||||
@ -271,6 +272,7 @@ public class TileEntityFurnace extends TileEntityContainer implements IUpdatePla
|
||||
return false;
|
||||
} else {
|
||||
ItemStack itemstack = RecipesFurnace.getInstance().getResult(this.items[0]);
|
||||
if(!this.world.isLoaded(this.position) || ((WorldServer) this.world).chunkProviderServer.unloadQueue.contains(LongHash.toLong(this.position.getX() >> 4, this.position.getZ() >> 4))) { return false; } // Migot
|
||||
|
||||
// CraftBukkit - consider resultant count instead of current count
|
||||
return itemstack == null ? false : (this.items[2] == null ? true : (!this.items[2].doMaterialsMatch(itemstack) ? false : (this.items[2].count + itemstack.count <= this.getMaxStackSize() && this.items[2].count < this.items[2].getMaxStackSize() ? true : this.items[2].count + itemstack.count <= itemstack.getMaxStackSize())));
|
||||
|
@ -41,7 +41,33 @@ public class Village {
|
||||
this.a = world;
|
||||
}
|
||||
|
||||
// Migot start
|
||||
private BlockPosition[] positions = null;
|
||||
|
||||
private void calculateNewCheckPositions() {
|
||||
if(this.d == null || this.d.equals(BlockPosition.ZERO)) {
|
||||
this.positions = null;
|
||||
} else {
|
||||
this.positions = new BlockPosition[] { this.d.a(-this.e, 0, -this.e),
|
||||
this.d.a(-this.e, 0, this.e),
|
||||
this.d.a(this.e, 0, -this.e),
|
||||
this.d.a(this.e, 0, this.e),
|
||||
this.d};
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVillageAreaLoaded() {
|
||||
for(int i = 0; this.positions != null && i < this.positions.length; i++) {
|
||||
if(this.a.isLoaded(this.positions[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Migot end
|
||||
|
||||
public void a(int i) {
|
||||
if(!this.isVillageAreaLoaded()) { return; } // Migot
|
||||
this.g = i;
|
||||
this.m();
|
||||
this.l();
|
||||
@ -402,6 +428,7 @@ public class Village {
|
||||
}
|
||||
}
|
||||
|
||||
this.calculateNewCheckPositions(); // Migot
|
||||
}
|
||||
|
||||
public void b(NBTTagCompound nbttagcompound) {
|
||||
|
@ -170,6 +170,28 @@ public abstract class World implements IBlockAccess {
|
||||
public final co.aikar.timings.WorldTimingsHandler timings; // Spigot
|
||||
public final net.techcable.tacospigot.TacoSpigotWorldConfig tacoSpigotConfig;
|
||||
|
||||
// Migot start
|
||||
private Chunk dummyChunk = new EmptyChunk(this, Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||
private Chunk lastChunkAccessed = dummyChunk;
|
||||
final Object chunkLock = new Object();
|
||||
public ChunkProviderServer chunkProviderServer; // moved here from WorldServer
|
||||
protected boolean cancelHeavyCalculations = false;
|
||||
private List<Entity> dimensionChangeQueue = java.util.Collections.synchronizedList(new ArrayList<Entity>());
|
||||
|
||||
public void queueEntityForDimensionChange(Entity entity) {
|
||||
this.dimensionChangeQueue.add(entity);
|
||||
}
|
||||
|
||||
public void processDimensionChangeQueue() {
|
||||
Iterator<Entity> iter = this.dimensionChangeQueue.iterator();
|
||||
while(iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
entity.changeDimension(entity.getTargetDimension());
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
// Migot end
|
||||
|
||||
public CraftWorld getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
@ -362,8 +384,30 @@ public abstract class World implements IBlockAccess {
|
||||
return this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4);
|
||||
}
|
||||
|
||||
// Migot start
|
||||
private void cacheLastChunkAccess(Chunk foundChunk) {
|
||||
this.lastChunkAccessed = ((foundChunk == null || foundChunk.isEmpty() || foundChunk.wasUnloaded()) ? this.dummyChunk : foundChunk);
|
||||
}
|
||||
// Migot end
|
||||
|
||||
public Chunk getChunkAt(int i, int j) {
|
||||
return this.chunkProvider.getOrCreateChunk(i, j);
|
||||
// Migot start
|
||||
Chunk last = this.lastChunkAccessed;
|
||||
if(last.a(i,j) && !last.wasUnloaded()) {
|
||||
return last;
|
||||
} else {
|
||||
Chunk result = null;
|
||||
if(this.chunkProviderServer.isChunkLoaded(i, j)) {
|
||||
result = this.chunkProviderServer.getChunkAt(i, j);
|
||||
} else {
|
||||
synchronized (this.chunkLock) {
|
||||
result = this.chunkProvider.getOrCreateChunk(i, j);
|
||||
}
|
||||
}
|
||||
this.cacheLastChunkAccess(result);
|
||||
return result;
|
||||
}
|
||||
// Migot end
|
||||
}
|
||||
|
||||
public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) {
|
||||
@ -1013,7 +1057,23 @@ public abstract class World implements IBlockAccess {
|
||||
}
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
public void playSoundIncludingSelf(EntityHuman entityhuman, String s, float f, float f1) {
|
||||
for (IWorldAccess worldAccess : this.u) {
|
||||
if (worldAccess instanceof WorldManager) {
|
||||
((WorldManager) worldAccess).broadcastPacketIncludingSelf(entityhuman, s, entityhuman.locX, entityhuman.locY, entityhuman.locZ, f, f1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// KigPaper end
|
||||
|
||||
public void makeSound(Entity entity, String s, float f, float f1) {
|
||||
// KigPaper start - respect visibility for players
|
||||
if (entity instanceof EntityHuman) {
|
||||
this.playSoundIncludingSelf((EntityHuman) entity, s, f, f1);
|
||||
return;
|
||||
}
|
||||
// KigPaper end
|
||||
for (int i = 0; i < this.u.size(); ++i) {
|
||||
((IWorldAccess) this.u.get(i)).a(s, entity.locX, entity.locY, entity.locZ, f, f1);
|
||||
}
|
||||
|
@ -33,6 +33,13 @@ public class WorldManager implements IWorldAccess {
|
||||
this.a.getPlayerList().sendPacketNearby(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.dimension, new PacketPlayOutNamedSoundEffect(s, d0, d1, d2, f, f1));
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
public void broadcastPacketIncludingSelf(EntityHuman entityhuman, String s, double d0, double d1, double d2, float f, float f1) {
|
||||
// CraftBukkit - this.world.dimension
|
||||
this.a.getPlayerList().sendPacketNearbyIncludingSelf(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.dimension, new PacketPlayOutNamedSoundEffect(s, d0, d1, d2, f, f1));
|
||||
}
|
||||
// KigPaper end
|
||||
|
||||
public void a(int i, int j, int k, int l, int i1, int j1) {}
|
||||
|
||||
public void a(BlockPosition blockposition) {
|
||||
|
@ -15,6 +15,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.github.paperspigot.PaperSpigotConfig;
|
||||
// CraftBukkit end
|
||||
|
||||
public class WorldNBTStorage implements IDataManager, IPlayerFileData {
|
||||
@ -196,13 +197,15 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData {
|
||||
}
|
||||
|
||||
public NBTTagCompound load(EntityHuman entityhuman) {
|
||||
if (!PaperSpigotConfig.savePlayerFiles) return null; // KigPaper
|
||||
NBTTagCompound nbttagcompound = null;
|
||||
|
||||
try {
|
||||
File file = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat");
|
||||
// Spigot Start
|
||||
boolean usingWrongFile = false;
|
||||
if ( org.bukkit.Bukkit.getOnlineMode() && !file.exists() ) // PaperSpigot - Check online mode first
|
||||
boolean normalFile = file.exists() && file.isFile(); // KigPaper
|
||||
if ( org.bukkit.Bukkit.getOnlineMode() && !normalFile ) // PaperSpigot - Check online mode first
|
||||
{
|
||||
file = new File( this.playerDir, UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + entityhuman.getName() ).getBytes( "UTF-8" ) ).toString() + ".dat");
|
||||
if ( file.exists() )
|
||||
@ -213,7 +216,7 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData {
|
||||
}
|
||||
// Spigot End
|
||||
|
||||
if (file.exists() && file.isFile()) {
|
||||
if (normalFile) { // KigPaper
|
||||
nbttagcompound = NBTCompressedStreamTools.a((InputStream) (new FileInputStream(file)));
|
||||
}
|
||||
// Spigot Start
|
||||
|
@ -36,7 +36,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||
private final PlayerChunkMap manager;
|
||||
private final HashTreeSet<NextTickListEntry> M = new HashTreeSet<>(); // CraftBukkit - HashTreeSet // PAIL: Rename nextTickList
|
||||
private final Map<UUID, Entity> entitiesByUUID = Maps.newHashMap();
|
||||
public ChunkProviderServer chunkProviderServer;
|
||||
//public ChunkProviderServer chunkProviderServer; // Migot - moved to World
|
||||
public boolean savingDisabled;
|
||||
private boolean O;
|
||||
private int emptyTime;
|
||||
@ -48,6 +48,12 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||
private static final List<StructurePieceTreasure> U = Lists.newArrayList(new StructurePieceTreasure[] { new StructurePieceTreasure(Items.STICK, 0, 1, 3, 10), new StructurePieceTreasure(Item.getItemOf(Blocks.PLANKS), 0, 1, 3, 10), new StructurePieceTreasure(Item.getItemOf(Blocks.LOG), 0, 1, 3, 10), new StructurePieceTreasure(Items.STONE_AXE, 0, 1, 1, 3), new StructurePieceTreasure(Items.WOODEN_AXE, 0, 1, 1, 5), new StructurePieceTreasure(Items.STONE_PICKAXE, 0, 1, 1, 3), new StructurePieceTreasure(Items.WOODEN_PICKAXE, 0, 1, 1, 5), new StructurePieceTreasure(Items.APPLE, 0, 2, 3, 5), new StructurePieceTreasure(Items.BREAD, 0, 2, 3, 3), new StructurePieceTreasure(Item.getItemOf(Blocks.LOG2), 0, 1, 3, 10)});
|
||||
private List<NextTickListEntry> V = Lists.newArrayList();
|
||||
|
||||
// Migot start
|
||||
public void cancelHeavyCalculations(boolean cancel) {
|
||||
this.cancelHeavyCalculations = cancel;
|
||||
}
|
||||
// Migot end
|
||||
|
||||
// CraftBukkit start
|
||||
public final int dimension;
|
||||
|
||||
|
@ -52,13 +52,7 @@ import org.bukkit.craftbukkit.command.VanillaCommandWrapper;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.generator.CraftChunkData;
|
||||
import org.bukkit.craftbukkit.help.SimpleHelpMap;
|
||||
import org.bukkit.craftbukkit.inventory.CraftFurnaceRecipe;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryCustom;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemFactory;
|
||||
import org.bukkit.craftbukkit.inventory.CraftRecipe;
|
||||
import org.bukkit.craftbukkit.inventory.CraftShapedRecipe;
|
||||
import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe;
|
||||
import org.bukkit.craftbukkit.inventory.RecipeIterator;
|
||||
import org.bukkit.craftbukkit.inventory.*;
|
||||
import org.bukkit.craftbukkit.map.CraftMapView;
|
||||
import org.bukkit.craftbukkit.metadata.EntityMetadataStore;
|
||||
import org.bukkit.craftbukkit.metadata.PlayerMetadataStore;
|
||||
@ -103,6 +97,8 @@ import org.bukkit.plugin.messaging.StandardMessenger;
|
||||
import org.bukkit.scheduler.BukkitWorker;
|
||||
import org.bukkit.util.StringUtil;
|
||||
import org.bukkit.util.permissions.DefaultPermissions;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
import org.yaml.snakeyaml.error.MarkedYAMLException;
|
||||
@ -125,6 +121,7 @@ import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.base64.Base64;
|
||||
import jline.console.ConsoleReader;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
public final class CraftServer implements Server {
|
||||
private static final Player[] EMPTY_PLAYER_ARRAY = new Player[0];
|
||||
@ -143,7 +140,10 @@ public final class CraftServer implements Server {
|
||||
private final Map<String, World> worlds = new LinkedHashMap<String, World>();
|
||||
private YamlConfiguration configuration;
|
||||
private YamlConfiguration commandsConfiguration;
|
||||
private final Yaml yaml = new Yaml(new SafeConstructor());
|
||||
// KigPaper start - CVE-2017-18640
|
||||
private final LoaderOptions loaderOptions = new LoaderOptions();
|
||||
private final Yaml yaml = new Yaml(new SafeConstructor(), new Representer(), new DumperOptions(), loaderOptions);
|
||||
// KigPaper end
|
||||
private final Map<UUID, OfflinePlayer> offlinePlayers = new MapMaker().softValues().makeMap();
|
||||
private final EntityMetadataStore entityMetadata = new EntityMetadataStore();
|
||||
private final PlayerMetadataStore playerMetadata = new PlayerMetadataStore();
|
||||
@ -178,6 +178,7 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
|
||||
public CraftServer(MinecraftServer console, PlayerList playerList) {
|
||||
loaderOptions.setMaxAliasesForCollections(32); // KigPaper - CVE-2017-18640
|
||||
this.console = console;
|
||||
this.playerList = (DedicatedPlayerList) playerList;
|
||||
this.playerView = Collections.unmodifiableList(Lists.transform(playerList.players, new Function<EntityPlayer, CraftPlayer>() {
|
||||
@ -1005,11 +1006,32 @@ public final class CraftServer implements Server {
|
||||
} catch (ExceptionWorldConflict ex) {
|
||||
getLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
} else { // KigPaper start
|
||||
ChunkProviderServer cps = handle.chunkProviderServer;
|
||||
ChunkRegionLoader loader = (ChunkRegionLoader) cps.chunkLoader;
|
||||
loader.b.clear();
|
||||
loader.c.clear();
|
||||
try {
|
||||
FileIOThread.a().b();
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
cps.chunkLoader = null;
|
||||
cps.chunkProvider = null;
|
||||
cps.chunks.clear();
|
||||
// KigPaper end
|
||||
}
|
||||
|
||||
worlds.remove(world.getName().toLowerCase());
|
||||
console.worlds.remove(console.worlds.indexOf(handle));
|
||||
|
||||
// KigPaper start - fix memory leak
|
||||
CraftingManager craftingManager = CraftingManager.getInstance();
|
||||
CraftInventoryView lastView = (CraftInventoryView) craftingManager.lastCraftView;
|
||||
if (lastView != null && lastView.getHandle() instanceof ContainerWorkbench
|
||||
&& ((ContainerWorkbench) lastView.getHandle()).g == handle) craftingManager.lastCraftView = null;
|
||||
// KigPaper end
|
||||
|
||||
File parentFolder = world.getWorldFolder().getAbsoluteFile();
|
||||
|
||||
// Synchronized because access to RegionFileCache.a is guarded by this lock.
|
||||
@ -1834,4 +1856,11 @@ public final class CraftServer implements Server {
|
||||
{
|
||||
return spigot;
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
@Override
|
||||
public String getPermissionMessage() {
|
||||
return configuration.getString("settings.permission-message", ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error.");
|
||||
}
|
||||
// KigPaper end
|
||||
}
|
||||
|
@ -216,6 +216,19 @@ public class CraftSound {
|
||||
// Tile
|
||||
set(PISTON_EXTEND, "tile.piston.out");
|
||||
set(PISTON_RETRACT, "tile.piston.in");
|
||||
// KigPaper start - Guardian sounds
|
||||
set(GUARDIAN_IDLE, "mob.guardian.idle");
|
||||
set(GUARDIAN_IDLE_LAND, "mob.guardian.land.idle");
|
||||
set(GUARDIAN_IDLE_ELDER, "mob.guardian.elder.idle");
|
||||
set(GUARDIAN_HIT, "mob.guardian.hit");
|
||||
set(GUARDIAN_HIT_LAND, "mob.guardian.land.hit");
|
||||
set(GUARDIAN_HIT_ELDER, "mob.guardian.elder.hit");
|
||||
set(GUARDIAN_DEATH, "mob.guardian.death");
|
||||
set(GUARDIAN_DEATH_LAND, "mob.guardian.land.death");
|
||||
set(GUARDIAN_DEATH_ELDER, "mob.guardian.elder.death");
|
||||
set(GUARDIAN_FLOP, "mob.guardian.flop");
|
||||
set(GUARDIAN_CURSE, "mob.guardian.curse");
|
||||
// KigPaper end
|
||||
}
|
||||
|
||||
private static void set(Sound sound, String key) {
|
||||
|
@ -44,7 +44,12 @@ public class CraftTravelAgent extends PortalTravelAgent implements TravelAgent {
|
||||
@Override
|
||||
public Location findPortal(Location location) {
|
||||
PortalTravelAgent pta = ((CraftWorld) location.getWorld()).getHandle().getTravelAgent();
|
||||
BlockPosition found = pta.findPortal(location.getX(), location.getY(), location.getZ(), this.getSearchRadius());
|
||||
// Migot start
|
||||
BlockPosition found = pta.findPortal(location.getX(), location.getY(), location.getZ(), 10);
|
||||
if (found == null) {
|
||||
found = pta.findPortal(location.getX(), location.getY(), location.getZ(), this.getSearchRadius());
|
||||
}
|
||||
// Migot end
|
||||
return found != null ? new Location(location.getWorld(), found.getX(), found.getY(), found.getZ(), location.getYaw(), location.getPitch()) : null;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import com.elevatemc.spigot.util.Dictionary;
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@ -35,6 +36,7 @@ import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||
import org.bukkit.craftbukkit.entity.*;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.metadata.BlockMetadataStore;
|
||||
import org.bukkit.craftbukkit.metadata.SpecializedBlockMetadataStore;
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
import org.bukkit.craftbukkit.util.LongHash;
|
||||
import org.bukkit.entity.*;
|
||||
@ -51,6 +53,7 @@ import org.bukkit.event.world.SpawnChangeEvent;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.metadata.MetadataStore;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.messaging.StandardMessenger;
|
||||
@ -65,7 +68,10 @@ public class CraftWorld implements World {
|
||||
private final CraftServer server = (CraftServer) Bukkit.getServer();
|
||||
private final ChunkGenerator generator;
|
||||
private final List<BlockPopulator> populators = new ArrayList<BlockPopulator>();
|
||||
private final BlockMetadataStore blockMetadata = new BlockMetadataStore(this);
|
||||
// KigPaper start
|
||||
//private final BlockMetadataStore blockMetadata = new BlockMetadataStore(this);
|
||||
private final MetadataStore<Block> blockMetadata = new SpecializedBlockMetadataStore(this);
|
||||
// KigPaper end
|
||||
private int monsterSpawn = -1;
|
||||
private int animalSpawn = -1;
|
||||
private int waterAnimalSpawn = -1;
|
||||
@ -235,6 +241,7 @@ public class CraftWorld implements World {
|
||||
save = true;
|
||||
}
|
||||
|
||||
chunk.markAsUnloaded(); // Migot
|
||||
chunk.removeEntities(); // Always remove entities - even if discarding, need to get them out of world table
|
||||
|
||||
if (save && !(chunk instanceof EmptyChunk)) {
|
||||
@ -787,17 +794,12 @@ public class CraftWorld implements World {
|
||||
}
|
||||
|
||||
public void save() {
|
||||
// Spigot start
|
||||
save(true);
|
||||
}
|
||||
public void save(boolean forceSave) {
|
||||
// Spigot end
|
||||
this.server.checkSaveState();
|
||||
try {
|
||||
boolean oldSave = world.savingDisabled;
|
||||
|
||||
world.savingDisabled = false;
|
||||
world.save(forceSave, null); // Spigot
|
||||
world.save(true, null); // Spigot
|
||||
|
||||
world.savingDisabled = oldSave;
|
||||
} catch (ExceptionWorldConflict ex) {
|
||||
@ -821,7 +823,7 @@ public class CraftWorld implements World {
|
||||
return Difficulty.getByValue(this.getHandle().getDifficulty().ordinal());
|
||||
}
|
||||
|
||||
public BlockMetadataStore getBlockMetadata() {
|
||||
public MetadataStore<Block> getBlockMetadata() { // KigPaper - change type
|
||||
return blockMetadata;
|
||||
}
|
||||
|
||||
@ -1457,14 +1459,10 @@ public class CraftWorld implements World {
|
||||
{
|
||||
net.minecraft.server.EnumParticle particle = null;
|
||||
int[] extra = null;
|
||||
for ( net.minecraft.server.EnumParticle p : net.minecraft.server.EnumParticle.values() )
|
||||
{
|
||||
if ( effect.getName().startsWith( p.b().replace("_", "") ) )
|
||||
{
|
||||
particle = p;
|
||||
if ((particle = Dictionary.EFFECT_TO_PARTICLE.get(effect)) != null) {
|
||||
if ( effect.getData() != null )
|
||||
{
|
||||
if ( effect.getData().equals( org.bukkit.Material.class ) )
|
||||
if ( effect.getData().equals( Material.class ) )
|
||||
{
|
||||
extra = new int[]{ id };
|
||||
} else
|
||||
@ -1472,8 +1470,6 @@ public class CraftWorld implements World {
|
||||
extra = new int[]{ (data << 12) | (id & 0xFFF) };
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( extra == null )
|
||||
{
|
||||
|
@ -12,18 +12,19 @@ import org.bukkit.plugin.Plugin;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class ServerCommandSender implements CommandSender {
|
||||
private static PermissibleBase blockPermInst;
|
||||
//private static PermissibleBase blockPermInst; // KigPaper - fix memory leak
|
||||
private final PermissibleBase perm;
|
||||
|
||||
public ServerCommandSender() {
|
||||
if (this instanceof CraftBlockCommandSender) {
|
||||
/* if (this instanceof CraftBlockCommandSender) {
|
||||
if (blockPermInst == null) {
|
||||
blockPermInst = new PermissibleBase(this);
|
||||
}
|
||||
this.perm = blockPermInst;
|
||||
} else {
|
||||
this.perm = new PermissibleBase(this);
|
||||
}
|
||||
} */ // KigPaper
|
||||
this.perm = new PermissibleBase(this);
|
||||
}
|
||||
|
||||
public boolean isPermissionSet(String name) {
|
||||
|
@ -43,7 +43,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
|
||||
protected final CraftServer server;
|
||||
protected Entity entity;
|
||||
private EntityDamageEvent lastDamageEvent;
|
||||
//private EntityDamageEvent lastDamageEvent; // KigPaper - this is almost never used and only leads to memory leaks
|
||||
|
||||
public CraftEntity(final CraftServer server, final Entity entity) {
|
||||
this.server = server;
|
||||
@ -259,6 +259,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
// entity.world = ((CraftWorld) location.getWorld()).getHandle();
|
||||
// Spigot end
|
||||
entity.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
entity.f(location.getYaw()); // KigPaper - update head yaw to keep consistency with /tp
|
||||
entity.world.entityJoinedWorld(entity, false); // PaperSpigot - Fix issues with entities not being switched to their new chunk
|
||||
// entity.setLocation() throws no event, and so cannot be cancelled
|
||||
return true;
|
||||
@ -358,11 +359,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
}
|
||||
|
||||
public void setLastDamageCause(EntityDamageEvent event) {
|
||||
lastDamageEvent = event;
|
||||
// lastDamageEvent = event;
|
||||
}
|
||||
|
||||
public EntityDamageEvent getLastDamageCause() {
|
||||
return lastDamageEvent;
|
||||
return null;
|
||||
}
|
||||
|
||||
public UUID getUniqueId() {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.elevatemc.spigot.event.PlayerHealthChangeEvent;
|
||||
import com.elevatemc.spigot.util.Dictionary;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
@ -289,6 +290,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendActionbarMessage(BaseComponent... message) {
|
||||
if(getHandle().playerConnection == null) return;
|
||||
PacketPlayOutChat packet = new PacketPlayOutChat(null, (byte) 2);
|
||||
packet.components = message;
|
||||
getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
// KigPaper end
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof OfflinePlayer)) {
|
||||
@ -532,8 +542,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
if (entity.passenger != null) {
|
||||
// KigPaper - only cancel if not unknown
|
||||
// if a PlayerMoveEvent is cancelled using setTo and the player has a passenger, the event won't set the user back.
|
||||
if (cause != PlayerTeleportEvent.TeleportCause.UNKNOWN) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// From = Players current Location
|
||||
Location from = this.getLocation();
|
||||
@ -1244,7 +1258,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void setFlying(boolean value) {
|
||||
boolean needsUpdate = getHandle().abilities.canFly != value; // PaperSpigot - Only refresh abilities if needed
|
||||
boolean needsUpdate = getHandle().abilities.isFlying != value; // PaperSpigot - Only refresh abilities if needed
|
||||
if (!getAllowFlight() && value) {
|
||||
throw new IllegalArgumentException("Cannot make player fly if getAllowFlight() is false");
|
||||
}
|
||||
@ -1508,11 +1522,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
{
|
||||
net.minecraft.server.EnumParticle particle = null;
|
||||
int[] extra = null;
|
||||
for ( net.minecraft.server.EnumParticle p : net.minecraft.server.EnumParticle.values() )
|
||||
{
|
||||
if ( effect.getName().startsWith( p.b().replace("_", "") ) )
|
||||
{
|
||||
particle = p;
|
||||
if ((particle = Dictionary.EFFECT_TO_PARTICLE.get(effect)) != null) {
|
||||
if ( effect.getData() != null )
|
||||
{
|
||||
if ( effect.getData().equals( org.bukkit.Material.class ) )
|
||||
@ -1523,8 +1533,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
extra = new int[]{ (data << 12) | (id & 0xFFF) };
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( extra == null )
|
||||
{
|
||||
|
@ -188,7 +188,7 @@ public class CraftEventFactory {
|
||||
if (action != Action.LEFT_CLICK_AIR && action != Action.RIGHT_CLICK_AIR) {
|
||||
throw new IllegalArgumentException(String.format("%s performing %s with %s", who, action, itemstack)); // Spigot
|
||||
}
|
||||
return callPlayerInteractEvent(who, action, new BlockPosition(0, 256, 0), EnumDirection.SOUTH, itemstack);
|
||||
return callPlayerInteractEvent(who, action, /*new BlockPosition(0, 256, 0) KigPaper */ null, EnumDirection.SOUTH, itemstack);
|
||||
}
|
||||
|
||||
public static PlayerInteractEvent callPlayerInteractEvent(EntityHuman who, Action action, BlockPosition position, EnumDirection direction, ItemStack itemstack) {
|
||||
@ -202,11 +202,11 @@ public class CraftEventFactory {
|
||||
CraftWorld craftWorld = (CraftWorld) player.getWorld();
|
||||
CraftServer craftServer = (CraftServer) player.getServer();
|
||||
|
||||
Block blockClicked = craftWorld.getBlockAt(position.getX(), position.getY(), position.getZ());
|
||||
BlockFace blockFace = CraftBlock.notchToBlockFace(direction);
|
||||
|
||||
if (position.getY() > 255) {
|
||||
blockClicked = null;
|
||||
// Block blockClicked = craftWorld.getBlockAt(position.getX(), position.getY(), position.getZ()); // KigPaper
|
||||
Block blockClicked = null;
|
||||
if (position != null) {
|
||||
blockClicked = craftWorld.getBlockAt(position.getX(), position.getY(), position.getZ());
|
||||
} else {
|
||||
switch (action) {
|
||||
case LEFT_CLICK_BLOCK:
|
||||
action = Action.LEFT_CLICK_AIR;
|
||||
@ -217,6 +217,8 @@ public class CraftEventFactory {
|
||||
}
|
||||
}
|
||||
|
||||
BlockFace blockFace = CraftBlock.notchToBlockFace(direction); // KigPaper - moved down
|
||||
|
||||
if (itemInHand.getType() == Material.AIR || itemInHand.getAmount() == 0) {
|
||||
itemInHand = null;
|
||||
}
|
||||
@ -532,7 +534,8 @@ public class CraftEventFactory {
|
||||
} else if (source == DamageSource.FALL) {
|
||||
cause = DamageCause.FALL;
|
||||
} else if (source == DamageSource.GENERIC) {
|
||||
return new EntityDamageEvent(entity.getBukkitEntity(), null, modifiers, modifierFunctions);
|
||||
//return new EntityDamageEvent(entity.getBukkitEntity(), null, modifiers, modifierFunctions);
|
||||
cause = DamageCause.CUSTOM; // KigPaper
|
||||
}
|
||||
|
||||
if (cause != null) {
|
||||
|
@ -33,8 +33,10 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
|
||||
static final ItemMetaKey BOOK_PAGES = new ItemMetaKey("pages");
|
||||
static final ItemMetaKey RESOLVED = new ItemMetaKey("resolved");
|
||||
static final ItemMetaKey GENERATION = new ItemMetaKey("generation");
|
||||
static final int MAX_PAGE_LENGTH = Short.MAX_VALUE; // TODO: Check me
|
||||
static final int MAX_TITLE_LENGTH = 0xffff;
|
||||
static final int MAX_PAGES = 50;
|
||||
static final int MAX_PAGE_LENGTH = 256;
|
||||
static final int MAX_TITLE_LENGTH = 16;
|
||||
|
||||
|
||||
protected String title;
|
||||
protected String author;
|
||||
@ -61,11 +63,11 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
|
||||
super(tag);
|
||||
|
||||
if (tag.hasKey(BOOK_TITLE.NBT)) {
|
||||
this.title = limit( tag.getString(BOOK_TITLE.NBT), 1024 ); // Spigot
|
||||
this.title = limit( tag.getString(BOOK_TITLE.NBT), 32 ); // Spigot // KigPaper - tighter limits
|
||||
}
|
||||
|
||||
if (tag.hasKey(BOOK_AUTHOR.NBT)) {
|
||||
this.author = limit( tag.getString(BOOK_AUTHOR.NBT), 1024 ); // Spigot
|
||||
this.author = limit( tag.getString(BOOK_AUTHOR.NBT), 16 ); // Spigot // KigPaper - tighter limits
|
||||
}
|
||||
|
||||
boolean resolved = false;
|
||||
@ -80,6 +82,7 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
|
||||
if (tag.hasKey(BOOK_PAGES.NBT) && handlePages) {
|
||||
NBTTagList pages = tag.getList(BOOK_PAGES.NBT, 8);
|
||||
|
||||
if (pages.size() > MAX_PAGES) return; // KigPaper - limit pages
|
||||
for (int i = 0; i < pages.size(); i++) {
|
||||
String page = pages.getString(i);
|
||||
if (resolved) {
|
||||
@ -90,7 +93,7 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
|
||||
// Ignore and treat as an old book
|
||||
}
|
||||
}
|
||||
addPage( limit( page, 2048 ) ); // Spigot
|
||||
addPage( limit( page, MAX_PAGE_LENGTH ) ); // Spigot // KigPaper - tighter limits
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,13 +106,17 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
|
||||
setTitle(SerializableMeta.getString(map, BOOK_TITLE.BUKKIT, true));
|
||||
|
||||
Iterable<?> pages = SerializableMeta.getObject(Iterable.class, map, BOOK_PAGES.BUKKIT, true);
|
||||
// KigPaper start - limit pages
|
||||
if(pages != null) {
|
||||
int count = 0;
|
||||
for (Object page : pages) {
|
||||
if (count++ > MAX_PAGES) break;
|
||||
if (page instanceof String) {
|
||||
addPage((String) page);
|
||||
}
|
||||
}
|
||||
}
|
||||
// KigPaper end
|
||||
|
||||
generation = SerializableMeta.getObject(Integer.class, map, GENERATION.BUKKIT, true);
|
||||
}
|
||||
@ -225,10 +232,14 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
|
||||
|
||||
public void addPage(final String... pages) {
|
||||
for (String page : pages) {
|
||||
if (this.pages.size() >= MAX_PAGES) {
|
||||
return;
|
||||
}
|
||||
if (page == null) {
|
||||
page = "";
|
||||
} else if (page.length() > MAX_PAGE_LENGTH) {
|
||||
page = page.substring(0, MAX_PAGE_LENGTH);
|
||||
//page = page.substring(0, MAX_PAGE_LENGTH);
|
||||
return; // KigPaper
|
||||
}
|
||||
|
||||
this.pages.add(CraftChatMessage.fromString(page, true)[0]);
|
||||
|
@ -35,6 +35,7 @@ public class CraftMapRenderer extends MapRenderer {
|
||||
cursors.removeCursor(cursors.getCursor(0));
|
||||
}
|
||||
|
||||
if (getDrawCursors()) {
|
||||
for (UUID key : worldMap.decorations.keySet()) { // Spigot string -> uuid.
|
||||
// If this cursor is for a player check visibility with vanish system
|
||||
Player other = Bukkit.getPlayer(key); // Spigot
|
||||
@ -46,5 +47,6 @@ public class CraftMapRenderer extends MapRenderer {
|
||||
cursors.addCursor(decoration.getX(), decoration.getY(), (byte) (decoration.getRotation() & 15), decoration.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,175 @@
|
||||
package org.bukkit.craftbukkit.metadata;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.metadata.MetadataStore;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An alternative to {@link BlockMetadataStore} that uses specialized collections and bit-packing for faster
|
||||
* operations and a lower memory footprint.
|
||||
*
|
||||
* <p>This can be a drop-in replacement, though keep in mind methods will throw an {@link IllegalArgumentException}
|
||||
* if invalid block coordinates are provided.
|
||||
*/
|
||||
public class SpecializedBlockMetadataStore implements MetadataStore<Block> {
|
||||
// Allows storing 25 bits (up to 33,554,432 - MC supports up to 30,000,000) sign
|
||||
private static final int MASK_26_BITS = 0b111_111_111_111_111_111_111_111_11;
|
||||
|
||||
private final Map<StoreKey, Map<Plugin, MetadataValue>> metadata = new HashMap<>();
|
||||
private final World owningWorld;
|
||||
|
||||
// Cached key used for (synchronized) lookups, saves allocations.
|
||||
// The key stored inside is usually cleared after use, so that the reference doesn't live too long.
|
||||
private final StoreKey cachedKey = new StoreKey(null, 0);
|
||||
|
||||
public SpecializedBlockMetadataStore(World owningWorld) {
|
||||
this.owningWorld = owningWorld;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<MetadataValue> getMetadata(Block block, String metadataKey) {
|
||||
Preconditions.checkArgument(block.getWorld() == owningWorld, "block is from another world");
|
||||
|
||||
List<MetadataValue> list = Collections.emptyList();
|
||||
Map<Plugin, MetadataValue> pluginMetadata = getEntry(metadataKey, block);
|
||||
if (pluginMetadata == null) {
|
||||
return list;
|
||||
}
|
||||
list = ImmutableList.copyOf(pluginMetadata.values());
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean hasMetadata(Block block, String metadataKey) {
|
||||
Preconditions.checkArgument(block.getWorld() == owningWorld, "block is from another world");
|
||||
Map<Plugin, MetadataValue> pluginMetadata = getEntry(metadataKey, block);
|
||||
return pluginMetadata != null && !pluginMetadata.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeMetadata(Block block, String metadataKey, Plugin owningPlugin) {
|
||||
Preconditions.checkArgument(block.getWorld() == owningWorld, "block is from another world");
|
||||
Preconditions.checkNotNull(owningPlugin, "plugin is null");
|
||||
|
||||
long id = getBlockId(block);
|
||||
Map<Plugin, MetadataValue> pluginMetadata = getEntry(metadataKey, id);
|
||||
if (pluginMetadata == null) {
|
||||
return;
|
||||
}
|
||||
// Clear empty entries
|
||||
if (pluginMetadata.remove(owningPlugin) != null && pluginMetadata.isEmpty()) {
|
||||
StoreKey key = getCachedKey(metadataKey, id);
|
||||
this.metadata.remove(key);
|
||||
key.metadataKey = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setMetadata(Block block, String metadataKey, MetadataValue newMetadataValue) {
|
||||
Preconditions.checkArgument(block.getWorld() == owningWorld, "block is from another world");
|
||||
Preconditions.checkNotNull(newMetadataValue, "value is null");
|
||||
Plugin owningPlugin = newMetadataValue.getOwningPlugin();
|
||||
Preconditions.checkNotNull(owningPlugin, "plugin is null");
|
||||
|
||||
Map<Plugin, MetadataValue> entry = metadata.computeIfAbsent(new StoreKey(metadataKey, getBlockId(block)),
|
||||
k -> new WeakHashMap<>(1));
|
||||
entry.put(owningPlugin, newMetadataValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void invalidateAll(Plugin owningPlugin) {
|
||||
Preconditions.checkNotNull(owningPlugin, "plugin is null");
|
||||
for (Map<Plugin, MetadataValue> values : metadata.values()) {
|
||||
MetadataValue value = values.get(owningPlugin);
|
||||
if (value != null) {
|
||||
value.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Plugin, MetadataValue> getEntry(String key, Block block) {
|
||||
return getEntry(key, getBlockId(block));
|
||||
}
|
||||
|
||||
private Map<Plugin, MetadataValue> getEntry(String key, long id) {
|
||||
StoreKey storeKey = getCachedKey(key, id);
|
||||
Map<Plugin, MetadataValue> ret = metadata.get(storeKey);
|
||||
storeKey.metadataKey = null;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private StoreKey getCachedKey(String metadataKey, long id) {
|
||||
cachedKey.block = id;
|
||||
cachedKey.metadataKey = metadataKey;
|
||||
return cachedKey;
|
||||
}
|
||||
|
||||
static long getBlockId(Block block) {
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
Preconditions.checkArgument(x >= -30_000_000 && x <= 30_000_000,
|
||||
"block X out of range");
|
||||
Preconditions.checkArgument(y >= 0 && y <= 255, "block Y out of range");
|
||||
Preconditions.checkArgument(z >= -30_000_000 && z <= 30_000_000,
|
||||
"block Z out of range");
|
||||
// X (26 bits) + Y (8 bits) + Z (26 bits)
|
||||
return ((long) (x & MASK_26_BITS) << 34) | ((long) (y & 0xFF) << 26) | (z & MASK_26_BITS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for tests.
|
||||
*/
|
||||
static Location toLocation(World world, long id) {
|
||||
int x = (int) (id >> 34);
|
||||
int y = (int) ((id >> 26) & 0xFF);
|
||||
int z = (int) id;
|
||||
|
||||
// Restore sign
|
||||
if ((x & (1 << 25)) > 0) {
|
||||
x |= ~MASK_26_BITS;
|
||||
} else {
|
||||
x &= MASK_26_BITS;
|
||||
}
|
||||
|
||||
if ((z & (1 << 25)) > 0) {
|
||||
z |= ~MASK_26_BITS;
|
||||
} else {
|
||||
z &= MASK_26_BITS;
|
||||
}
|
||||
|
||||
return new Location(world, x, y, z);
|
||||
}
|
||||
|
||||
private static class StoreKey {
|
||||
private String metadataKey;
|
||||
private long block;
|
||||
|
||||
private StoreKey(String metadataKey, long block) {
|
||||
this.metadataKey = metadataKey;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
StoreKey storeKey = (StoreKey) o;
|
||||
return block == storeKey.block && Objects.equal(metadataKey, storeKey.metadataKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(metadataKey, block);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ import org.bukkit.metadata.MetadataStoreBase;
|
||||
public class WorldMetadataStore extends MetadataStoreBase<World> implements MetadataStore<World> {
|
||||
/**
|
||||
* Generates a unique metadata key for a {@link World} object based on the world UID.
|
||||
* @see WorldMetadataStore#disambiguate(Object, String)
|
||||
* @see WorldMetadataStore#disambiguate(World, String)
|
||||
* @param world the world
|
||||
* @param metadataKey The name identifying the metadata value
|
||||
* @return a unique metadata key
|
||||
|
@ -32,7 +32,7 @@ import org.bukkit.scheduler.BukkitWorker;
|
||||
* <li>Changing the period on a task is delicate.
|
||||
* Any future task needs to notify waiting threads.
|
||||
* Async tasks must be synchronized to make sure that any thread that's finishing will remove itself from {@link #runners}.
|
||||
* Another utility method is provided for this, {@link #cancelTask(CraftTask)}</li>
|
||||
* Another utility method is provided for this, {@link #cancelTask(int)}</li>
|
||||
* <li>{@link #runners} provides a moderately up-to-date view of active tasks.
|
||||
* If the linked head to tail set is read, all remaining tasks that were active at the time execution started will be located in runners.</li>
|
||||
* <li>Async tasks are responsible for removing themselves from runners</li>
|
||||
@ -47,7 +47,7 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
*/
|
||||
private final AtomicInteger ids = new AtomicInteger(1);
|
||||
/**
|
||||
* Current head of linked-list. This reference is always stale, {@link CraftTask#next} is the live reference.
|
||||
* Current head of linked-list. This reference is always stale, {@code CraftTask#next} is the live reference.
|
||||
*/
|
||||
private volatile CraftTask head = new CraftTask();
|
||||
/**
|
||||
|
@ -22,7 +22,8 @@ public final class CraftChatMessage {
|
||||
private static final Pattern LINK_PATTERN = Pattern.compile("((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " \\n]|$))))");
|
||||
private static class StringMessage {
|
||||
private static final Map<Character, EnumChatFormat> formatMap;
|
||||
private static final Pattern INCREMENTAL_PATTERN = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-or])|(\\n)|((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " \\n]|$))))", Pattern.CASE_INSENSITIVE);
|
||||
//private static final Pattern INCREMENTAL_PATTERN = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-or])|(\\n)|((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " \\n]|$))))", Pattern.CASE_INSENSITIVE);
|
||||
private static final Pattern INCREMENTAL_PATTERN = Pattern.compile("(§[0-9a-fk-or])|(\\n)|(https?://[^\\s/$.?#].[^\\s§]*)", Pattern.CASE_INSENSITIVE); // KigPaper - better regex
|
||||
|
||||
static {
|
||||
Builder<Character, EnumChatFormat> builder = ImmutableMap.builder();
|
||||
|
@ -13,6 +13,7 @@ import java.util.logging.Level;
|
||||
import net.minecraft.server.Item;
|
||||
import net.minecraft.server.Items;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.RegionFile;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
@ -227,4 +228,41 @@ public class PaperSpigotConfig
|
||||
private static void saveEmptyScoreboardTeams() {
|
||||
saveEmptyScoreboardTeams = getBoolean("save-empty-scoreboard-teams", false);
|
||||
}
|
||||
|
||||
// KigPaper start
|
||||
public static boolean betterVehicleHitboxes;
|
||||
private static void betterVehicleHitboxes() {
|
||||
betterVehicleHitboxes = getBoolean("better-vehicle-hitboxes", true);
|
||||
}
|
||||
|
||||
public static boolean nettyReadTimeout;
|
||||
private static void nettyReadTimeout() {
|
||||
nettyReadTimeout = getBoolean("netty-read-timeout", true);
|
||||
}
|
||||
|
||||
public static boolean savePlayerFiles;
|
||||
private static void savePlayerFiles() {
|
||||
savePlayerFiles = getBoolean("save-player-files", true);
|
||||
}
|
||||
|
||||
public static boolean enableBookDeserialization;
|
||||
private static void enableBookDeserialization() {
|
||||
enableBookDeserialization = getBoolean("enable-book-deserialization", false);
|
||||
}
|
||||
|
||||
public static boolean accurateBlockCollisions;
|
||||
private static void accurateBlockCollisions() {
|
||||
accurateBlockCollisions = getBoolean("accurate-block-collisions", true);
|
||||
}
|
||||
|
||||
public static RegionFile.CompressionAlgorithm regionCompressionAlgorithm;
|
||||
private static void regionCompressionAlgorithm() {
|
||||
regionCompressionAlgorithm = RegionFile.CompressionAlgorithm.valueOf(getString("region-compression-algo", "ZLIB").toUpperCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public static boolean kickChatMessageLength;
|
||||
private static void kickChatMessageLength() {
|
||||
kickChatMessageLength = getBoolean("kick-chat-message-length", false);
|
||||
}
|
||||
// KigPaper end
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public class ActivationRange
|
||||
* These entities are excluded from Activation range checks.
|
||||
*
|
||||
* @param entity
|
||||
* @param world
|
||||
* @param config
|
||||
* @return boolean If it should always tick.
|
||||
*/
|
||||
public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config)
|
||||
|
@ -344,7 +344,7 @@ public class Metrics {
|
||||
*/
|
||||
private void postPlugin(final boolean isPing) throws IOException {
|
||||
// Server software specific section
|
||||
String pluginName = "TacoSpigot"; // PaperSpigot - We need some usage data // TacoSpigot - its *my* usage data
|
||||
String pluginName = "eSpigot"; // PaperSpigot - We need some usage data // TacoSpigot - its *my* usage data // eSpigot
|
||||
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
|
||||
String pluginVersion = (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown";
|
||||
String serverVersion = Bukkit.getVersion();
|
||||
|
@ -191,10 +191,15 @@ public class SpigotWorldConfig
|
||||
}
|
||||
|
||||
public boolean saveStructureInfo;
|
||||
public boolean saveMineshaftStructureInfo; // Migot
|
||||
private void structureInfo()
|
||||
{
|
||||
saveStructureInfo = getBoolean( "save-structure-info", true );
|
||||
log( "Structure Info Saving: " + saveStructureInfo );
|
||||
// Migot start
|
||||
saveMineshaftStructureInfo = getBoolean( "save-mineshaft-structure-info", false);
|
||||
log( "Mineshaft Structure Info Saving: " + saveMineshaftStructureInfo );
|
||||
// Migot end
|
||||
if ( !saveStructureInfo )
|
||||
{
|
||||
log( "*** WARNING *** You have selected to NOT save structure info. This may cause structures such as fortresses to not spawn mobs!" );
|
||||
|
@ -56,9 +56,8 @@ public class WatchdogThread extends Thread
|
||||
{
|
||||
Logger log = Bukkit.getServer().getLogger();
|
||||
log.log( Level.SEVERE, "The server has stopped responding!" );
|
||||
log.log( Level.SEVERE, "Please report this to PaperSpigot directly!" );
|
||||
log.log( Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports" );
|
||||
log.log( Level.SEVERE, "PaperSpigot version: " + Bukkit.getServer().getVersion() );
|
||||
log.log( Level.SEVERE, "This is all alf's fault." );
|
||||
log.log( Level.SEVERE, "Version: " + Bukkit.getServer().getVersion() );
|
||||
//
|
||||
if(net.minecraft.server.World.haveWeSilencedAPhysicsCrash)
|
||||
{
|
||||
|
@ -0,0 +1,62 @@
|
||||
package org.bukkit.craftbukkit.metadata;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataStore;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BlockMetadataTest {
|
||||
@Test
|
||||
public void oldNewComparison() {
|
||||
MetadataStore<Block> oldStore = new BlockMetadataStore(null);
|
||||
MetadataStore<Block> newStore = new SpecializedBlockMetadataStore(null);
|
||||
Plugin plugin = Mockito.mock(Plugin.class);
|
||||
|
||||
for (int x = 2, y = 0, z = 2, i = 0; i < 20; i++, x += 300, z += 200, y += 10) {
|
||||
Block block = makeBlock(i % 2 == 0 ? x : -x, y, i % 2 == 0 ? z : -z);
|
||||
MetadataValue value = new FixedMetadataValue(plugin, i);
|
||||
|
||||
oldStore.setMetadata(block, "test", value);
|
||||
oldStore.setMetadata(block, "test" + i, value);
|
||||
newStore.setMetadata(block, "test", value);
|
||||
newStore.setMetadata(block, "test" + i, value);
|
||||
|
||||
Assert.assertTrue(newStore.hasMetadata(block, "test"));
|
||||
Assert.assertTrue(newStore.hasMetadata(block, "test" + i));
|
||||
|
||||
List<MetadataValue> test = newStore.getMetadata(block, "test");
|
||||
Assert.assertEquals(test, oldStore.getMetadata(block, "test"));
|
||||
Assert.assertTrue("value in newStore[\"test\"]", test.contains(value));
|
||||
|
||||
List<MetadataValue> indexTest = newStore.getMetadata(block, "test" + i);
|
||||
Assert.assertEquals(indexTest, oldStore.getMetadata(block, "test" + i));
|
||||
Assert.assertTrue("value in newStore[\"test\" + i]", indexTest.contains(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareIds() {
|
||||
for (int x = 3, y = 1, z = 2, i = 0; i < 20; i++, x += 300, z += 200, y += 10) {
|
||||
Block block = makeBlock(i % 2 == 0 ? x : -x, y, i % 2 == 0 ? z : -z);
|
||||
Location location = new Location(null, block.getX(), block.getY(), block.getZ());
|
||||
|
||||
Assert.assertEquals(location, SpecializedBlockMetadataStore.toLocation(null,
|
||||
SpecializedBlockMetadataStore.getBlockId(block)));
|
||||
}
|
||||
}
|
||||
|
||||
private static Block makeBlock(int x, int y, int z) {
|
||||
Block block = Mockito.mock(Block.class);
|
||||
Mockito.when(block.getX()).thenReturn(x);
|
||||
Mockito.when(block.getY()).thenReturn(y);
|
||||
Mockito.when(block.getZ()).thenReturn(z);
|
||||
return block;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user