From be7deb26370796d0f9d4de22c0a4973c798f154e Mon Sep 17 00:00:00 2001 From: beaness Date: Sat, 25 Jun 2022 16:22:33 +0200 Subject: [PATCH] SharedConfig & NachoSpigot optimizations --- .../7.1/executionHistory/executionHistory.bin | Bin 5262936 -> 5262936 bytes .../executionHistory/executionHistory.lock | Bin 17 -> 17 bytes .gradle/7.1/fileHashes/fileHashes.bin | Bin 529141 -> 529591 bytes .gradle/7.1/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../7.1/fileHashes/resourceHashesCache.bin | Bin 72559 -> 72797 bytes .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .gradle/buildOutputCleanup/outputFiles.bin | Bin 22457 -> 22529 bytes .gradle/checksums/checksums.lock | Bin 17 -> 17 bytes .gradle/checksums/md5-checksums.bin | Bin 20147 -> 20197 bytes .gradle/checksums/sha1-checksums.bin | Bin 27245 -> 27515 bytes .../java/co/aikar/timings/TimingHandler.java | 9 +- .../src/main/java/org/bukkit/Bukkit.java | 7 - .../src/main/java/org/bukkit/Server.java | 5 - .../org/bukkit/command/SimpleCommandMap.java | 1 - .../command/defaults/ReloadCommand.java | 39 -- eSpigot-Server/build.gradle.kts | 1 + .../elevatemc/spigot/config/BukkitConfig.java | 128 ++++++ .../elevatemc/spigot/config/SharedConfig.java | 90 +++++ .../spigot/config/eSpigotConfig.java | 109 +++++ .../java/com/elevatemc/spigot/eSpigot.java | 11 +- .../com/elevatemc/spigot/eSpigotFeature.java | 41 -- .../elevatemc/spigot/network/VarIntUtil.java | 1 + .../com/elevatemc/spigot/util/Constants.java | 6 + .../net/minecraft/server/BlockDragonEgg.java | 3 +- .../net/minecraft/server/BlockFluids.java | 4 +- .../java/net/minecraft/server/BlockGrass.java | 2 +- .../java/net/minecraft/server/BlockNote.java | 3 +- .../net/minecraft/server/BlockPumpkin.java | 5 +- .../minecraft/server/BlockRedstoneOre.java | 3 +- .../minecraft/server/BlockRedstoneTorch.java | 3 +- .../java/net/minecraft/server/BlockSkull.java | 3 +- .../net/minecraft/server/BlockStateList.java | 6 +- .../main/java/net/minecraft/server/Chunk.java | 41 +- .../net/minecraft/server/CommandAbstract.java | 5 +- .../minecraft/server/CommandScoreboard.java | 2 +- .../net/minecraft/server/DedicatedServer.java | 21 +- .../java/net/minecraft/server/Entity.java | 12 +- .../net/minecraft/server/EntityAgeable.java | 4 +- .../net/minecraft/server/EntityAnimal.java | 4 +- .../minecraft/server/EntityArmorStand.java | 2 +- .../net/minecraft/server/EntityArrow.java | 5 +- .../net/minecraft/server/EntityBlaze.java | 4 +- .../java/net/minecraft/server/EntityBoat.java | 5 +- .../net/minecraft/server/EntityCreature.java | 3 +- .../minecraft/server/EntityEnderDragon.java | 7 +- .../minecraft/server/EntityEnderSignal.java | 6 +- .../net/minecraft/server/EntityEnderman.java | 9 +- .../net/minecraft/server/EntityEndermite.java | 4 +- .../minecraft/server/EntityFallingBlock.java | 2 +- .../net/minecraft/server/EntityFireball.java | 5 +- .../net/minecraft/server/EntityFireworks.java | 4 +- .../minecraft/server/EntityFishingHook.java | 13 +- .../net/minecraft/server/EntityGuardian.java | 5 +- .../minecraft/server/EntityInsentient.java | 3 +- .../net/minecraft/server/EntityLiving.java | 18 +- .../server/EntityMinecartFurnace.java | 4 +- .../minecraft/server/EntityMinecartTNT.java | 4 +- .../minecraft/server/EntityMushroomCow.java | 3 +- .../net/minecraft/server/EntityPigZombie.java | 6 +- .../net/minecraft/server/EntityPlayer.java | 72 +++- .../minecraft/server/EntityProjectile.java | 6 +- .../net/minecraft/server/EntitySlime.java | 3 +- .../net/minecraft/server/EntitySnowball.java | 4 +- .../net/minecraft/server/EntityTNTPrimed.java | 3 +- .../server/EntityTameableAnimal.java | 7 +- .../net/minecraft/server/EntityTracker.java | 6 + .../minecraft/server/EntityTrackerEntry.java | 4 +- .../net/minecraft/server/EntityWitch.java | 4 +- .../net/minecraft/server/EntityWither.java | 7 +- .../java/net/minecraft/server/EntityWolf.java | 3 +- .../net/minecraft/server/EntityZombie.java | 3 +- .../net/minecraft/server/EnumDirection.java | 163 ++------ .../java/net/minecraft/server/Explosion.java | 11 +- .../minecraft/server/GameProfileBanEntry.java | 3 +- .../server/GameProfileSerializer.java | 3 +- .../main/java/net/minecraft/server/Item.java | 3 +- .../java/net/minecraft/server/ItemBucket.java | 3 +- .../net/minecraft/server/ItemEnderEye.java | 4 +- .../net/minecraft/server/MinecraftServer.java | 3 +- .../net/minecraft/server/MobEffectList.java | 3 +- .../minecraft/server/MobSpawnerAbstract.java | 5 +- .../net/minecraft/server/NBTTagCompound.java | 4 +- .../java/net/minecraft/server/NBTTagList.java | 5 +- .../server/NameReferencingFileConverter.java | 3 +- .../net/minecraft/server/NetworkManager.java | 10 - .../net/minecraft/server/OpListEntry.java | 3 +- .../server/PacketLoginOutSuccess.java | 5 +- .../server/PacketPlayInCloseWindow.java | 5 + .../server/PacketPlayOutMapChunk.java | 2 +- .../server/PacketPlayOutMapChunkBulk.java | 4 +- .../minecraft/server/PathfinderGoalBreed.java | 4 +- .../minecraft/server/PlayerConnection.java | 12 +- .../java/net/minecraft/server/PlayerList.java | 29 +- .../minecraft/server/ServerConnection.java | 38 +- .../java/net/minecraft/server/ServerPing.java | 5 +- .../net/minecraft/server/SpawnerCreature.java | 55 ++- .../server/TileEntityEnchantTable.java | 5 + .../minecraft/server/TileEntityFurnace.java | 2 + .../minecraft/server/TileEntityHopper.java | 6 +- .../java/net/minecraft/server/UserCache.java | 5 +- .../java/net/minecraft/server/Village.java | 3 +- .../net/minecraft/server/WhiteListEntry.java | 3 +- .../main/java/net/minecraft/server/World.java | 57 ++- .../net/minecraft/server/WorldNBTStorage.java | 2 +- .../net/minecraft/server/WorldServer.java | 20 +- .../techcable/tacospigot/HopperHelper.java | 2 +- .../techcable/tacospigot/HopperPusher.java | 2 +- .../tacospigot/TacoSpigotConfig.java | 106 ----- .../tacospigot/TacoSpigotWorldConfig.java | 113 ------ .../bukkit/craftbukkit/CraftCrashReport.java | 1 - .../craftbukkit/CraftOfflinePlayer.java | 3 +- .../org/bukkit/craftbukkit/CraftServer.java | 266 +++--------- .../org/bukkit/craftbukkit/CraftWorld.java | 3 +- .../java/org/bukkit/craftbukkit/Main.java | 27 +- .../bukkit/craftbukkit/entity/CraftHorse.java | 5 +- .../craftbukkit/entity/CraftPlayer.java | 9 +- .../entity/CraftTameableAnimal.java | 5 +- .../github/paperspigot/PaperSpigotConfig.java | 110 +---- .../paperspigot/PaperSpigotWorldConfig.java | 380 ++++++++++-------- .../main/java/org/spigotmc/SpigotConfig.java | 180 ++------- .../java/org/spigotmc/SpigotWorldConfig.java | 246 +++++------- 121 files changed, 1245 insertions(+), 1504 deletions(-) delete mode 100644 eSpigot-API/src/main/java/org/bukkit/command/defaults/ReloadCommand.java create mode 100644 eSpigot-Server/src/main/java/com/elevatemc/spigot/config/BukkitConfig.java create mode 100644 eSpigot-Server/src/main/java/com/elevatemc/spigot/config/SharedConfig.java create mode 100644 eSpigot-Server/src/main/java/com/elevatemc/spigot/config/eSpigotConfig.java delete mode 100644 eSpigot-Server/src/main/java/com/elevatemc/spigot/eSpigotFeature.java create mode 100644 eSpigot-Server/src/main/java/com/elevatemc/spigot/util/Constants.java delete mode 100644 eSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotConfig.java diff --git a/.gradle/7.1/executionHistory/executionHistory.bin b/.gradle/7.1/executionHistory/executionHistory.bin index b372564e2b6f19e8d25fc98dce1f95fc2c70bcc5..e495d422f92eb44ec26ec46ea5ece80c4e9146df 100644 GIT binary patch delta 53539 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 delta 49639 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 PZud>!8N0t!gR}tvt=wxB delta 95 zcmV-l0HFWfxCHOE1h6z10j#q%7>OFQ)-vA;v&}uj0tGPu0E8!#LD?abdf6|N+1W|6 z{y>6z0kyM%ya5BVn!nc%vx(0U0+X`Q@UyzoKoOJXMi;Xw1mXYy literal 17 VcmZQBofh<6aP77Z1~6cJ3jj8A1wsG- diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin index 89bf8689609209cae1ee8a1526abe21920807a18..e4b4c6222ad2bef7b50bbfae3308c769e5d475bb 100644 GIT binary patch delta 121 zcmdnFp0RNQ;|3E6#s`y4C2k0G1PQw69%2w@0E6(mn^`3lI0b%cPDzh&HHm?WzMm|s zq#*GB-=DbL$1$c*!PA>fl_IzVYM!3sw?Fbc9V)tWa;r`hlc?ZE#UJ7u4LF!LJ9<>` JPrmQz0RZT-CKLbw delta 49 zcmV-10M7q`umQQR0kAX}0o;={7}&EV85jwZRU#O(g(6T2lkF^00u-^aA@~=uFlYm_ HK}dKH$V3s! diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock index 057e5354efc00453dbcdfe12326670eaf1c78be1..0bb4c49b3e4f3287d8928597718447fd536554b8 100644 GIT binary patch literal 17 VcmZR6K96-?@v`Iq1~6b`0su351N#5~ literal 17 UcmZR6K96-?@v`Iq1_<~805om{@Bjb+ diff --git a/.gradle/checksums/md5-checksums.bin b/.gradle/checksums/md5-checksums.bin index 66cba72fe925a75dcbc9a37af381e15027eadbce..03fc8b509c238764f64743ca5ae075897b8d050c 100644 GIT binary patch delta 103 zcmdlym+|Rb#tkMCj7pPDC2j~@Jie{2x`X`%0~q*i-pnc)%*5!pQSpcPMuQt7n;kuh w*o=&UlA1uQ2*Lv0K5ggDDW~PxN7|>~b=)Me% diff --git a/.gradle/checksums/sha1-checksums.bin b/.gradle/checksums/sha1-checksums.bin index 89a276ea0634a8d473970f80782586b518b96d92..e96e373abe786c7ec649ee147411eee8335983ba 100644 GIT binary patch delta 410 zcmaERh4J?_#tkMCjLSEhN@%bO+;~#BgUx%94FectU^f5c zP=y%+tY?FQdWHU0Kvmw{{8S-=Q9xlwRC6Um98_u6;?1T?FIo6k{Z9I;9B>D!-*vL6 zdNkwCjfy|SHyR{xYu Mu`t*Ovq4BKB1L5sI{*Lx diff --git a/eSpigot-API/src/main/java/co/aikar/timings/TimingHandler.java b/eSpigot-API/src/main/java/co/aikar/timings/TimingHandler.java index 3ffe7e5..13e592d 100644 --- a/eSpigot-API/src/main/java/co/aikar/timings/TimingHandler.java +++ b/eSpigot-API/src/main/java/co/aikar/timings/TimingHandler.java @@ -112,7 +112,14 @@ class TimingHandler implements Timing { start = 0; return; } - addDiff(System.nanoTime() - start); + try + { + addDiff(System.nanoTime() - start); + } + catch (ArrayIndexOutOfBoundsException ex) + { + ex.printStackTrace(); + } start = 0; } } diff --git a/eSpigot-API/src/main/java/org/bukkit/Bukkit.java b/eSpigot-API/src/main/java/org/bukkit/Bukkit.java index 933607e..cd3b4de 100644 --- a/eSpigot-API/src/main/java/org/bukkit/Bukkit.java +++ b/eSpigot-API/src/main/java/org/bukkit/Bukkit.java @@ -550,13 +550,6 @@ public final class Bukkit { return server.createMap(world); } - /** - * Reloads the server, refreshing settings and plugin information. - */ - public static void reload() { - server.reload(); - } - /** * Returns the primary logger associated with this server instance. * diff --git a/eSpigot-API/src/main/java/org/bukkit/Server.java b/eSpigot-API/src/main/java/org/bukkit/Server.java index bb2e2d1..3632413 100644 --- a/eSpigot-API/src/main/java/org/bukkit/Server.java +++ b/eSpigot-API/src/main/java/org/bukkit/Server.java @@ -452,11 +452,6 @@ public interface Server extends PluginMessageRecipient { */ MapView createMap(World world); - /** - * Reloads the server, refreshing settings and plugin information. - */ - void reload(); - /** * Returns the primary logger associated with this server instance. * diff --git a/eSpigot-API/src/main/java/org/bukkit/command/SimpleCommandMap.java b/eSpigot-API/src/main/java/org/bukkit/command/SimpleCommandMap.java index 29e2d0a..4c3fc92 100644 --- a/eSpigot-API/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/eSpigot-API/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -30,7 +30,6 @@ public class SimpleCommandMap implements CommandMap { private void setDefaultCommands() { register("bukkit", new VersionCommand("version")); - register("bukkit", new ReloadCommand("reload")); register("bukkit", new PluginsCommand("plugins")); register("bukkit", new co.aikar.timings.TimingsCommand("timings")); // Spigot } diff --git a/eSpigot-API/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/eSpigot-API/src/main/java/org/bukkit/command/defaults/ReloadCommand.java deleted file mode 100644 index 22f81af..0000000 --- a/eSpigot-API/src/main/java/org/bukkit/command/defaults/ReloadCommand.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.bukkit.command.defaults; - -import java.util.Arrays; -import java.util.Collections; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; - -public class ReloadCommand extends BukkitCommand { - public ReloadCommand(String name) { - super(name); - this.description = "Reloads the server configuration and plugins"; - this.usageMessage = "/reload"; - this.setPermission("bukkit.command.reload"); - this.setAliases(Collections.singletonList("rl")); - } - - @Override - public boolean execute(CommandSender sender, String currentAlias, String[] args) { - if (!testPermission(sender)) return true; - - Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues when using some plugins."); - Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server."); - Bukkit.reload(); - Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete."); - - return true; - } - - // Spigot Start - @Override - public java.util.List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException - { - return java.util.Collections.emptyList(); - } - // Spigot End -} diff --git a/eSpigot-Server/build.gradle.kts b/eSpigot-Server/build.gradle.kts index 5a92e5a..7896664 100644 --- a/eSpigot-Server/build.gradle.kts +++ b/eSpigot-Server/build.gradle.kts @@ -49,6 +49,7 @@ dependencies { implementation("com.github.luben:zstd-jni:1.5.2-3") implementation("net.openhft:affinity:3.20.0") implementation("net.jafama:jafama:2.3.2") + implementation("com.eatthepath:fast-uuid:0.2.0") testImplementation("junit:junit:4.11") diff --git a/eSpigot-Server/src/main/java/com/elevatemc/spigot/config/BukkitConfig.java b/eSpigot-Server/src/main/java/com/elevatemc/spigot/config/BukkitConfig.java new file mode 100644 index 0000000..adb8021 --- /dev/null +++ b/eSpigot-Server/src/main/java/com/elevatemc/spigot/config/BukkitConfig.java @@ -0,0 +1,128 @@ +package com.elevatemc.spigot.config; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.List; +import java.util.Map; + +public class BukkitConfig { + + public static YamlConfiguration config; + static Map commands; + + public static void init() + { + config = SharedConfig.config; + commands = SharedConfig.commands; + SharedConfig.readConfig( BukkitConfig.class, null ); + } + + private static boolean getBoolean(String path, boolean def) + { + path = "bukkit." + path; + config.addDefault( path, def ); + return config.getBoolean( path, config.getBoolean( path ) ); + } + + private static double getDouble(String path, double def) + { + path = "bukkit." + path; + config.addDefault( path, def ); + return config.getDouble( path, config.getDouble( path ) ); + } + + private static int getInt(String path, int def) + { + path = "bukkit." + path; + config.addDefault( path, def ); + return config.getInt( path, config.getInt( path ) ); + } + + private static List getList(String path, T def) + { + path = "bukkit." + path; + config.addDefault( path, def ); + return config.getList( path, config.getList( path ) ); + } + + private static String getString(String path, String def) + { + path = "bukkit." + path; + config.addDefault( path, def ); + return config.getString( path, config.getString( path ) ); + } + + public static ConfigurationSection getConfigurationSection(String path) { + return config.getConfigurationSection("bukkit." + path); + } + + public static boolean allowEnd = true; + public static boolean warnOnOverlaod = true; + public static String permissionsFile = "permissions.yml"; + public static String updateFolder = "update"; + public static boolean pluginProfiling = false; + public static int connectionThrottle = 4000; + public static boolean queryPlugins = true; + public static String deprecatedVerbose = "default"; + public static String shutdownMessage = "Server closed"; + public static String permissionMessage = 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."; + public static boolean useExactLoginLocation = false; + public static String worldContainer = "."; + private static void settings() { + allowEnd = getBoolean("settings.allow-end", allowEnd); + warnOnOverlaod = getBoolean("settings.warn-on-overload", warnOnOverlaod); + permissionsFile = getString("settings.update-folder", updateFolder); + pluginProfiling = getBoolean("settings.plugin-profilling", pluginProfiling); + connectionThrottle = getInt("settings.connection-throttle", connectionThrottle); + queryPlugins = getBoolean("settings.query-plugins", queryPlugins); + deprecatedVerbose = getString("settings.deprecated-verbose", deprecatedVerbose); + shutdownMessage = getString("settings.shutdown-message", shutdownMessage); + permissionMessage = getString("settings.permission-message", permissionMessage); + useExactLoginLocation = getBoolean("settings.use-exact-login-location", useExactLoginLocation); + worldContainer = getString("settings.world-container", worldContainer); + } + + public static int monsterSpawnLimit = 70; + public static int animalSpawnLimit = 15; + public static int waterAnimalSpawnLimit = 5; + public static int ambientSpawnLimit = 15; + private static void spawnLimits() { + monsterSpawnLimit = getInt("spawn-limits.monsters", monsterSpawnLimit); + animalSpawnLimit = getInt("spawn-limits.animals", animalSpawnLimit); + waterAnimalSpawnLimit = getInt("spawn-limits.water-animals", waterAnimalSpawnLimit); + ambientSpawnLimit = getInt("spawn-limits.ambient", ambientSpawnLimit); + } + + public static int chunkGCPeriodInTicks = 600; + public static int chunkGCLoadThreshold = 0; + private static void chunkGC() { + chunkGCPeriodInTicks = getInt("chunk-gc.period-in-ticks", chunkGCPeriodInTicks); + chunkGCLoadThreshold = getInt("chunk-gc.load-threshold", chunkGCLoadThreshold); + } + + public static int ticksPerAnimalSpawn = 400; + public static int ticksPerMonsterSpawn = 1; + public static int ticksPerAutosave = 6000; + private static void ticksPer() { + ticksPerAnimalSpawn = getInt("ticks-per.animal-spawns", ticksPerAnimalSpawn); + ticksPerMonsterSpawn = getInt("ticks-per.monster-spawns", ticksPerMonsterSpawn); + ticksPerAutosave = getInt("ticks-per.autosave", ticksPerAutosave); + } + + public static String databaseUsername = "bukkit"; + public static String databaseIsolation = "SERIALIZABLE"; + public static String databaseDriver = "org.sqlite.JDBC"; + public static String databasePassword = "walrus"; + public static String databaseUrl = "jdbc:sqlite:{DIR}{NAME}.db"; + private static void database() { + databaseUsername = getString("database.username", databaseUsername); + databaseIsolation = getString("database.isolation", databaseIsolation); + databaseDriver = getString("database.driver", databaseDriver); + databasePassword = getString("database.password", databasePassword); + databaseUrl = getString("database.url", databaseUrl); + } + +} diff --git a/eSpigot-Server/src/main/java/com/elevatemc/spigot/config/SharedConfig.java b/eSpigot-Server/src/main/java/com/elevatemc/spigot/config/SharedConfig.java new file mode 100644 index 0000000..f5ba9b0 --- /dev/null +++ b/eSpigot-Server/src/main/java/com/elevatemc/spigot/config/SharedConfig.java @@ -0,0 +1,90 @@ +package com.elevatemc.spigot.config; + +import com.google.common.base.Throwables; +import net.minecraft.server.MinecraftServer; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.github.paperspigot.PaperSpigotConfig; +import org.github.paperspigot.PaperSpigotWorldConfig; +import org.spigotmc.SpigotConfig; +import org.spigotmc.SpigotWorldConfig; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; + +public class SharedConfig { + + private static File CONFIG_FILE; + private static final String HEADER = "This is the main configuration file for eSpigot.\n" + + "Command aliases also go in this file, just put what you would normally put in commands.yml under a commands: tag"; + + /*========================================================================*/ + public static YamlConfiguration config; + public static Map commands; + /*========================================================================*/ + + public static void init(File configFile) { + CONFIG_FILE = configFile; + config = new YamlConfiguration(); + try { + config.load (CONFIG_FILE); + } catch (IOException ex) { + } catch (InvalidConfigurationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Could not load sportpaper.yml, please correct your syntax errors", ex); + throw Throwables.propagate(ex); + } + config.options().header(HEADER); + config.options().copyDefaults(true); + + commands = new HashMap(); + + eSpigotConfig.init(); + BukkitConfig.init(); + SpigotConfig.init(); + PaperSpigotConfig.init(); + SpigotWorldConfig.init(); + PaperSpigotWorldConfig.init(); + } + + public static void registerCommands() { + for (Map.Entry entry : commands.entrySet()) { + MinecraftServer. + getServer(). + server. + getCommandMap(). + register(entry.getKey(), "eSpigot", entry.getValue()); + } + } + + public static void readConfig(Class clazz, Object instance) { + for (Method method : clazz.getDeclaredMethods()) { + if (Modifier.isPrivate(method.getModifiers())) { + if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) { + try { + method.setAccessible(true); + method.invoke(instance); + } catch (InvocationTargetException ex) { + throw Throwables.propagate(ex.getCause()); + } catch (Exception ex) { + Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex); + } + } + } + } + + try { + config.save(CONFIG_FILE); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex); + } + } + +} diff --git a/eSpigot-Server/src/main/java/com/elevatemc/spigot/config/eSpigotConfig.java b/eSpigot-Server/src/main/java/com/elevatemc/spigot/config/eSpigotConfig.java new file mode 100644 index 0000000..ce5c04f --- /dev/null +++ b/eSpigot-Server/src/main/java/com/elevatemc/spigot/config/eSpigotConfig.java @@ -0,0 +1,109 @@ +package com.elevatemc.spigot.config; + +import java.util.*; + +import org.bukkit.command.Command; +import org.bukkit.configuration.file.YamlConfiguration; + +public class eSpigotConfig +{ + + public static YamlConfiguration config; + static Map commands; + + public static void init() + { + config = SharedConfig.config; + commands = SharedConfig.commands; + SharedConfig.readConfig( eSpigotConfig.class, null ); + } + + private static boolean getBoolean(String path, boolean def) + { + path = "espigot." + path; + config.addDefault( path, def ); + return config.getBoolean( path, config.getBoolean( path ) ); + } + + private static double getDouble(String path, double def) + { + path = "espigot." + path; + config.addDefault( path, def ); + return config.getDouble( path, config.getDouble( path ) ); + } + + private static int getInt(String path, int def) + { + path = "espigot." + path; + config.addDefault( path, def ); + return config.getInt( path, config.getInt( path ) ); + } + + private static List getList(String path, T def) + { + path = "espigot." + path; + config.addDefault( path, def ); + return config.getList( path, config.getList( path ) ); + } + + private static String getString(String path, String def) + { + path = "espigot." + path; + config.addDefault( path, def ); + return config.getString( path, config.getString( path ) ); + } + + public static boolean entityCollisions; + private static void entityCollisions() + { + entityCollisions = getBoolean( "settings.entity-collisions", false ); + } + + public static boolean villageTicking; + private static void villageTicking() + { + villageTicking = getBoolean( "settings.village-ticking", false ); + } + + public static boolean enchantmentTableTicking; + private static void enchantmentTableTicking() + { + enchantmentTableTicking = getBoolean( "settings.enchantment-table-ticking", false ); + } + + public static boolean dayLightCycle; + private static void dayLightCycle() + { + dayLightCycle = getBoolean( "settings.day-light-cycle", false ); + } + + public static boolean naturalMobSpawning; + private static void naterualMobSpawning() + { + naturalMobSpawning = getBoolean( "settings.natural-mob-spawning", false ); + } + + public static boolean showHiddenPlayersInTab; + private static void showHiddenPlayersInTab() + { + showHiddenPlayersInTab = getBoolean( "settings.show-hidden-players-in-tab", true ); + } + + public static boolean mobAI; + private static void mobAI() + { + mobAI = getBoolean( "settings.mob-ai", false ); + } + + public static boolean fixSprintEatExploit; + private static void fixSprintEatExploit() + { + fixSprintEatExploit = getBoolean( "settings.fix-sprint-eat-exploit", true ); + } + + public static boolean obfuscatePlayerHealth; + private static void obfuscatePlayerHealth() + { + obfuscatePlayerHealth = getBoolean( "settings.obfuscate-player-health", true ); + } +} diff --git a/eSpigot-Server/src/main/java/com/elevatemc/spigot/eSpigot.java b/eSpigot-Server/src/main/java/com/elevatemc/spigot/eSpigot.java index 6b05c49..5027946 100644 --- a/eSpigot-Server/src/main/java/com/elevatemc/spigot/eSpigot.java +++ b/eSpigot-Server/src/main/java/com/elevatemc/spigot/eSpigot.java @@ -28,20 +28,16 @@ public class eSpigot { return instance; } - private final YamlConfig config, knockbackConfig; + private final YamlConfig knockbackConfig; private final KnockbackHandler knockbackHandler; public eSpigot(CraftServer server) { // Set instance of the server instance = this; - config = new YamlConfig("espigot.yml"); knockbackConfig = new YamlConfig("knockback.yml"); knockbackHandler = new KnockbackHandler(); - for (eSpigotFeature eSpigotFeature : eSpigotFeature.values()) - eSpigotFeature.reload(config); - for (Command command : Arrays.asList(new KnockbackCommand(), new TicksPerSecondCommand())) server.getCommandMap() .register(command.getLabel(), "eSpigot", command); @@ -67,11 +63,6 @@ public class eSpigot { return this.packetHandlers; } - - public YamlConfig getConfig() { - return config; - } - public YamlConfig getKnockbackConfig() { return knockbackConfig; } diff --git a/eSpigot-Server/src/main/java/com/elevatemc/spigot/eSpigotFeature.java b/eSpigot-Server/src/main/java/com/elevatemc/spigot/eSpigotFeature.java deleted file mode 100644 index 6e4dd0f..0000000 --- a/eSpigot-Server/src/main/java/com/elevatemc/spigot/eSpigotFeature.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.elevatemc.spigot; - -import org.bukkit.configuration.file.YamlConfiguration; -import com.elevatemc.spigot.util.YamlConfig; - -public enum eSpigotFeature { - - ENTITY_COLLISION(false), - VILLAGE_TICKING(false), - DAY_LIGHT_CYCLE(false), - NATURAL_MOB_SPAWNING(false), - SHOW_HIDDEN_PLAYERS_IN_TAB(true), - MOB_AI(false), - FIX_SPRINT_EAT_EXPLOIT(true), - OBFUSCATE_HEALTH(true); - - private boolean enabled; - - eSpigotFeature(boolean enabled) { - this.enabled = enabled; - } - - public void reload(YamlConfig yamlConfig) { - yamlConfig.reload(); - YamlConfiguration config = yamlConfig.getConfig(); - - if (config != null) { - enabled = config.getBoolean("features." + name().toLowerCase(), enabled); - config.set("features." + name().toLowerCase(), enabled); - yamlConfig.saveAsync(); - } - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } -} diff --git a/eSpigot-Server/src/main/java/com/elevatemc/spigot/network/VarIntUtil.java b/eSpigot-Server/src/main/java/com/elevatemc/spigot/network/VarIntUtil.java index 4013383..4005259 100644 --- a/eSpigot-Server/src/main/java/com/elevatemc/spigot/network/VarIntUtil.java +++ b/eSpigot-Server/src/main/java/com/elevatemc/spigot/network/VarIntUtil.java @@ -1,3 +1,4 @@ +// Original source: velocity package com.elevatemc.spigot.network; import io.netty.buffer.ByteBuf; diff --git a/eSpigot-Server/src/main/java/com/elevatemc/spigot/util/Constants.java b/eSpigot-Server/src/main/java/com/elevatemc/spigot/util/Constants.java new file mode 100644 index 0000000..246eb08 --- /dev/null +++ b/eSpigot-Server/src/main/java/com/elevatemc/spigot/util/Constants.java @@ -0,0 +1,6 @@ +package com.elevatemc.spigot.util; + +public class Constants +{ + public static final int[] EMPTY_ARRAY = new int[0]; +} \ No newline at end of file diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/BlockDragonEgg.java b/eSpigot-Server/src/main/java/net/minecraft/server/BlockDragonEgg.java index 4b81020..47351ef 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/BlockDragonEgg.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/BlockDragonEgg.java @@ -2,6 +2,7 @@ package net.minecraft.server; import java.util.Random; +import com.elevatemc.spigot.util.Constants; import org.bukkit.event.block.BlockFromToEvent; // CraftBukkit public class BlockDragonEgg extends Block { @@ -87,7 +88,7 @@ public class BlockDragonEgg extends Block { double d2 = (double) blockposition1.getY() + (double) (blockposition.getY() - blockposition1.getY()) * d0 + world.random.nextDouble() * 1.0D - 0.5D; double d3 = (double) blockposition1.getZ() + (double) (blockposition.getZ() - blockposition1.getZ()) * d0 + (world.random.nextDouble() - 0.5D) * 1.0D + 0.5D; - world.addParticle(EnumParticle.PORTAL, d1, d2, d3, f, f1, f2, new int[0]); + world.addParticle(EnumParticle.PORTAL, d1, d2, d3, f, f1, f2, Constants.EMPTY_ARRAY); } } else { world.setTypeAndData(blockposition1, iblockdata, 2); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/BlockFluids.java b/eSpigot-Server/src/main/java/net/minecraft/server/BlockFluids.java index 29b1cc8..a7df73f 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/BlockFluids.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/BlockFluids.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + import java.util.Iterator; import java.util.Random; @@ -171,7 +173,7 @@ public abstract class BlockFluids extends Block { world.makeSound(d0 + 0.5D, d1 + 0.5D, d2 + 0.5D, "random.fizz", 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); for (int i = 0; i < 8; ++i) { - world.addParticle(EnumParticle.SMOKE_LARGE, d0 + Math.random(), d1 + 1.2D, d2 + Math.random(), 0.0D, 0.0D, 0.0D, new int[0]); + world.addParticle(EnumParticle.SMOKE_LARGE, d0 + Math.random(), d1 + 1.2D, d2 + Math.random(), 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/BlockGrass.java b/eSpigot-Server/src/main/java/net/minecraft/server/BlockGrass.java index 0d0f241..6eec173 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/BlockGrass.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/BlockGrass.java @@ -44,7 +44,7 @@ public class BlockGrass extends Block implements IBlockFragilePlantElement { } // CraftBukkit end } else { - if (world.tacoSpigotConfig.grassIgnoresLight || world.getLightLevel(blockposition.up()) >= 9) { // TacoSpigot - add an option to ignore light + if (world.paperSpigotConfig.grassIgnoresLight || world.getLightLevel(blockposition.up()) >= 9) { // TacoSpigot - add an option to ignore light for (int i = 0; i < Math.min(4, Math.max(20, (int) (4 * 100F / world.growthOdds))); ++i) { // Spigot BlockPosition blockposition1 = blockposition.a(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1); Block block = world.getType(blockposition1.up()).getBlock(); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/BlockNote.java b/eSpigot-Server/src/main/java/net/minecraft/server/BlockNote.java index e6b7546..c7e419a 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/BlockNote.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/BlockNote.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.google.common.collect.Lists; import java.util.List; @@ -76,7 +77,7 @@ public class BlockNote extends BlockContainer { float f = (float) Math.pow(2.0D, (double) (j - 12) / 12.0D); world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "note." + this.b(i), 3.0F, f); - world.addParticle(EnumParticle.NOTE, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 1.2D, (double) blockposition.getZ() + 0.5D, (double) j / 24.0D, 0.0D, 0.0D, new int[0]); + world.addParticle(EnumParticle.NOTE, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 1.2D, (double) blockposition.getZ() + 0.5D, (double) j / 24.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); return true; } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/BlockPumpkin.java b/eSpigot-Server/src/main/java/net/minecraft/server/BlockPumpkin.java index 21b3cc2..b876273 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/BlockPumpkin.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/BlockPumpkin.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.google.common.base.Predicate; // CraftBukkit start @@ -65,7 +66,7 @@ public class BlockPumpkin extends BlockDirectional { blockList.updateList(); for (j = 0; j < 120; ++j) { - world.addParticle(EnumParticle.SNOW_SHOVEL, (double) blockposition1.getX() + world.random.nextDouble(), (double) blockposition1.getY() + world.random.nextDouble() * 2.5D, (double) blockposition1.getZ() + world.random.nextDouble(), 0.0D, 0.0D, 0.0D, new int[0]); + world.addParticle(EnumParticle.SNOW_SHOVEL, (double) blockposition1.getX() + world.random.nextDouble(), (double) blockposition1.getY() + world.random.nextDouble() * 2.5D, (double) blockposition1.getZ() + world.random.nextDouble(), 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } for (j = 0; j < this.getDetectorSnowGolem().b(); ++j) { @@ -97,7 +98,7 @@ public class BlockPumpkin extends BlockDirectional { blockList.updateList(); for (j = 0; j < 120; ++j) { - world.addParticle(EnumParticle.SNOWBALL, (double) blockposition2.getX() + world.random.nextDouble(), (double) blockposition2.getY() + world.random.nextDouble() * 3.9D, (double) blockposition2.getZ() + world.random.nextDouble(), 0.0D, 0.0D, 0.0D, new int[0]); + world.addParticle(EnumParticle.SNOWBALL, (double) blockposition2.getX() + world.random.nextDouble(), (double) blockposition2.getY() + world.random.nextDouble() * 3.9D, (double) blockposition2.getZ() + world.random.nextDouble(), 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } for (j = 0; j < this.getDetectorIronGolem().c(); ++j) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneOre.java b/eSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneOre.java index 881de93..3252015 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneOre.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneOre.java @@ -3,6 +3,7 @@ package net.minecraft.server; import java.util.Random; // CraftBukkit start +import com.elevatemc.spigot.util.Constants; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit end @@ -147,7 +148,7 @@ public class BlockRedstoneOre extends Block { } if (d1 < (double) blockposition.getX() || d1 > (double) (blockposition.getX() + 1) || d2 < 0.0D || d2 > (double) (blockposition.getY() + 1) || d3 < (double) blockposition.getZ() || d3 > (double) (blockposition.getZ() + 1)) { - world.addParticle(EnumParticle.REDSTONE, d1, d2, d3, 0.0D, 0.0D, 0.0D, new int[0]); + world.addParticle(EnumParticle.REDSTONE, d1, d2, d3, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneTorch.java b/eSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneTorch.java index 2627344..6fe68c2 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneTorch.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneTorch.java @@ -2,6 +2,7 @@ package net.minecraft.server; import java.util.Random; +import com.elevatemc.spigot.util.Constants; import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit public class BlockRedstoneTorch extends BlockTorch { @@ -152,7 +153,7 @@ public class BlockRedstoneTorch extends BlockTorch { double d1 = blockposition.getY() + random.nextDouble() * 0.6D + 0.2D; double d2 = blockposition.getZ() + random.nextDouble() * 0.6D + 0.2D; - world.addParticle(EnumParticle.SMOKE_NORMAL, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]); + world.addParticle(EnumParticle.SMOKE_NORMAL, d0, d1, d2, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } world.a(blockposition, world.getType(blockposition).getBlock(), 160); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/BlockSkull.java b/eSpigot-Server/src/main/java/net/minecraft/server/BlockSkull.java index 74673e4..5bdad2d 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/BlockSkull.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/BlockSkull.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.google.common.base.Predicate; import java.util.Iterator; import java.util.Random; @@ -208,7 +209,7 @@ public class BlockSkull extends BlockContainer { int k; for (k = 0; k < 120; ++k) { - world.addParticle(EnumParticle.SNOWBALL, (double) blockposition1.getX() + world.random.nextDouble(), (double) (blockposition1.getY() - 2) + world.random.nextDouble() * 3.9D, (double) blockposition1.getZ() + world.random.nextDouble(), 0.0D, 0.0D, 0.0D, new int[0]); + world.addParticle(EnumParticle.SNOWBALL, (double) blockposition1.getX() + world.random.nextDouble(), (double) (blockposition1.getY() - 2) + world.random.nextDouble() * 3.9D, (double) blockposition1.getZ() + world.random.nextDouble(), 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } for (k = 0; k < shapedetector.c(); ++k) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/BlockStateList.java b/eSpigot-Server/src/main/java/net/minecraft/server/BlockStateList.java index 031d41b..16b2eeb 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/BlockStateList.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/BlockStateList.java @@ -26,7 +26,7 @@ import com.google.common.collect.Table; import net.techcable.tacospigot.ImmutableArrayMap; import net.techcable.tacospigot.ImmutableArrayTable; -import net.techcable.tacospigot.TacoSpigotConfig; +import org.github.paperspigot.PaperSpigotConfig; // TacoSpigot end public class BlockStateList { @@ -126,7 +126,7 @@ public class BlockStateList { this.a = block; // TacoSpigot start this.bAsImmutableMap = immutablemap; - if (TacoSpigotConfig.useArraysForBlockStates) { + if (PaperSpigotConfig.useArraysForBlockStates) { b = new ImmutableArrayMap<>(IBlockState.INDEXER, immutablemap); } else { b = immutablemap; @@ -195,7 +195,7 @@ public class BlockStateList { } // TacoSpigot start - if (TacoSpigotConfig.useArraysForBlockStates) { + if (PaperSpigotConfig.useArraysForBlockStates) { this.c = new ImmutableArrayTable ( IBlockState.INDEXER, (IBlockState state, Comparable value) -> state.getValueId(value), diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/Chunk.java b/eSpigot-Server/src/main/java/net/minecraft/server/Chunk.java index 0f79fef..5bf4ec2 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/Chunk.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/Chunk.java @@ -687,6 +687,44 @@ public class Chunk { return chunksection == null ? (this.d(blockposition) ? enumskyblock.c : 0) : (enumskyblock == EnumSkyBlock.SKY ? (this.world.worldProvider.o() ? 0 : chunksection.d(i, j & 15, k)) : (enumskyblock == EnumSkyBlock.BLOCK ? chunksection.e(i, j & 15, k) : enumskyblock.c)); } + public int getBrightness(EnumSkyBlock enumskyblock, int blockposition_x, int blockposition_y, int blockposition_z) { + int i = blockposition_x & 15; + int j = blockposition_y; + int k = blockposition_z & 15; + ChunkSection chunksection = this.sections[j >> 4]; + + if(chunksection == null) + { + if(j >= this.heightMap[(k) << 4 | (i)]) + { + return enumskyblock.c; + } + } + else + { + if(enumskyblock == EnumSkyBlock.SKY) + { + if(!this.world.worldProvider.o()) + { + return chunksection.d(i, j & 15, k); + } + } + else + { + if(enumskyblock == EnumSkyBlock.BLOCK) + { + return chunksection.e(i, j & 15, k); + } + else + { + return enumskyblock.c; + } + } + } + + return 0; + } + public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { int j = blockposition.getX() & 15; int k = blockposition.getY(); @@ -838,9 +876,10 @@ public class Chunk { public boolean isBelowHeightMap(int blockposition_x, int blockposition_y, int blockposition_z) { int i = blockposition_x & 15; + int j = blockposition_y; int k = blockposition_z & 15; - return blockposition_y >= this.heightMap[k << 4 | i]; + return j >= this.heightMap[k << 4 | i]; } public TileEntity i(BlockPosition blockposition) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/CommandAbstract.java b/eSpigot-Server/src/main/java/net/minecraft/server/CommandAbstract.java index 1121880..d38e0d8 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/CommandAbstract.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/CommandAbstract.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.common.base.Functions; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -139,7 +140,7 @@ public abstract class CommandAbstract implements ICommand { if (entityplayer == null) { try { - entityplayer = MinecraftServer.getServer().getPlayerList().a(UUID.fromString(s)); + entityplayer = MinecraftServer.getServer().getPlayerList().a(FastUUID.parseUUID(s)); } catch (IllegalArgumentException illegalargumentexception) { ; } @@ -170,7 +171,7 @@ public abstract class CommandAbstract implements ICommand { if (object == null) { try { - UUID uuid = UUID.fromString(s); + UUID uuid = FastUUID.parseUUID(s); object = minecraftserver.a(uuid); if (object == null) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/CommandScoreboard.java b/eSpigot-Server/src/main/java/net/minecraft/server/CommandScoreboard.java index 5e4ed54..c992da1 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/CommandScoreboard.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/CommandScoreboard.java @@ -475,7 +475,7 @@ public class CommandScoreboard extends CommandAbstract { for (Object o : list) { Entity entity = (Entity) o; - if (!entity.world.tacoSpigotConfig.nonPlayerEntitiesOnScoreboards && !(entity instanceof EntityHuman)) + if (!entity.world.paperSpigotConfig.nonPlayerEntitiesOnScoreboards && !(entity instanceof EntityHuman)) continue; // TacoSpigot String s2 = e(icommandlistener, entity.getUniqueID().toString()); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/DedicatedServer.java b/eSpigot-Server/src/main/java/net/minecraft/server/DedicatedServer.java index 594e1f8..90a71bd 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/DedicatedServer.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.config.SharedConfig; import com.elevatemc.spigot.console.PandaConsole; import java.io.File; @@ -159,9 +160,9 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer // PandaSpigot - Move SpigotConfig to load earlier, so that we can check IP forwarding status here. // Spigot start this.a(new DedicatedPlayerList(this)); - org.spigotmc.SpigotConfig.init((File) options.valueOf("spigot-settings")); - org.spigotmc.SpigotConfig.registerCommands(); // Spigot end + SharedConfig.registerCommands(); + java.net.SocketAddress bindAddress; if (this.getServerIp().startsWith("unix:")) { if (!io.netty.channel.epoll.Epoll.isAvailable()) { @@ -189,12 +190,6 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer bindAddress = new java.net.InetSocketAddress(inetaddress, this.R()); } - // PandaSpigot end - // PaperSpigot start - org.github.paperspigot.PaperSpigotConfig.init((File) options.valueOf("paper-settings")); - org.github.paperspigot.PaperSpigotConfig.registerCommands(); - // PaperSpigot end - DedicatedServer.LOGGER.info("Generating keypair"); this.a(MinecraftEncryption.b()); DedicatedServer.LOGGER.info("Starting Minecraft server on " + (this.getServerIp().length() == 0 ? "*" : this.getServerIp()) + ":" + this.R()); @@ -295,16 +290,6 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer this.remoteConsole = new org.bukkit.craftbukkit.command.CraftRemoteConsoleCommandSender(); // CraftBukkit } - // CraftBukkit start - if (this.server.getBukkitSpawnRadius() > -1) { - DedicatedServer.LOGGER.info("'settings.spawn-radius' in bukkit.yml has been moved to 'spawn-protection' in server.properties. I will move your config for you."); - this.propertyManager.properties.remove("spawn-protection"); - this.propertyManager.getInt("spawn-protection", this.server.getBukkitSpawnRadius()); - this.server.removeBukkitSpawnRadius(); - this.propertyManager.savePropertiesFile(); - } - // CraftBukkit end - if (org.spigotmc.SpigotConfig.lateBind) { try { this.aq().bind(bindAddress); // PandaSpigot - Unix domain socket support diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/Entity.java b/eSpigot-Server/src/main/java/net/minecraft/server/Entity.java index 5a82d03..f9de1d9 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/Entity.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/Entity.java @@ -4,6 +4,8 @@ import java.util.*; import java.util.concurrent.Callable; // CraftBukkit start +import com.eatthepath.uuid.FastUUID; +import com.elevatemc.spigot.util.Constants; import com.elevatemc.spigot.util.FastRandom; import org.apache.logging.log4j.LogManager; import org.bukkit.Bukkit; @@ -557,7 +559,7 @@ public abstract class Entity implements ICommandListener { double xLength = totalArea.d - totalArea.a; double yLength = totalArea.e - totalArea.b; double zLength = totalArea.f - totalArea.c; - boolean axisScan = this.world.tacoSpigotConfig.optimizeTntMovement && xLength * yLength * zLength > 10; + boolean axisScan = this.world.paperSpigotConfig.optimizeTntMovement && xLength * yLength * zLength > 10; List list = this.world.getCubes(this, axisScan ? this.getBoundingBox().a(0, d1, 0) : totalArea); // TacoSpigot end @@ -577,7 +579,7 @@ public abstract class Entity implements ICommandListener { Iterator iterator1; // eSpigot start - getCubesNoEntities - if(this.world.tacoSpigotConfig.fixEastWest && Math.abs(d0) > Math.abs(d2)) { //TacoSpigot - fix east/west cannoning by calculating the z movement before x if the x velocity is greater + if(this.world.paperSpigotConfig.fixEastWest && Math.abs(d0) > Math.abs(d2)) { //TacoSpigot - fix east/west cannoning by calculating the z movement before x if the x velocity is greater if(axisScan) list = this.world.getCubesNoEntities(this, this.getBoundingBox().a(0, 0, d2)); // TacoSpigot - get z axis blocks for (iterator1 = list.iterator(); iterator1.hasNext(); d2 = axisalignedbb2.c(this.getBoundingBox(), d2)) { @@ -1053,13 +1055,13 @@ public abstract class Entity implements ICommandListener { for (i = 0; (float) i < 1.0F + this.width * 20.0F; ++i) { f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width; f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width; - this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + (double) f2, f1 + 1.0F, this.locZ + (double) f3, this.motX, this.motY - (double) (this.random.nextFloat() * 0.2F), this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + (double) f2, f1 + 1.0F, this.locZ + (double) f3, this.motX, this.motY - (double) (this.random.nextFloat() * 0.2F), this.motZ, Constants.EMPTY_ARRAY); } for (i = 0; (float) i < 1.0F + this.width * 20.0F; ++i) { f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width; f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width; - this.world.addParticle(EnumParticle.WATER_SPLASH, this.locX + (double) f2, f1 + 1.0F, this.locZ + (double) f3, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_SPLASH, this.locX + (double) f2, f1 + 1.0F, this.locZ + (double) f3, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } } @@ -1440,7 +1442,7 @@ public abstract class Entity implements ICommandListener { if (nbttagcompound.hasKeyOfType("UUIDMost", 4) && nbttagcompound.hasKeyOfType("UUIDLeast", 4)) { this.uniqueID = new UUID(nbttagcompound.getLong("UUIDMost"), nbttagcompound.getLong("UUIDLeast")); } else if (nbttagcompound.hasKeyOfType("UUID", 8)) { - this.uniqueID = UUID.fromString(nbttagcompound.getString("UUID")); + this.uniqueID = FastUUID.parseUUID(nbttagcompound.getString("UUID")); } this.setPosition(this.locX, this.locY, this.locZ); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityAgeable.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityAgeable.java index e6f32ea..37c7ef0 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityAgeable.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityAgeable.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public abstract class EntityAgeable extends EntityCreature { protected int a; @@ -140,7 +142,7 @@ public abstract class EntityAgeable extends EntityCreature { if (this.world.isClientSide || ageLocked) { // CraftBukkit if (this.c > 0) { if (this.c % 4 == 0) { - this.world.addParticle(EnumParticle.VILLAGER_HAPPY, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.VILLAGER_HAPPY, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } --this.c; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityAnimal.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityAnimal.java index c725368..535cbb8 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityAnimal.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityAnimal.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public abstract class EntityAnimal extends EntityAgeable implements IAnimal { protected Block bn; @@ -32,7 +34,7 @@ public abstract class EntityAnimal extends EntityAgeable implements IAnimal { double d1 = this.random.nextGaussian() * 0.02D; double d2 = this.random.nextGaussian() * 0.02D; - this.world.addParticle(EnumParticle.HEART, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2, new int[0]); + this.world.addParticle(EnumParticle.HEART, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2, Constants.EMPTY_ARRAY); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityArmorStand.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityArmorStand.java index ed4b3bd..2774043 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityArmorStand.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityArmorStand.java @@ -714,7 +714,7 @@ public class EntityArmorStand extends EntityLiving { // TacoSpigot start - add an option to make armor stands not move @Override public void move(double motX, double motY, double motZ) { - if (getWorld().tacoSpigotConfig.optimizeArmorStandMovement) return; + if (getWorld().paperSpigotConfig.optimizeArmorStandMovement) return; super.move(motX, motY, motZ); } // TacoSpigot end diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityArrow.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityArrow.java index 1c3aa31..cc1050a 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityArrow.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityArrow.java @@ -3,6 +3,7 @@ package net.minecraft.server; import java.util.List; // CraftBukkit start +import com.elevatemc.spigot.util.Constants; import org.bukkit.entity.LivingEntity; import org.bukkit.event.entity.EntityCombustByEntityEvent; import org.bukkit.event.player.PlayerPickupItemEvent; @@ -342,7 +343,7 @@ public class EntityArrow extends Entity implements IProjectile { if (this.isCritical()) { for (j = 0; j < 4; ++j) { - this.world.addParticle(EnumParticle.CRIT, this.locX + this.motX * (double) j / 4.0D, this.locY + this.motY * (double) j / 4.0D, this.locZ + this.motZ * (double) j / 4.0D, -this.motX, -this.motY + 0.2D, -this.motZ, new int[0]); + this.world.addParticle(EnumParticle.CRIT, this.locX + this.motX * (double) j / 4.0D, this.locY + this.motY * (double) j / 4.0D, this.locZ + this.motZ * (double) j / 4.0D, -this.motX, -this.motY + 0.2D, -this.motZ, Constants.EMPTY_ARRAY); } } @@ -375,7 +376,7 @@ public class EntityArrow extends Entity implements IProjectile { if (this.V()) { for (int l = 0; l < 4; ++l) { f3 = 0.25F; - this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX - this.motX * (double) f3, this.locY - this.motY * (double) f3, this.locZ - this.motZ * (double) f3, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX - this.motX * (double) f3, this.locY - this.motY * (double) f3, this.locZ - this.motZ * (double) f3, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } f4 = 0.6F; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityBlaze.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityBlaze.java index c6b7113..e9c0a66 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityBlaze.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityBlaze.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public class EntityBlaze extends EntityMonster { private float a = 0.5F; @@ -57,7 +59,7 @@ public class EntityBlaze extends EntityMonster { } for (int i = 0; i < 2; ++i) { - this.world.addParticle(EnumParticle.SMOKE_LARGE, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.SMOKE_LARGE, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityBoat.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityBoat.java index 7b78b7c..45cca9b 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityBoat.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityBoat.java @@ -3,6 +3,7 @@ package net.minecraft.server; import java.util.List; // CraftBukkit start +import com.elevatemc.spigot.util.Constants; import org.bukkit.Location; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.entity.Vehicle; @@ -200,11 +201,11 @@ public class EntityBoat extends Entity { if (this.random.nextBoolean()) { d8 = this.locX - d4 * d6 * 0.8D + d5 * d7; d9 = this.locZ - d5 * d6 * 0.8D - d4 * d7; - this.world.addParticle(EnumParticle.WATER_SPLASH, d8, this.locY - 0.125D, d9, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_SPLASH, d8, this.locY - 0.125D, d9, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } else { d8 = this.locX + d4 + d5 * d6 * 0.7D; d9 = this.locZ + d5 - d4 * d6 * 0.7D; - this.world.addParticle(EnumParticle.WATER_SPLASH, d8, this.locY - 0.125D, d9, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_SPLASH, d8, this.locY - 0.125D, d9, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityCreature.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityCreature.java index 3daf7c4..e205513 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityCreature.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityCreature.java @@ -3,6 +3,7 @@ package net.minecraft.server; import java.util.UUID; // CraftBukkit start +import com.eatthepath.uuid.FastUUID; import com.elevatemc.spigot.pathsearch.jobs.PathSearchJob; import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobEntity; import com.elevatemc.spigot.pathsearch.jobs.PathSearchJobPosition; @@ -12,7 +13,7 @@ import org.bukkit.event.entity.EntityUnleashEvent; public abstract class EntityCreature extends EntityInsentient { - public static final UUID bk = UUID.fromString("E199AD21-BA8A-4C53-8D13-6182D5C69D3A"); + public static final UUID bk = FastUUID.parseUUID("E199AD21-BA8A-4C53-8D13-6182D5C69D3A"); public static final AttributeModifier bl = (new AttributeModifier(EntityCreature.bk, "Fleeing speed bonus", 2.0D, 2)).a(false); private BlockPosition a; private float b; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderDragon.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderDragon.java index 44f7cc3..b681beb 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderDragon.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.Iterator; @@ -99,7 +100,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo f = (this.random.nextFloat() - 0.5F) * 8.0F; f1 = (this.random.nextFloat() - 0.5F) * 4.0F; f2 = (this.random.nextFloat() - 0.5F) * 8.0F; - this.world.addParticle(EnumParticle.EXPLOSION_LARGE, this.locX + (double) f, this.locY + 2.0D + (double) f1, this.locZ + (double) f2, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.EXPLOSION_LARGE, this.locX + (double) f, this.locY + 2.0D + (double) f1, this.locZ + (double) f2, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } else { this.n(); f = 0.2F / (MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ) * 10.0F + 1.0F); @@ -498,7 +499,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo double d1 = axisalignedbb.b + (axisalignedbb.e - axisalignedbb.b) * (double) this.random.nextFloat(); double d2 = axisalignedbb.c + (axisalignedbb.f - axisalignedbb.c) * (double) this.random.nextFloat(); - this.world.addParticle(EnumParticle.EXPLOSION_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.EXPLOSION_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } return flag; @@ -548,7 +549,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo float f1 = (this.random.nextFloat() - 0.5F) * 4.0F; float f2 = (this.random.nextFloat() - 0.5F) * 8.0F; - this.world.addParticle(EnumParticle.EXPLOSION_HUGE, this.locX + (double) f, this.locY + 2.0D + (double) f1, this.locZ + (double) f2, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.EXPLOSION_HUGE, this.locX + (double) f, this.locY + 2.0D + (double) f1, this.locZ + (double) f2, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } boolean flag = this.world.getGameRules().getBoolean("doMobLoot"); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderSignal.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderSignal.java index 1e4188c..03318f5 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderSignal.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderSignal.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public class EntityEnderSignal extends Entity { private double a; @@ -99,10 +101,10 @@ public class EntityEnderSignal extends Entity { if (this.V()) { for (int i = 0; i < 4; ++i) { - this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX - this.motX * (double) f3, this.locY - this.motY * (double) f3, this.locZ - this.motZ * (double) f3, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX - this.motX * (double) f3, this.locY - this.motY * (double) f3, this.locZ - this.motZ * (double) f3, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } } else { - this.world.addParticle(EnumParticle.PORTAL, this.locX - this.motX * (double) f3 + this.random.nextDouble() * 0.6D - 0.3D, this.locY - this.motY * (double) f3 - 0.5D, this.locZ - this.motZ * (double) f3 + this.random.nextDouble() * 0.6D - 0.3D, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.PORTAL, this.locX - this.motX * (double) f3 + this.random.nextDouble() * 0.6D - 0.3D, this.locY - this.motY * (double) f3 - 0.5D, this.locZ - this.motZ * (double) f3 + this.random.nextDouble() * 0.6D - 0.3D, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } if (!this.world.isClientSide) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderman.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderman.java index 03a6906..cd0ac9c 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderman.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityEnderman.java @@ -1,8 +1,9 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; +import com.elevatemc.spigot.util.Constants; import com.google.common.base.Predicate; import com.google.common.collect.Sets; -import java.util.Collections; import java.util.List; import java.util.Random; import java.util.Set; @@ -15,7 +16,7 @@ import org.bukkit.event.entity.EntityTeleportEvent; public class EntityEnderman extends EntityMonster { - private static final UUID a = UUID.fromString("020E0DFB-87AE-4653-9556-831010E291A0"); + private static final UUID a = FastUUID.parseUUID("020E0DFB-87AE-4653-9556-831010E291A0"); private static final AttributeModifier b = (new AttributeModifier(EntityEnderman.a, "Attacking speed boost", 0.15000000596046448D, 0)).a(false); private static final Set c = Sets.newIdentityHashSet(); private boolean bm; @@ -104,7 +105,7 @@ public class EntityEnderman extends EntityMonster { public void m() { if (this.world.isClientSide) { for (int i = 0; i < 2; ++i) { - this.world.addParticle(EnumParticle.PORTAL, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length - 0.25D, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, (this.random.nextDouble() - 0.5D) * 2.0D, -this.random.nextDouble(), (this.random.nextDouble() - 0.5D) * 2.0D, new int[0]); + this.world.addParticle(EnumParticle.PORTAL, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length - 0.25D, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, (this.random.nextDouble() - 0.5D) * 2.0D, -this.random.nextDouble(), (this.random.nextDouble() - 0.5D) * 2.0D, Constants.EMPTY_ARRAY); } } @@ -214,7 +215,7 @@ public class EntityEnderman extends EntityMonster { double d8 = d4 + (this.locY - d4) * d6 + this.random.nextDouble() * (double) this.length; double d9 = d5 + (this.locZ - d5) * d6 + (this.random.nextDouble() - 0.5D) * (double) this.width * 2.0D; - this.world.addParticle(EnumParticle.PORTAL, d7, d8, d9, f, f1, f2, new int[0]); + this.world.addParticle(EnumParticle.PORTAL, d7, d8, d9, f, f1, f2, Constants.EMPTY_ARRAY); } this.world.makeSound(d3, d4, d5, "mob.endermen.portal", 1.0F, 1.0F); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityEndermite.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityEndermite.java index be2bf9c..3014b25 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityEndermite.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityEndermite.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public class EntityEndermite extends EntityMonster { private int a = 0; @@ -82,7 +84,7 @@ public class EntityEndermite extends EntityMonster { super.m(); if (this.world.isClientSide) { for (int i = 0; i < 2; ++i) { - this.world.addParticle(EnumParticle.PORTAL, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, (this.random.nextDouble() - 0.5D) * 2.0D, -this.random.nextDouble(), (this.random.nextDouble() - 0.5D) * 2.0D, new int[0]); + this.world.addParticle(EnumParticle.PORTAL, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, (this.random.nextDouble() - 0.5D) * 2.0D, -this.random.nextDouble(), (this.random.nextDouble() - 0.5D) * 2.0D, Constants.EMPTY_ARRAY); } } else { if (!this.isPersistent()) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityFallingBlock.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityFallingBlock.java index 5789de6..a332c64 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityFallingBlock.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityFallingBlock.java @@ -113,7 +113,7 @@ public class EntityFallingBlock extends Entity { if (this.world.getType(blockposition).getBlock() != Blocks.PISTON_EXTENSION) { this.die(); if (!this.e) { - if (this.world.a(block, blockposition, true, EnumDirection.UP, null, null) && !BlockFalling.canFall(this.world, blockposition.down()) /* mimic the false conditions of setTypeIdAndData */ && blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000 && blockposition.getY() >= 0 && blockposition.getY() < (this.world.tacoSpigotConfig.disableFallingBlockStackingAt256 ? 255 : 256) && this.world.getType(blockposition) != this.block) { + if (this.world.a(block, blockposition, true, EnumDirection.UP, null, null) && !BlockFalling.canFall(this.world, blockposition.down()) /* mimic the false conditions of setTypeIdAndData */ && blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000 && blockposition.getY() >= 0 && blockposition.getY() < (this.world.paperSpigotConfig.disableFallingBlockStackingAt256 ? 255 : 256) && this.world.getType(blockposition) != this.block) { if (CraftEventFactory.callEntityChangeBlockEvent(this, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.block.getBlock(), this.block.getBlock().toLegacyData(this.block)).isCancelled()) { return; } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityFireball.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityFireball.java index 06b54ad..738ca30 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityFireball.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityFireball.java @@ -2,6 +2,7 @@ package net.minecraft.server; import java.util.List; +import com.elevatemc.spigot.util.Constants; import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public abstract class EntityFireball extends Entity { @@ -166,7 +167,7 @@ public abstract class EntityFireball extends Entity { for (int j = 0; j < 4; ++j) { float f3 = 0.25F; - this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX - this.motX * (double) f3, this.locY - this.motY * (double) f3, this.locZ - this.motZ * (double) f3, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX - this.motX * (double) f3, this.locY - this.motY * (double) f3, this.locZ - this.motZ * (double) f3, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } f2 = 0.8F; @@ -178,7 +179,7 @@ public abstract class EntityFireball extends Entity { this.motX *= f2; this.motY *= f2; this.motZ *= f2; - this.world.addParticle(EnumParticle.SMOKE_NORMAL, this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.SMOKE_NORMAL, this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); this.setPosition(this.locX, this.locY, this.locZ); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityFireworks.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityFireworks.java index 2d101a4..50c6e61 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityFireworks.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityFireworks.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public class EntityFireworks extends Entity { private int ticksFlown; @@ -82,7 +84,7 @@ public class EntityFireworks extends Entity { ++this.ticksFlown; if (this.world.isClientSide && this.ticksFlown % 2 < 2) { - this.world.addParticle(EnumParticle.FIREWORKS_SPARK, this.locX, this.locY - 0.3D, this.locZ, this.random.nextGaussian() * 0.05D, -this.motY * 0.5D, this.random.nextGaussian() * 0.05D, new int[0]); + this.world.addParticle(EnumParticle.FIREWORKS_SPARK, this.locX, this.locY - 0.3D, this.locZ, this.random.nextGaussian() * 0.05D, -this.motY * 0.5D, this.random.nextGaussian() * 0.05D, Constants.EMPTY_ARRAY); } if (!this.world.isClientSide && this.ticksFlown > this.expectedLifespan) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityFishingHook.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityFishingHook.java index e1f9ff7..4bb3f96 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityFishingHook.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityFishingHook.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.List; // CraftBukkit start +import com.elevatemc.spigot.util.Constants; import org.bukkit.entity.Player; import org.bukkit.entity.Fish; import org.bukkit.event.player.PlayerFishEvent; @@ -288,8 +289,8 @@ public class EntityFishingHook extends Entity { this.motY -= 0.20000000298023224D; this.makeSound("random.splash", 0.25F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); f3 = (float) MathHelper.floor(this.getBoundingBox().b); - worldserver.a(EnumParticle.WATER_BUBBLE, this.locX, f3 + 1.0F, this.locZ, (int) (1.0F + this.width * 20.0F), this.width, 0.0D, this.width, 0.20000000298023224D, new int[0]); - worldserver.a(EnumParticle.WATER_WAKE, this.locX, f3 + 1.0F, this.locZ, (int) (1.0F + this.width * 20.0F), this.width, 0.0D, this.width, 0.20000000298023224D, new int[0]); + worldserver.a(EnumParticle.WATER_BUBBLE, this.locX, f3 + 1.0F, this.locZ, (int) (1.0F + this.width * 20.0F), this.width, 0.0D, this.width, 0.20000000298023224D, Constants.EMPTY_ARRAY); + worldserver.a(EnumParticle.WATER_WAKE, this.locX, f3 + 1.0F, this.locZ, (int) (1.0F + this.width * 20.0F), this.width, 0.0D, this.width, 0.20000000298023224D, Constants.EMPTY_ARRAY); this.av = MathHelper.nextInt(this.random, 10, 30); } else { this.ay = (float) ((double) this.ay + this.random.nextGaussian() * 4.0D); @@ -302,14 +303,14 @@ public class EntityFishingHook extends Entity { block = worldserver.getType(new BlockPosition((int) d8, (int) d12 - 1, (int) d11)).getBlock(); if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) { if (this.random.nextFloat() < 0.15F) { - worldserver.a(EnumParticle.WATER_BUBBLE, d8, d12 - 0.10000000149011612D, d11, 1, f5, 0.1D, f4, 0.0D, new int[0]); + worldserver.a(EnumParticle.WATER_BUBBLE, d8, d12 - 0.10000000149011612D, d11, 1, f5, 0.1D, f4, 0.0D, Constants.EMPTY_ARRAY); } float f6 = f5 * 0.04F; float f7 = f4 * 0.04F; - worldserver.a(EnumParticle.WATER_WAKE, d8, d12, d11, 0, f7, 0.01D, -f6, 1.0D, new int[0]); - worldserver.a(EnumParticle.WATER_WAKE, d8, d12, d11, 0, -f7, 0.01D, f6, 1.0D, new int[0]); + worldserver.a(EnumParticle.WATER_WAKE, d8, d12, d11, 0, f7, 0.01D, -f6, 1.0D, Constants.EMPTY_ARRAY); + worldserver.a(EnumParticle.WATER_WAKE, d8, d12, d11, 0, -f7, 0.01D, f6, 1.0D, Constants.EMPTY_ARRAY); } } } else if (this.aw > 0) { @@ -331,7 +332,7 @@ public class EntityFishingHook extends Entity { d11 = this.locZ + (double) (MathHelper.cos(f5) * f4 * 0.1F); block = worldserver.getType(new BlockPosition((int) d8, (int) d12 - 1, (int) d11)).getBlock(); if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) { - worldserver.a(EnumParticle.WATER_SPLASH, d8, d12, d11, 2 + this.random.nextInt(2), 0.10000000149011612D, 0.0D, 0.10000000149011612D, 0.0D, new int[0]); + worldserver.a(EnumParticle.WATER_SPLASH, d8, d12, d11, 2 + this.random.nextInt(2), 0.10000000149011612D, 0.0D, 0.10000000149011612D, 0.0D, Constants.EMPTY_ARRAY); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityGuardian.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityGuardian.java index 4dfe5a6..2616206 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityGuardian.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityGuardian.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.google.common.base.Predicate; import java.util.Iterator; import java.util.List; @@ -211,7 +212,7 @@ public class EntityGuardian extends EntityMonster { Vec3D vec3d = this.d(0.0F); for (int i = 0; i < 2; ++i) { - this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width - vec3d.a * 1.5D, this.locY + this.random.nextDouble() * (double) this.length - vec3d.b * 1.5D, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width - vec3d.c * 1.5D, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width - vec3d.a * 1.5D, this.locY + this.random.nextDouble() * (double) this.length - vec3d.b * 1.5D, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width - vec3d.c * 1.5D, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } } @@ -238,7 +239,7 @@ public class EntityGuardian extends EntityMonster { while (d5 < d4) { d5 += 1.8D - d0 + this.random.nextDouble() * (1.7D - d0); - this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + d1 * d5, this.locY + d2 * d5 + (double) this.getHeadHeight(), this.locZ + d3 * d5, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + d1 * d5, this.locY + d2 * d5 + (double) this.getHeadHeight(), this.locZ + d3 * d5, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityInsentient.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityInsentient.java index f9e8cae..0788ef1 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityInsentient.java @@ -7,6 +7,7 @@ import java.util.UUID; // CraftBukkit start import com.elevatemc.spigot.pathsearch.AsyncNavigation; +import com.elevatemc.spigot.util.Constants; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.entity.CraftLivingEntity; import org.bukkit.event.entity.EntityTargetLivingEntityEvent; @@ -184,7 +185,7 @@ public abstract class EntityInsentient extends EntityLiving { double d2 = this.random.nextGaussian() * 0.02D; double d3 = 10.0D; - this.world.addParticle(EnumParticle.EXPLOSION_NORMAL, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d0 * d3, this.locY + (double) (this.random.nextFloat() * this.length) - d1 * d3, this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d2 * d3, d0, d1, d2, new int[0]); + this.world.addParticle(EnumParticle.EXPLOSION_NORMAL, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d0 * d3, this.locY + (double) (this.random.nextFloat() * this.length) - d1 * d3, this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d2 * d3, d0, d1, d2, Constants.EMPTY_ARRAY); } } else { this.world.broadcastEntityEffect(this, (byte) 20); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java index 2d8e90b..fb9ff97 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java @@ -1,5 +1,8 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; +import com.elevatemc.spigot.config.eSpigotConfig; +import com.elevatemc.spigot.util.Constants; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Maps; @@ -28,14 +31,13 @@ import org.bukkit.event.vehicle.VehicleExitEvent; // PaperSpigot start import org.bukkit.Bukkit; -import com.elevatemc.spigot.eSpigotFeature; import com.elevatemc.spigot.eSpigot; import org.spigotmc.event.entity.EntityDismountEvent; // PaperSpigot end public abstract class EntityLiving extends Entity { - private static final UUID a = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D"); + private static final UUID a = FastUUID.parseUUID("662A6B8D-DA3E-4C1C-8813-96EA6097278D"); private static final AttributeModifier b = (new AttributeModifier(EntityLiving.a, "Sprinting speed boost", 0.30000001192092896D, 2)).a(false); private AttributeMapBase c; public CombatTracker combatTracker = new CombatTracker(this); @@ -214,7 +216,7 @@ public abstract class EntityLiving extends Entity { float f1 = this.random.nextFloat() - this.random.nextFloat(); float f2 = this.random.nextFloat() - this.random.nextFloat(); - this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + (double) f, this.locY + (double) f1, this.locZ + (double) f2, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + (double) f, this.locY + (double) f1, this.locZ + (double) f2, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } this.damageEntity(DamageSource.DROWN, 2.0F); @@ -315,7 +317,7 @@ public abstract class EntityLiving extends Entity { double d1 = this.random.nextGaussian() * 0.02D; double d2 = this.random.nextGaussian() * 0.02D; - this.world.addParticle(EnumParticle.EXPLOSION_NORMAL, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2, new int[0]); + this.world.addParticle(EnumParticle.EXPLOSION_NORMAL, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2, Constants.EMPTY_ARRAY); } } @@ -539,7 +541,7 @@ public abstract class EntityLiving extends Entity { double d1 = (double) (i >> 8 & 255) / 255.0D; double d2 = (double) (i & 255) / 255.0D; - this.world.addParticle(flag ? EnumParticle.SPELL_MOB_AMBIENT : EnumParticle.SPELL_MOB, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, d0, d1, d2, new int[0]); + this.world.addParticle(flag ? EnumParticle.SPELL_MOB_AMBIENT : EnumParticle.SPELL_MOB, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, d0, d1, d2, Constants.EMPTY_ARRAY); } } @@ -1664,7 +1666,7 @@ public abstract class EntityLiving extends Entity { this.ba = 0.0F; this.bb = 0.0F; } else if (this.bM()) { - if (eSpigotFeature.MOB_AI.isEnabled() || this instanceof EntityHuman) { + if (eSpigotConfig.mobAI || this instanceof EntityHuman) { this.world.methodProfiler.a("newAi"); this.doTick(); this.world.methodProfiler.b(); @@ -1704,7 +1706,7 @@ public abstract class EntityLiving extends Entity { protected void doTick() {} protected void bL() { - if (!eSpigotFeature.ENTITY_COLLISION.isEnabled()) + if (!eSpigotConfig.entityCollisions) return; List list = this.world.a(this, this.getBoundingBox().grow(0.20000000298023224D, 0.0D, 0.20000000298023224D), Predicates.and(IEntitySelector.d, new Predicate() { @@ -1871,7 +1873,7 @@ public abstract class EntityLiving extends Entity { } public ScoreboardTeamBase getScoreboardTeam() { - if (!this.world.tacoSpigotConfig.nonPlayerEntitiesOnScoreboards && !(this instanceof EntityHuman)) return null; // TacoSpigot + if (!this.world.paperSpigotConfig.nonPlayerEntitiesOnScoreboards && !(this instanceof EntityHuman)) return null; // TacoSpigot return this.world.getScoreboard().getPlayerTeam(this.getUniqueID().toString()); } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartFurnace.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartFurnace.java index ccc59d9..920fe25 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartFurnace.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartFurnace.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public class EntityMinecartFurnace extends EntityMinecartAbstract { private int c; @@ -35,7 +37,7 @@ public class EntityMinecartFurnace extends EntityMinecartAbstract { this.i(this.c > 0); if (this.j() && this.random.nextInt(4) == 0) { - this.world.addParticle(EnumParticle.SMOKE_LARGE, this.locX, this.locY + 0.8D, this.locZ, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.SMOKE_LARGE, this.locX, this.locY + 0.8D, this.locZ, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartTNT.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartTNT.java index 98d3217..8d364e9 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartTNT.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartTNT.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public class EntityMinecartTNT extends EntityMinecartAbstract { private int a = -1; @@ -24,7 +26,7 @@ public class EntityMinecartTNT extends EntityMinecartAbstract { super.t_(); if (this.a > 0) { --this.a; - this.world.addParticle(EnumParticle.SMOKE_NORMAL, this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.SMOKE_NORMAL, this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } else if (this.a == 0) { this.b(this.motX * this.motX + this.motZ * this.motZ); } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityMushroomCow.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityMushroomCow.java index fef767c..1dbd645 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityMushroomCow.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityMushroomCow.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import org.bukkit.event.player.PlayerShearEntityEvent; // CraftBukkit public class EntityMushroomCow extends EntityCow { @@ -35,7 +36,7 @@ public class EntityMushroomCow extends EntityCow { } // CraftBukkit end this.die(); - this.world.addParticle(EnumParticle.EXPLOSION_LARGE, this.locX, this.locY + (double) (this.length / 2.0F), this.locZ, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.EXPLOSION_LARGE, this.locX, this.locY + (double) (this.length / 2.0F), this.locZ, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); if (!this.world.isClientSide) { EntityCow entitycow = new EntityCow(this.world); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityPigZombie.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityPigZombie.java index 10f363a..c672aae 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityPigZombie.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityPigZombie.java @@ -1,10 +1,12 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; + import java.util.UUID; public class EntityPigZombie extends EntityZombie { - private static final UUID b = UUID.fromString("49455A49-7EC5-45BA-B886-3B90B23A1718"); + private static final UUID b = FastUUID.parseUUID("49455A49-7EC5-45BA-B886-3B90B23A1718"); private static final AttributeModifier c = (new AttributeModifier(EntityPigZombie.b, "Attacking speed boost", 0.05D, 0)).a(false); public int angerLevel; private int soundDelay; @@ -92,7 +94,7 @@ public class EntityPigZombie extends EntityZombie { String s = nbttagcompound.getString("HurtBy"); if (s.length() > 0) { - this.hurtBy = UUID.fromString(s); + this.hurtBy = FastUUID.parseUUID(s); EntityHuman entityhuman = this.world.b(this.hurtBy); this.b((EntityLiving) entityhuman); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityPlayer.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityPlayer.java index 01f3ce4..0eab50f 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityPlayer.java @@ -8,6 +8,7 @@ import io.netty.buffer.Unpooled; import java.util.*; import com.elevatemc.spigot.eSpigot; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -192,6 +193,11 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.bs(), PacketPlayOutCombatEvent.EnumCombatEventType.END_COMBAT)); } + private long chunkToLong(int chunkX, int chunkZ) + { + return (chunkX << 32L) + chunkZ - -2147483648L; + } + public void t_() { // CraftBukkit start if (this.joining) { @@ -231,49 +237,71 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } if (!this.chunkCoordIntPairQueue.isEmpty()) { - ArrayList arraylist = Lists.newArrayList(); - Iterator iterator1 = this.chunkCoordIntPairQueue.iterator(); - ArrayList arraylist1 = Lists.newArrayList(); + ArrayList chunkList = Lists.newArrayList(); + Iterator chunksToLoad = this.chunkCoordIntPairQueue.iterator(); + ArrayList tileEntities = Lists.newArrayList(); - Chunk chunk; + Chunk chunk = null; - while (iterator1.hasNext() && arraylist.size() < this.world.spigotConfig.maxBulkChunk) { // Spigot - ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator1.next(); + while (chunksToLoad.hasNext() && chunkList.size() < this.world.spigotConfig.maxBulkChunk) { // Spigot + ChunkCoordIntPair chunkcoordintpair = chunksToLoad.next(); if (chunkcoordintpair != null) { - if (this.world.isLoaded(new BlockPosition(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4))) { + if (this.world.isLoaded(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4)) {// [Nacho-0024] Do not create new BlockPosition when loading chunk chunk = this.world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z); if (chunk.isReady()) { - arraylist.add(chunk); - arraylist1.addAll(chunk.tileEntities.values()); // CraftBukkit - Get tile entities directly from the chunk instead of the world - iterator1.remove(); + chunkList.add(chunk); + tileEntities.addAll(chunk.tileEntities.values()); // CraftBukkit - Get tile entities directly from the chunk instead of the world + chunksToLoad.remove(); } } } else { - iterator1.remove(); + chunksToLoad.remove(); } } - if (!arraylist.isEmpty()) { - if (arraylist.size() == 1) { - this.playerConnection.sendPacket(new PacketPlayOutMapChunk((Chunk) arraylist.get(0), true, '\uffff')); + if (!chunkList.isEmpty()) { + if (chunkList.size() == 1) { + this.playerConnection.sendPacket(new PacketPlayOutMapChunk(chunkList.get(0), true, '\uffff')); } else { - this.playerConnection.sendPacket(new PacketPlayOutMapChunkBulk(arraylist)); + this.playerConnection.sendPacket(new PacketPlayOutMapChunkBulk(chunkList)); } - Iterator iterator2 = arraylist1.iterator(); + Iterator tileEntitiesIterator = tileEntities.iterator(); - while (iterator2.hasNext()) { - TileEntity tileentity = (TileEntity) iterator2.next(); + while (tileEntitiesIterator.hasNext()) { + TileEntity tileentity = tileEntitiesIterator.next(); this.a(tileentity); } - iterator2 = arraylist.iterator(); + // //Nacho - if there are a lot of entities, we end up scanning the WHOLE list of entities multiple times +// // Which isn't the best if we have 100 players doing that + // So instead of updating all entities by chunk, we update all entities at once with a hashset of chunks + // This means we don't have to pass over the list x chunks + // o(chunk * entityList) => o(entitylist) - while (iterator2.hasNext()) { - chunk = (Chunk) iterator2.next(); - this.u().getTracker().a(this, chunk); +// Iterator chunkIterator = chunkList.iterator(); +// while (chunkIterator.hasNext()) +// { +// chunk = (Chunk) chunkIterator.next(); +// this.u().getTracker().a(this, chunk); +// } +// Nacho - end + + LongOpenHashSet chunkPosSet = new LongOpenHashSet(chunkList.size()); + for (Chunk newChunk : chunkList) + chunkPosSet.add(this.chunkToLong(newChunk.locX, newChunk.locZ)); + + Iterator trackerEntryIterator = this.u().getTracker().getEntityTrackerEntries(); + while (trackerEntryIterator.hasNext()) + { + EntityTrackerEntry entitytrackerentry = trackerEntryIterator.next(); + + if (entitytrackerentry.tracker != this && chunkPosSet.contains(this.chunkToLong(entitytrackerentry.tracker.ae, entitytrackerentry.tracker.ag))) + { + entitytrackerentry.updatePlayer(this); + } } } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java index ce4a98c..b1636ab 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; +import com.elevatemc.spigot.util.Constants; import org.bukkit.craftbukkit.entity.CraftPlayer; import java.util.List; @@ -207,7 +209,7 @@ public abstract class EntityProjectile extends Entity implements IProjectile { for (int j = 0; j < 4; ++j) { float f4 = 0.25F; - this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX - this.motX * (double) f4, this.locY - this.motY * (double) f4, this.locZ - this.motZ * (double) f4, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX - this.motX * (double) f4, this.locY - this.motY * (double) f4, this.locZ - this.motZ * (double) f4, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } f2 = 0.8F; @@ -268,7 +270,7 @@ public abstract class EntityProjectile extends Entity implements IProjectile { this.shooter = this.world.a(this.shooterName); if (this.shooter == null && this.world instanceof WorldServer) { try { - Entity entity = ((WorldServer) this.world).getEntity(UUID.fromString(this.shooterName)); + Entity entity = ((WorldServer) this.world).getEntity(FastUUID.parseUUID(this.shooterName)); if (entity instanceof EntityLiving) { this.shooter = (EntityLiving) entity; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntitySlime.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntitySlime.java index aee272e..6e69c83 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntitySlime.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntitySlime.java @@ -1,6 +1,7 @@ package net.minecraft.server; // CraftBukkit start +import com.elevatemc.spigot.util.Constants; import org.bukkit.event.entity.SlimeSplitEvent; // CraftBukkit end @@ -88,7 +89,7 @@ public class EntitySlime extends EntityInsentient implements IMonster { double d0 = this.locX + (double) f2; double d1 = this.locZ + (double) f3; - world.addParticle(enumparticle, d0, this.getBoundingBox().b, d1, 0.0D, 0.0D, 0.0D, new int[0]); + world.addParticle(enumparticle, d0, this.getBoundingBox().b, d1, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } if (this.cl()) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntitySnowball.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntitySnowball.java index dade83b..5e6e81d 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntitySnowball.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntitySnowball.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public class EntitySnowball extends EntityProjectile { public EntitySnowball(World world) { @@ -26,7 +28,7 @@ public class EntitySnowball extends EntityProjectile { } for (int i = 0; i < 8; ++i) { - this.world.addParticle(EnumParticle.SNOWBALL, this.locX, this.locY, this.locZ, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.SNOWBALL, this.locX, this.locY, this.locZ, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } if (!this.world.isClientSide) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityTNTPrimed.java index 4874dbc..4b82987 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityTNTPrimed.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityTNTPrimed.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit public class EntityTNTPrimed extends Entity { @@ -90,7 +91,7 @@ public class EntityTNTPrimed extends Entity { // CraftBukkit end } else { this.W(); - this.world.addParticle(EnumParticle.SMOKE_NORMAL, this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.SMOKE_NORMAL, this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityTameableAnimal.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityTameableAnimal.java index 1cc087d..15b4598 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityTameableAnimal.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityTameableAnimal.java @@ -1,5 +1,8 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; +import com.elevatemc.spigot.util.Constants; + import java.util.UUID; public abstract class EntityTameableAnimal extends EntityAnimal implements EntityOwnable { @@ -61,7 +64,7 @@ public abstract class EntityTameableAnimal extends EntityAnimal implements Entit double d1 = this.random.nextGaussian() * 0.02D; double d2 = this.random.nextGaussian() * 0.02D; - this.world.addParticle(enumparticle, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2, new int[0]); + this.world.addParticle(enumparticle, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2, Constants.EMPTY_ARRAY); } } @@ -109,7 +112,7 @@ public abstract class EntityTameableAnimal extends EntityAnimal implements Entit public EntityLiving getOwner() { try { - UUID uuid = UUID.fromString(this.getOwnerUUID()); + UUID uuid = FastUUID.parseUUID(this.getOwnerUUID()); return uuid == null ? null : this.world.b(uuid); } catch (IllegalArgumentException illegalargumentexception) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityTracker.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityTracker.java index ef704e7..95bb657 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityTracker.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityTracker.java @@ -3,6 +3,7 @@ package net.minecraft.server; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.Callable; @@ -265,6 +266,11 @@ public class EntityTracker { else TASK_EXECUTOR.submit(task); } + public Iterator getEntityTrackerEntries() + { + return this.c.iterator(); + } + public void a(EntityPlayer entityplayer, Chunk chunk) { Task task = executor -> { for (EntityTrackerEntry entitytrackerentry : this.c) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityTrackerEntry.java index 89d69de..1073364 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityTrackerEntry.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityTrackerEntry.java @@ -3,7 +3,7 @@ package net.minecraft.server; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import com.elevatemc.spigot.eSpigotFeature; +import com.elevatemc.spigot.config.eSpigotConfig; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -273,7 +273,7 @@ public class EntityTrackerEntry { DataWatcher datawatcher = this.tracker.getDataWatcher(); if (datawatcher.a()) { - if (eSpigotFeature.OBFUSCATE_HEALTH.isEnabled() && this.tracker instanceof EntityHuman) { + if (eSpigotConfig.obfuscatePlayerHealth && this.tracker instanceof EntityHuman) { List changedMetadata = datawatcher.c(); Iterator iter = changedMetadata.iterator(); boolean found = false; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityWitch.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityWitch.java index d59d779..2824a1e 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityWitch.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityWitch.java @@ -1,12 +1,14 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; + import java.util.Iterator; import java.util.List; import java.util.UUID; public class EntityWitch extends EntityMonster implements IRangedEntity { - private static final UUID a = UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E"); + private static final UUID a = FastUUID.parseUUID("5CD17E52-A79A-43D3-A529-90FDE04B181E"); private static final AttributeModifier b = (new AttributeModifier(EntityWitch.a, "Drinking speed penalty", -0.25D, 0)).a(false); private static final Item[] c = new Item[] { Items.GLOWSTONE_DUST, Items.SUGAR, Items.REDSTONE, Items.SPIDER_EYE, Items.GLASS_BOTTLE, Items.GUNPOWDER, Items.STICK, Items.STICK}; private int bm; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityWither.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityWither.java index d8e3b65..a5c9dea 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityWither.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityWither.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import java.util.Iterator; @@ -154,15 +155,15 @@ public class EntityWither extends EntityMonster implements IRangedEntity { double d9 = this.u(j); double d10 = this.v(j); - this.world.addParticle(EnumParticle.SMOKE_NORMAL, d8 + this.random.nextGaussian() * 0.30000001192092896D, d9 + this.random.nextGaussian() * 0.30000001192092896D, d10 + this.random.nextGaussian() * 0.30000001192092896D, 0.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.SMOKE_NORMAL, d8 + this.random.nextGaussian() * 0.30000001192092896D, d9 + this.random.nextGaussian() * 0.30000001192092896D, d10 + this.random.nextGaussian() * 0.30000001192092896D, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); if (flag && this.world.random.nextInt(4) == 0) { - this.world.addParticle(EnumParticle.SPELL_MOB, d8 + this.random.nextGaussian() * 0.30000001192092896D, d9 + this.random.nextGaussian() * 0.30000001192092896D, d10 + this.random.nextGaussian() * 0.30000001192092896D, 0.699999988079071D, 0.699999988079071D, 0.5D, new int[0]); + this.world.addParticle(EnumParticle.SPELL_MOB, d8 + this.random.nextGaussian() * 0.30000001192092896D, d9 + this.random.nextGaussian() * 0.30000001192092896D, d10 + this.random.nextGaussian() * 0.30000001192092896D, 0.699999988079071D, 0.699999988079071D, 0.5D, Constants.EMPTY_ARRAY); } } if (this.cl() > 0) { for (j = 0; j < 3; ++j) { - this.world.addParticle(EnumParticle.SPELL_MOB, this.locX + this.random.nextGaussian() * 1.0D, this.locY + (double) (this.random.nextFloat() * 3.3F), this.locZ + this.random.nextGaussian() * 1.0D, 0.699999988079071D, 0.699999988079071D, 0.8999999761581421D, new int[0]); + this.world.addParticle(EnumParticle.SPELL_MOB, this.locX + this.random.nextGaussian() * 1.0D, this.locY + (double) (this.random.nextFloat() * 3.3F), this.locZ + this.random.nextGaussian() * 1.0D, 0.699999988079071D, 0.699999988079071D, 0.8999999761581421D, Constants.EMPTY_ARRAY); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityWolf.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityWolf.java index ae0a219..7fe0268 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityWolf.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityWolf.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.google.common.base.Predicate; // CraftBukkit start @@ -183,7 +184,7 @@ public class EntityWolf extends EntityTameableAnimal { float f1 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; float f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; - this.world.addParticle(EnumParticle.WATER_SPLASH, this.locX + (double) f1, f + 0.8F, this.locZ + (double) f2, this.motX, this.motY, this.motZ, new int[0]); + this.world.addParticle(EnumParticle.WATER_SPLASH, this.locX + (double) f1, f + 0.8F, this.locZ + (double) f2, this.motX, this.motY, this.motZ, Constants.EMPTY_ARRAY); } } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EntityZombie.java b/eSpigot-Server/src/main/java/net/minecraft/server/EntityZombie.java index a7daf95..a05bec1 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EntityZombie.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EntityZombie.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.UUID; //CraftBukkit start +import com.eatthepath.uuid.FastUUID; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityCombustByEntityEvent; import org.bukkit.event.entity.EntityCombustEvent; @@ -14,7 +15,7 @@ import org.bukkit.event.entity.EntityTargetEvent; public class EntityZombie extends EntityMonster { protected static final IAttribute a = (new AttributeRanged(null, "zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).a("Spawn Reinforcements Chance"); - private static final UUID b = UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836"); + private static final UUID b = FastUUID.parseUUID("B9766B59-9566-4402-BC1F-2EE2A276D836"); private static final AttributeModifier c = new AttributeModifier(EntityZombie.b, "Baby speed boost", org.github.paperspigot.PaperSpigotConfig.babyZombieMovementSpeed, 1); // PaperSpigot - Configurable baby zombie movement speed private final PathfinderGoalBreakDoor bm = new PathfinderGoalBreakDoor(this); private int bn; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/EnumDirection.java b/eSpigot-Server/src/main/java/net/minecraft/server/EnumDirection.java index 938769b..496b1aa 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/EnumDirection.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/EnumDirection.java @@ -20,9 +20,10 @@ public enum EnumDirection implements INamable { private final BaseBlockPosition m; private static final EnumDirection[] n = new EnumDirection[6]; private static final EnumDirection[] o = new EnumDirection[4]; + private static final EnumDirection[] ALL = EnumDirection.values(); private static final Map p = Maps.newHashMap(); - private EnumDirection(int i, int j, int k, String s, EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection, EnumDirection.EnumAxis enumdirection_enumaxis, BaseBlockPosition baseblockposition) { + EnumDirection(int i, int j, int k, String s, EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection, EnumDirection.EnumAxis enumdirection_enumaxis, BaseBlockPosition baseblockposition) { this.g = i; this.i = k; this.h = j; @@ -45,42 +46,34 @@ public enum EnumDirection implements INamable { } public EnumDirection opposite() { - return fromType1(this.h); + return ALL[this.h]; } public EnumDirection e() { - switch (EnumDirection.SyntheticClass_1.b[this.ordinal()]) { - case 1: - return EnumDirection.EAST; - - case 2: - return EnumDirection.SOUTH; - - case 3: - return EnumDirection.WEST; - - case 4: - return EnumDirection.NORTH; - + switch(this) { + case NORTH: + return EAST; + case EAST: + return SOUTH; + case SOUTH: + return WEST; + case WEST: + return NORTH; default: throw new IllegalStateException("Unable to get Y-rotated facing of " + this); } } public EnumDirection f() { - switch (EnumDirection.SyntheticClass_1.b[this.ordinal()]) { - case 1: - return EnumDirection.WEST; - - case 2: - return EnumDirection.NORTH; - - case 3: - return EnumDirection.EAST; - - case 4: - return EnumDirection.SOUTH; - + switch(this) { + case NORTH: + return WEST; + case EAST: + return NORTH; + case SOUTH: + return EAST; + case WEST: + return SOUTH; default: throw new IllegalStateException("Unable to get CCW facing of " + this); } @@ -119,7 +112,7 @@ public enum EnumDirection implements INamable { } public static EnumDirection a(Random random) { - return values()[random.nextInt(values().length)]; + return ALL[random.nextInt(ALL.length)]; } public String toString() { @@ -131,11 +124,10 @@ public enum EnumDirection implements INamable { } public static EnumDirection a(EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection, EnumDirection.EnumAxis enumdirection_enumaxis) { - EnumDirection[] aenumdirection = values(); - int i = aenumdirection.length; + int i = ALL.length; for (int j = 0; j < i; ++j) { - EnumDirection enumdirection = aenumdirection[j]; + EnumDirection enumdirection = ALL[j]; if (enumdirection.c() == enumdirection_enumaxisdirection && enumdirection.k() == enumdirection_enumaxis) { return enumdirection; @@ -146,11 +138,10 @@ public enum EnumDirection implements INamable { } static { - EnumDirection[] aenumdirection = values(); - int i = aenumdirection.length; + int i = ALL.length; for (int j = 0; j < i; ++j) { - EnumDirection enumdirection = aenumdirection[j]; + EnumDirection enumdirection = ALL[j]; EnumDirection.n[enumdirection.g] = enumdirection; if (enumdirection.k().c()) { @@ -162,102 +153,20 @@ public enum EnumDirection implements INamable { } - static class SyntheticClass_1 { - - static final int[] a; - static final int[] b; - static final int[] c = new int[EnumDirection.EnumDirectionLimit.values().length]; - - static { - try { - EnumDirection.SyntheticClass_1.c[EnumDirection.EnumDirectionLimit.HORIZONTAL.ordinal()] = 1; - } catch (NoSuchFieldError nosuchfielderror) { - ; - } - - try { - EnumDirection.SyntheticClass_1.c[EnumDirection.EnumDirectionLimit.VERTICAL.ordinal()] = 2; - } catch (NoSuchFieldError nosuchfielderror1) { - ; - } - - b = new int[EnumDirection.values().length]; - - try { - EnumDirection.SyntheticClass_1.b[EnumDirection.NORTH.ordinal()] = 1; - } catch (NoSuchFieldError nosuchfielderror2) { - ; - } - - try { - EnumDirection.SyntheticClass_1.b[EnumDirection.EAST.ordinal()] = 2; - } catch (NoSuchFieldError nosuchfielderror3) { - ; - } - - try { - EnumDirection.SyntheticClass_1.b[EnumDirection.SOUTH.ordinal()] = 3; - } catch (NoSuchFieldError nosuchfielderror4) { - ; - } - - try { - EnumDirection.SyntheticClass_1.b[EnumDirection.WEST.ordinal()] = 4; - } catch (NoSuchFieldError nosuchfielderror5) { - ; - } - - try { - EnumDirection.SyntheticClass_1.b[EnumDirection.UP.ordinal()] = 5; - } catch (NoSuchFieldError nosuchfielderror6) { - ; - } - - try { - EnumDirection.SyntheticClass_1.b[EnumDirection.DOWN.ordinal()] = 6; - } catch (NoSuchFieldError nosuchfielderror7) { - ; - } - - a = new int[EnumDirection.EnumAxis.values().length]; - - try { - EnumDirection.SyntheticClass_1.a[EnumDirection.EnumAxis.X.ordinal()] = 1; - } catch (NoSuchFieldError nosuchfielderror8) { - ; - } - - try { - EnumDirection.SyntheticClass_1.a[EnumDirection.EnumAxis.Y.ordinal()] = 2; - } catch (NoSuchFieldError nosuchfielderror9) { - ; - } - - try { - EnumDirection.SyntheticClass_1.a[EnumDirection.EnumAxis.Z.ordinal()] = 3; - } catch (NoSuchFieldError nosuchfielderror10) { - ; - } - - } - } - - public static enum EnumDirectionLimit implements Predicate, Iterable { + public enum EnumDirectionLimit implements Predicate, Iterable { HORIZONTAL, VERTICAL; - private EnumDirectionLimit() {} + EnumDirectionLimit() {} public EnumDirection[] a() { - switch (EnumDirection.SyntheticClass_1.c[this.ordinal()]) { - case 1: - return new EnumDirection[] { EnumDirection.NORTH, EnumDirection.EAST, EnumDirection.SOUTH, EnumDirection.WEST}; - - case 2: - return new EnumDirection[] { EnumDirection.UP, EnumDirection.DOWN}; - + switch(this) { + case HORIZONTAL: + return new EnumDirection[]{EnumDirection.NORTH, EnumDirection.EAST, EnumDirection.SOUTH, EnumDirection.WEST}; + case VERTICAL: + return new EnumDirection[]{EnumDirection.UP, EnumDirection.DOWN}; default: - throw new Error("Someone\'s been tampering with the universe!"); + throw new Error("Someone's been tampering with the universe!"); } } @@ -280,7 +189,7 @@ public enum EnumDirection implements INamable { } } - public static enum EnumAxisDirection { + public enum EnumAxisDirection { POSITIVE(1, "Towards positive"), NEGATIVE(-1, "Towards negative"); @@ -301,7 +210,7 @@ public enum EnumDirection implements INamable { } } - public static enum EnumAxis implements Predicate, INamable { + public enum EnumAxis implements Predicate, INamable { X("x", EnumDirection.EnumDirectionLimit.HORIZONTAL), Y("y", EnumDirection.EnumDirectionLimit.VERTICAL), Z("z", EnumDirection.EnumDirectionLimit.HORIZONTAL); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/Explosion.java b/eSpigot-Server/src/main/java/net/minecraft/server/Explosion.java index 3c891d9..7608b5b 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/Explosion.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/Explosion.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.elevatemc.spigot.util.FastRandom; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -58,7 +59,7 @@ public class Explosion { Block b = world.getChunkAt((int)posX >> 4, (int)posZ >> 4).getBlockData(new BlockPosition(posX, posY, posZ)).getBlock(); // TacoSpigot - get block of the explosion - if (!this.world.tacoSpigotConfig.optimizeLiquidExplosions || !b.getMaterial().isLiquid()) { //TacoSpigot - skip calculating what blocks to blow up in water/lava + if (!this.world.paperSpigotConfig.optimizeLiquidExplosions || !b.getMaterial().isLiquid()) { //TacoSpigot - skip calculating what blocks to blow up in water/lava for (int k = 0; k < 16; ++k) { for (i = 0; i < 16; ++i) { for (j = 0; j < 16; ++j) { @@ -170,9 +171,9 @@ public class Explosion { this.world.makeSound(this.posX, this.posY, this.posZ, "random.explode", volume, (1.0F + (this.world.random.nextFloat() - this.world.random.nextFloat()) * 0.2F) * 0.7F); // PaperSpigot end if (this.size >= 2.0F && this.b) { - this.world.addParticle(EnumParticle.EXPLOSION_HUGE, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.EXPLOSION_HUGE, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } else { - this.world.addParticle(EnumParticle.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D, new int[0]); + this.world.addParticle(EnumParticle.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } Iterator iterator; @@ -248,8 +249,8 @@ public class Explosion { d3 *= d7; d4 *= d7; d5 *= d7; - this.world.addParticle(EnumParticle.EXPLOSION_NORMAL, (d0 + this.posX * 1.0D) / 2.0D, (d1 + this.posY * 1.0D) / 2.0D, (d2 + this.posZ * 1.0D) / 2.0D, d3, d4, d5, new int[0]); - this.world.addParticle(EnumParticle.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5, new int[0]); + this.world.addParticle(EnumParticle.EXPLOSION_NORMAL, (d0 + this.posX * 1.0D) / 2.0D, (d1 + this.posY * 1.0D) / 2.0D, (d2 + this.posZ * 1.0D) / 2.0D, d3, d4, d5, Constants.EMPTY_ARRAY); + this.world.addParticle(EnumParticle.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5, Constants.EMPTY_ARRAY); } if (block.getMaterial() != Material.AIR) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/GameProfileBanEntry.java b/eSpigot-Server/src/main/java/net/minecraft/server/GameProfileBanEntry.java index daa1bc3..0ebab11 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/GameProfileBanEntry.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/GameProfileBanEntry.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; import java.util.Date; @@ -36,7 +37,7 @@ public class GameProfileBanEntry extends ExpirableListEntry { String s = jsonobject.get("uuid").getAsString(); try { - uuid = UUID.fromString(s); + uuid = FastUUID.parseUUID(s); } catch (Throwable ignored) { } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/GameProfileSerializer.java b/eSpigot-Server/src/main/java/net/minecraft/server/GameProfileSerializer.java index 998cf70..d8d084f 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/GameProfileSerializer.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/GameProfileSerializer.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import java.util.Iterator; @@ -25,7 +26,7 @@ public final class GameProfileSerializer { UUID uuid; try { - uuid = UUID.fromString(s1); + uuid = FastUUID.parseUUID(s1); } catch (Throwable throwable) { uuid = null; } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/Item.java b/eSpigot-Server/src/main/java/net/minecraft/server/Item.java index 87a2d7b..d5d93e9 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/Item.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/Item.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.common.base.Function; import com.google.common.collect.HashMultimap; import com.google.common.collect.Maps; @@ -12,7 +13,7 @@ public class Item { public static final RegistryMaterials REGISTRY = new RegistryMaterials(); private static final Map a = Maps.newHashMap(); - protected static final UUID f = UUID.fromString("CB3F55D3-645C-4F38-A497-9C13A33DB5CF"); + protected static final UUID f = FastUUID.parseUUID("CB3F55D3-645C-4F38-A497-9C13A33DB5CF"); private CreativeModeTab b; protected static Random g = new Random(); protected int maxStackSize = 64; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/ItemBucket.java b/eSpigot-Server/src/main/java/net/minecraft/server/ItemBucket.java index 080d79c..1f0f3fe 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/ItemBucket.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/ItemBucket.java @@ -1,6 +1,7 @@ package net.minecraft.server; // CraftBukkit start +import com.elevatemc.spigot.util.Constants; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.event.player.PlayerBucketEmptyEvent; @@ -154,7 +155,7 @@ public class ItemBucket extends Item { world.makeSound((float) i + 0.5F, (float) j + 0.5F, (float) k + 0.5F, "random.fizz", 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); for (int l = 0; l < 8; ++l) { - world.addParticle(EnumParticle.SMOKE_LARGE, (double) i + Math.random(), (double) j + Math.random(), (double) k + Math.random(), 0.0D, 0.0D, 0.0D, new int[0]); + world.addParticle(EnumParticle.SMOKE_LARGE, (double) i + Math.random(), (double) j + Math.random(), (double) k + Math.random(), 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); } } else { if (!world.isClientSide && flag && !material.isLiquid()) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/ItemEnderEye.java b/eSpigot-Server/src/main/java/net/minecraft/server/ItemEnderEye.java index 8c000a1..4c4571c 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/ItemEnderEye.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/ItemEnderEye.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + public class ItemEnderEye extends Item { public ItemEnderEye() { @@ -25,7 +27,7 @@ public class ItemEnderEye extends Item { double d4 = 0.0D; double d5 = 0.0D; - world.addParticle(EnumParticle.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5, new int[0]); + world.addParticle(EnumParticle.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5, Constants.EMPTY_ARRAY); } EnumDirection enumdirection1 = (EnumDirection) iblockdata.get(BlockEnderPortalFrame.FACING); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/MinecraftServer.java b/eSpigot-Server/src/main/java/net/minecraft/server/MinecraftServer.java index 27bf1e1..088ab6c 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/MinecraftServer.java @@ -16,6 +16,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; import io.netty.handler.codec.base64.Base64; +import io.netty.util.ResourceLeakDetector; import joptsimple.OptionSet; import com.elevatemc.spigot.eSpigot; import net.minecrell.terminalconsole.TerminalConsoleAppender; @@ -176,7 +177,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs private final ThreadingManager threadingManager; public MinecraftServer(OptionSet options, Proxy proxy, File file1) { - io.netty.util.ResourceLeakDetector.setEnabled(false); // Spigot - disable + io.netty.util.ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED); // [Nacho-0040] Change deprecated Netty parameter // Spigot - disable this.e = proxy; this.threadingManager = new ThreadingManager(); MinecraftServer.l = this; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/MobEffectList.java b/eSpigot-Server/src/main/java/net/minecraft/server/MobEffectList.java index 64ed4e3..7aa27b3 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/MobEffectList.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/MobEffectList.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.common.collect.Maps; import java.util.Iterator; import java.util.Map; @@ -194,7 +195,7 @@ public class MobEffectList { } public MobEffectList a(IAttribute iattribute, String s, double d0, int i) { - AttributeModifier attributemodifier = new AttributeModifier(UUID.fromString(s), this.a(), d0, i); + AttributeModifier attributemodifier = new AttributeModifier(FastUUID.parseUUID(s), this.a(), d0, i); this.J.put(iattribute, attributemodifier); return this; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/eSpigot-Server/src/main/java/net/minecraft/server/MobSpawnerAbstract.java index 3774b3a..90dd3b4 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/MobSpawnerAbstract.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/MobSpawnerAbstract.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.google.common.collect.Lists; import java.util.Iterator; import java.util.List; @@ -75,8 +76,8 @@ public abstract class MobSpawnerAbstract { double d2 = (float) blockposition.getY() + this.a().random.nextFloat(); d0 = (float) blockposition.getZ() + this.a().random.nextFloat(); - this.a().addParticle(EnumParticle.SMOKE_NORMAL, d1, d2, d0, 0.0D, 0.0D, 0.0D, new int[0]); - this.a().addParticle(EnumParticle.FLAME, d1, d2, d0, 0.0D, 0.0D, 0.0D, new int[0]); + this.a().addParticle(EnumParticle.SMOKE_NORMAL, d1, d2, d0, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); + this.a().addParticle(EnumParticle.FLAME, d1, d2, d0, 0.0D, 0.0D, 0.0D, Constants.EMPTY_ARRAY); if (this.spawnDelay > 0) { this.spawnDelay -= tickDelay; // PaperSpigot } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/NBTTagCompound.java b/eSpigot-Server/src/main/java/net/minecraft/server/NBTTagCompound.java index 7239bf2..0b59e4a 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/NBTTagCompound.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/NBTTagCompound.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; @@ -201,7 +203,7 @@ public class NBTTagCompound extends NBTBase { public int[] getIntArray(String s) { try { - return !this.hasKeyOfType(s, 11) ? new int[0] : ((NBTTagIntArray) this.map.get(s)).c(); + return !this.hasKeyOfType(s, 11) ? Constants.EMPTY_ARRAY : ((NBTTagIntArray) this.map.get(s)).c(); } catch (ClassCastException classcastexception) { throw new ReportedException(this.a(s, 11, classcastexception)); } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/NBTTagList.java b/eSpigot-Server/src/main/java/net/minecraft/server/NBTTagList.java index 45ea25d..9ae5401 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/NBTTagList.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/NBTTagList.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; import com.google.common.collect.Lists; import java.io.DataInput; import java.io.DataOutput; @@ -131,9 +132,9 @@ public class NBTTagList extends NBTBase { if (i >= 0 && i < this.list.size()) { NBTBase nbtbase = this.list.get(i); - return nbtbase.getTypeId() == 11 ? ((NBTTagIntArray) nbtbase).c() : new int[0]; + return nbtbase.getTypeId() == 11 ? ((NBTTagIntArray) nbtbase).c() : Constants.EMPTY_ARRAY; } else { - return new int[0]; + return Constants.EMPTY_ARRAY; } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/NameReferencingFileConverter.java b/eSpigot-Server/src/main/java/net/minecraft/server/NameReferencingFileConverter.java index 959b895..cdd63db 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/NameReferencingFileConverter.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/NameReferencingFileConverter.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.common.base.Charsets; import com.google.common.base.Predicate; import com.google.common.collect.Iterators; @@ -330,7 +331,7 @@ public class NameReferencingFileConverter { if (uuid == null) { throw new NameReferencingFileConverter.FileConversionException("Missing UUID for user profile " + gameprofile.getName(), null); } else { - this.a(file, this.a(gameprofile), uuid.toString()); + this.a(file, this.a(gameprofile), FastUUID.toString(uuid)); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/NetworkManager.java b/eSpigot-Server/src/main/java/net/minecraft/server/NetworkManager.java index 468734c..478fbc6 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/NetworkManager.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/NetworkManager.java @@ -126,16 +126,6 @@ public class NetworkManager extends SimpleChannelInboundHandler { super.channelActive(channelhandlercontext); this.channel = channelhandlercontext.channel(); this.l = this.channel.remoteAddress(); - // eSpigot start - ChannelConfig config = this.channel.config(); - config.setOption(ChannelOption.SO_KEEPALIVE, true); - config.setOption(ChannelOption.TCP_NODELAY, true); - config.setOption(ChannelOption.TCP_FASTOPEN, 1); - config.setOption(ChannelOption.TCP_FASTOPEN_CONNECT, true); - config.setOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); - config.setOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(8 * 1024, 32 * 1024)); - config.setOption(ChannelOption.IP_TOS, 0x18); - // eSpigot end // Spigot Start this.preparing = false; diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/OpListEntry.java b/eSpigot-Server/src/main/java/net/minecraft/server/OpListEntry.java index 6fb9fef..e339110 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/OpListEntry.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/OpListEntry.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; import java.util.UUID; @@ -46,7 +47,7 @@ public class OpListEntry extends JsonListEntry { UUID uuid; try { - uuid = UUID.fromString(s); + uuid = FastUUID.parseUUID(s); } catch (Throwable throwable) { return null; } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/PacketLoginOutSuccess.java b/eSpigot-Server/src/main/java/net/minecraft/server/PacketLoginOutSuccess.java index c811dd6..9dcc9aa 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/PacketLoginOutSuccess.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/PacketLoginOutSuccess.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.mojang.authlib.GameProfile; import java.io.IOException; import java.util.UUID; @@ -17,7 +18,7 @@ public class PacketLoginOutSuccess implements Packet { public void a(PacketDataSerializer packetdataserializer) throws IOException { String s = packetdataserializer.c(36); String s1 = packetdataserializer.c(16); - UUID uuid = UUID.fromString(s); + UUID uuid = FastUUID.parseUUID(s); this.a = new GameProfile(uuid, s1); } @@ -25,7 +26,7 @@ public class PacketLoginOutSuccess implements Packet { public void b(PacketDataSerializer packetdataserializer) throws IOException { UUID uuid = this.a.getId(); - packetdataserializer.a(uuid == null ? "" : uuid.toString()); + packetdataserializer.a(uuid == null ? "" : FastUUID.toString(uuid)); packetdataserializer.a(this.a.getName()); } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java b/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java index 4dfb6c0..993d853 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java @@ -14,6 +14,10 @@ public class PacketPlayInCloseWindow implements Packet { } // CraftBukkit end + public int getId() { + return id; + } + public void a(PacketListenerPlayIn packetlistenerplayin) { packetlistenerplayin.a(this); } @@ -26,3 +30,4 @@ public class PacketPlayInCloseWindow implements Packet { packetdataserializer.writeByte(this.id); } } + diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java index 4336f65..f5c97c1 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java @@ -19,7 +19,7 @@ public class PacketPlayOutMapChunk implements Packet { this.b = chunk.locZ; this.d = flag; this.c = chunk.getChunkMap(flag, i); // PaperSpigot - chunk.world.spigotConfig.antiXrayInstance.obfuscateSync(chunk.locX, chunk.locZ, c.b, c.a, chunk.world); + chunk.world.spigotConfig.antiXrayInstance.obfuscate(chunk.locX, chunk.locZ, c.b, c.a, chunk.world); } public void a(PacketDataSerializer packetdataserializer) throws IOException { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java b/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java index 8227519..e276fd6 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java @@ -23,11 +23,11 @@ public class PacketPlayOutMapChunkBulk implements Packet for (int j = 0; j < i; ++j) { Chunk chunk = list.get(j); - PacketPlayOutMapChunk.ChunkMap packetplayoutmapchunk_chunkmap = chunk.getChunkMap(true, '\uffff'); // PaperSpigot + PacketPlayOutMapChunk.ChunkMap map = chunk.getChunkMap(true, '\uffff'); // PaperSpigot this.a[j] = chunk.locX; this.b[j] = chunk.locZ; - this.c[j] = packetplayoutmapchunk_chunkmap; + this.c[j] = map; } world = list.get(0).getWorld(); // Spigot diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreed.java b/eSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreed.java index 897696f..4d7fa9e 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreed.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreed.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.util.Constants; + import java.util.Iterator; import java.util.List; import java.util.Random; @@ -104,7 +106,7 @@ public class PathfinderGoalBreed extends PathfinderGoal { double d4 = 0.5D + random.nextDouble() * (double) this.d.length; double d5 = random.nextDouble() * (double) this.d.width * 2.0D - (double) this.d.width; - this.a.addParticle(EnumParticle.HEART, this.d.locX + d3, this.d.locY + d4, this.d.locZ + d5, d0, d1, d2, new int[0]); + this.a.addParticle(EnumParticle.HEART, this.d.locX + d3, this.d.locY + d4, this.d.locZ + d5, d0, d1, d2, Constants.EMPTY_ARRAY); } if (this.a.getGameRules().getBoolean("doMobLoot")) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/PlayerConnection.java b/eSpigot-Server/src/main/java/net/minecraft/server/PlayerConnection.java index 703f6ed..fc2dfdc 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/PlayerConnection.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.config.eSpigotConfig; import com.elevatemc.spigot.eSpigot; import com.elevatemc.spigot.handler.MovementHandler; import com.elevatemc.spigot.handler.PacketHandler; @@ -67,7 +68,6 @@ import co.aikar.timings.SpigotTimings; // Spigot // CraftBukkit end import org.github.paperspigot.PaperSpigotConfig; // PaperSpigot -import com.elevatemc.spigot.eSpigotFeature; public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerListBox { @@ -636,7 +636,7 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList return; case 3: // RELEASE_USE_ITEM - if (eSpigotFeature.FIX_SPRINT_EAT_EXPLOIT.isEnabled()) + if (eSpigotConfig.fixSprintEatExploit) this.player.bU(); // eSpigot - Patch eat while running glitch this.player.setSprinting(true); @@ -1541,9 +1541,11 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList if (this.player.dead) return; // CraftBukkit PlayerConnectionUtils.ensureMainThread(packetplayinclosewindow, this, this.player.u()); - CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit - - this.player.p(); + // Nacho: only fire InventoryCloseEvent if inventory is open + if (packetplayinclosewindow.getId() == player.activeContainer.windowId) { + CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit + this.player.p(); + } } public void a(PacketPlayInWindowClick packetplayinwindowclick) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/PlayerList.java b/eSpigot-Server/src/main/java/net/minecraft/server/PlayerList.java index 39f90e3..dbfaee6 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/PlayerList.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/PlayerList.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; +import com.elevatemc.spigot.config.eSpigotConfig; import com.elevatemc.spigot.console.PandaConsoleCommandSender; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -9,14 +11,8 @@ import io.netty.buffer.Unpooled; import java.io.File; import java.net.SocketAddress; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; -import com.elevatemc.spigot.eSpigotFeature; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -57,6 +53,7 @@ public abstract class PlayerList { private final GameProfileBanList k; private final IpBanList l; private final OpList operators; + private Set fastOperator = new HashSet<>(); private final WhiteList whitelist; private final Map o; public IPlayerFileData playerFileData; @@ -79,6 +76,9 @@ public abstract class PlayerList { this.k = new GameProfileBanList(PlayerList.a); this.l = new IpBanList(PlayerList.b); this.operators = new OpList(PlayerList.c); + for (OpListEntry value : this.operators.getValues()) { + this.fastOperator.add(value.getKey().getId()); + } this.whitelist = new WhiteList(PlayerList.d); this.o = Maps.newHashMap(); this.server = minecraftserver; @@ -328,11 +328,11 @@ public abstract class PlayerList { for (EntityPlayer player : this.players) { EntityPlayer entityplayer1 = player; - if (eSpigotFeature.SHOW_HIDDEN_PLAYERS_IN_TAB.isEnabled() || entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { + if (eSpigotConfig.showHiddenPlayersInTab || entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { entityplayer1.playerConnection.sendPacket(packet); } - if (!entityplayer.getBukkitEntity().canSee(entityplayer1.getBukkitEntity()) && !eSpigotFeature.SHOW_HIDDEN_PLAYERS_IN_TAB.isEnabled()) { + if (!entityplayer.getBukkitEntity().canSee(entityplayer1.getBukkitEntity()) && !eSpigotConfig.showHiddenPlayersInTab) { continue; } @@ -1020,6 +1020,7 @@ public abstract class PlayerList { public void addOp(GameProfile gameprofile) { this.operators.add(new OpListEntry(gameprofile, this.server.p(), this.operators.b(gameprofile))); + this.fastOperator.add(gameprofile.getId()); // CraftBukkit start Player player = server.server.getPlayer(gameprofile.getId()); @@ -1031,6 +1032,7 @@ public abstract class PlayerList { public void removeOp(GameProfile gameprofile) { this.operators.remove(gameprofile); + this.fastOperator.remove(gameprofile.getId()); // CraftBukkit start Player player = server.server.getPlayer(gameprofile.getId()); @@ -1041,11 +1043,11 @@ public abstract class PlayerList { } public boolean isWhitelisted(GameProfile gameprofile) { - return !this.hasWhitelist || this.operators.d(gameprofile) || this.whitelist.d(gameprofile); + return !this.hasWhitelist || this.fastOperator.contains(gameprofile.getId()) || this.whitelist.d(gameprofile); } public boolean isOp(GameProfile gameprofile) { - return this.operators.d(gameprofile) || this.server.T() && this.server.worlds.get(0).getWorldData().v() && this.server.S().equalsIgnoreCase(gameprofile.getName()) || this.t; // CraftBukkit + return this.fastOperator.contains(gameprofile.getId()) || this.server.T() && this.server.worlds.get(0).getWorldData().v() && this.server.S().equalsIgnoreCase(gameprofile.getName()) || this.t; // CraftBukkit } public EntityPlayer getPlayer(String s) { @@ -1057,6 +1059,7 @@ public abstract class PlayerList { } public void sendPacketNearby(EntityHuman entityhuman, double d0, double d1, double d2, double d3, int i, Packet packet) { + double squared = d3 * d3; for (EntityPlayer player : this.players) { EntityPlayer entityplayer = player; @@ -1071,7 +1074,7 @@ public abstract class PlayerList { double d5 = d1 - entityplayer.locY; double d6 = d2 - entityplayer.locZ; - if (d4 * d4 + d5 * d5 + d6 * d6 < d3 * d3) { + if (d4 * d4 + d5 * d5 + d6 * d6 < squared) { entityplayer.playerConnection.sendPacket(packet); } } @@ -1249,7 +1252,7 @@ public abstract class PlayerList { if (serverstatisticmanager == null) { File file = new File(this.server.getWorldServer(0).getDataManager().getDirectory(), "stats"); - File file1 = new File(file, uuid.toString() + ".json"); + File file1 = new File(file, FastUUID.toString(uuid) + ".json"); if (!file1.exists()) { File file2 = new File(file, entityhuman.getName() + ".json"); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/ServerConnection.java b/eSpigot-Server/src/main/java/net/minecraft/server/ServerConnection.java index c32f4e7..1065937 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/ServerConnection.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/ServerConnection.java @@ -4,12 +4,8 @@ import com.google.common.collect.Lists; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.velocitypowered.natives.util.Natives; import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelException; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.EventLoopGroup; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.channel.*; import io.netty.channel.epoll.Epoll; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollServerSocketChannel; @@ -92,17 +88,24 @@ public class ServerConnection { Class oclass; LazyInitVar lazyinitvar; - if (Epoll.isAvailable() && this.f.ai()) { - // PandaSpigot start - Unix domain socket support - if (address instanceof io.netty.channel.unix.DomainSocketAddress) { - oclass = io.netty.channel.epoll.EpollServerDomainSocketChannel.class; + try { + if (Epoll.isAvailable() && this.f.ai()) { + // PandaSpigot start - Unix domain socket support + if (address instanceof io.netty.channel.unix.DomainSocketAddress) { + oclass = io.netty.channel.epoll.EpollServerDomainSocketChannel.class; + } else { + oclass = EpollServerSocketChannel.class; + } + // PandaSpigot end + lazyinitvar = ServerConnection.b; + ServerConnection.e.info("Using epoll channel type"); } else { - oclass = EpollServerSocketChannel.class; + oclass = NioServerSocketChannel.class; + lazyinitvar = ServerConnection.a; + ServerConnection.e.info("Using default channel type"); } - // PandaSpigot end - lazyinitvar = ServerConnection.b; - ServerConnection.e.info("Using epoll channel type"); - } else { + } catch (Exception e) { + ServerConnection.e.warn("An error occurred trying to check if Epoll is available, falling back to default channel type."); oclass = NioServerSocketChannel.class; lazyinitvar = ServerConnection.a; ServerConnection.e.info("Using default channel type"); @@ -115,11 +118,6 @@ public class ServerConnection { this.g.add((new ServerBootstrap()).channel(oclass).childHandler(new ChannelInitializer() { protected void initChannel(Channel channel) throws Exception { - try { - channel.config().setOption(ChannelOption.TCP_NODELAY, Boolean.TRUE); - } catch (ChannelException ignored) { - } - // KigPaper start if(PaperSpigotConfig.nettyReadTimeout) channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)); // KigPaper end diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/ServerPing.java b/eSpigot-Server/src/main/java/net/minecraft/server/ServerPing.java index eeb8100..b0d0773 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/ServerPing.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/ServerPing.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; @@ -202,7 +203,7 @@ public class ServerPing { JsonObject jsonobject1 = ChatDeserializer.l(jsonarray.get(i), "player[" + i + "]"); String s = ChatDeserializer.h(jsonobject1, "id"); - agameprofile[i] = new GameProfile(UUID.fromString(s), ChatDeserializer.h(jsonobject1, "name")); + agameprofile[i] = new GameProfile(FastUUID.parseUUID(s), ChatDeserializer.h(jsonobject1, "name")); } serverping_serverpingplayersample.a(agameprofile); @@ -224,7 +225,7 @@ public class ServerPing { JsonObject jsonobject1 = new JsonObject(); UUID uuid = serverping_serverpingplayersample.c()[i].getId(); - jsonobject1.addProperty("id", uuid == null ? "" : uuid.toString()); + jsonobject1.addProperty("id", uuid == null ? "" : FastUUID.toString(uuid)); jsonobject1.addProperty("name", serverping_serverpingplayersample.c()[i].getName()); jsonarray.add(jsonobject1); } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/SpawnerCreature.java b/eSpigot-Server/src/main/java/net/minecraft/server/SpawnerCreature.java index 530a75c..1654c79 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/SpawnerCreature.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/SpawnerCreature.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Random; // CraftBukkit start +import it.unimi.dsi.fastutil.objects.ObjectIterator; import org.bukkit.craftbukkit.util.LongHash; import org.bukkit.craftbukkit.util.LongHashSet; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; @@ -20,28 +21,40 @@ public final class SpawnerCreature { // Spigot start - get entity count only from chunks being processed in b private int getEntityCount(WorldServer server, Class oClass) { + // NachoSpigot start - remove Steam + int sum = 0; + for (ObjectIterator objectIterator = (server.chunkProviderServer).chunks.values().iterator(); objectIterator.hasNext(); ) { + Chunk c = objectIterator.next(); + sum += c.entityCount.get(oClass); + } + return sum; + // NachoSpigot end + + // TacoSpigot start - use entire world, not just active chunks. Spigot broke vanilla expectations. - if (true) { - return server - .chunkProviderServer - .chunks.values() - .stream() - .collect(java.util.stream.Collectors.summingInt(c -> c.entityCount.get(oClass))); - } - // TacoSpigot end - int i = 0; - Iterator it = this.b.iterator(); - while ( it.hasNext() ) - { - Long coord = it.next(); - int x = LongHash.msw( coord ); - int z = LongHash.lsw( coord ); - if ( !server.chunkProviderServer.unloadQueue.contains( coord ) && server.isChunkLoaded( x, z, true ) ) - { - i += server.getChunkAt( x, z ).entityCount.get( oClass ); - } - } - return i; +// if (true) { +// +// server.chunkProviderServer.chunks.values().iterator() +// return server +// .chunkProviderServer +// .chunks.values() +// .stream() +// .collect(java.util.stream.Collectors.summingInt(c -> c.entityCount.get(oClass))); +// } +// // TacoSpigot end +// int i = 0; +// Iterator it = this.b.iterator(); +// while ( it.hasNext() ) +// { +// Long coord = it.next(); +// int x = LongHash.msw( coord ); +// int z = LongHash.lsw( coord ); +// if ( !server.chunkProviderServer.unloadQueue.contains( coord ) && server.isChunkLoaded( x, z, true ) ) +// { +// i += server.getChunkAt( x, z ).entityCount.get( oClass ); +// } +// } +// return i; } // Spigot end diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityEnchantTable.java b/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityEnchantTable.java index e054166..77feb1f 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityEnchantTable.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityEnchantTable.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import com.elevatemc.spigot.config.eSpigotConfig; + import java.util.Random; public class TileEntityEnchantTable extends TileEntity implements IUpdatePlayerListBox, ITileEntityContainer { @@ -36,6 +38,9 @@ public class TileEntityEnchantTable extends TileEntity implements IUpdatePlayerL } public void c() { + if (!eSpigotConfig.enchantmentTableTicking) { + return; + } this.k = this.j; this.m = this.l; EntityHuman entityhuman = this.world.findNearbyPlayer((double) ((float) this.position.getX() + 0.5F), (double) ((float) this.position.getY() + 0.5F), (double) ((float) this.position.getZ() + 0.5F), 3.0D); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityFurnace.java b/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityFurnace.java index f0a7014..dd10ddc 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityFurnace.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityFurnace.java @@ -350,6 +350,8 @@ public class TileEntityFurnace extends TileEntityContainer implements IUpdatePla } } + if(item == Items.COAL) return 1600; + return item instanceof ItemTool && ((ItemTool) item).h().equals("WOOD") ? 200 : (item instanceof ItemSword && ((ItemSword) item).h().equals("WOOD") ? 200 : (item instanceof ItemHoe && ((ItemHoe) item).g().equals("WOOD") ? 200 : (item == Items.STICK ? 100 : (item == Items.COAL ? 1600 : (item == Items.LAVA_BUCKET ? 20000 : (item == Item.getItemOf(Blocks.SAPLING) ? 100 : (item == Items.BLAZE_ROD ? 2400 : 0))))))); } } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityHopper.java b/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityHopper.java index a66b5a0..bb51a6b 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityHopper.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/TileEntityHopper.java @@ -202,7 +202,7 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU } } // PaperSpigot start - if (world.paperSpigotConfig.useHopperCheck && !world.tacoSpigotConfig.isHopperPushBased && !this.n()) { // TacoSpigot - dont use hopper check in push mode + if (world.paperSpigotConfig.useHopperCheck && !world.paperSpigotConfig.isHopperPushBased && !this.n()) { // TacoSpigot - dont use hopper check in push mode this.d(world.spigotConfig.hopperCheck); } // PaperSpigot end @@ -367,7 +367,7 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU @Deprecated public static boolean a(IHopper ihopper) { IInventory iinventory; - if (ihopper.getWorld().tacoSpigotConfig.isHopperPushBased && ihopper instanceof TileEntityHopper) { + if (ihopper.getWorld().paperSpigotConfig.isHopperPushBased && ihopper instanceof TileEntityHopper) { BlockPosition pos = ((TileEntityHopper) ihopper).getPosition().up(); // Only pull from a above, because everything else comes to us iinventory = HopperHelper.getInventory(ihopper.getWorld(), pos); } else { @@ -403,7 +403,7 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU } } } - } else if (!ihopper.getWorld().tacoSpigotConfig.isHopperPushBased || !(ihopper instanceof TileEntityHopper)) { // TacoSpigot - only search for entities in 'pull mode' + } else if (!ihopper.getWorld().paperSpigotConfig.isHopperPushBased || !(ihopper instanceof TileEntityHopper)) { // TacoSpigot - only search for entities in 'pull mode' for (EntityItem entityitem : a(ihopper.getWorld(), ihopper.A(), ihopper.B() + 1.0D, ihopper.C())) { if (a(ihopper, entityitem)) { diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/UserCache.java b/eSpigot-Server/src/main/java/net/minecraft/server/UserCache.java index 1637404..0b9ee61 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/UserCache.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/UserCache.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.common.base.Charsets; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; @@ -287,7 +288,7 @@ public class UserCache { jsonobject.addProperty("name", usercache_usercacheentry.a().getName()); UUID uuid = usercache_usercacheentry.a().getId(); - jsonobject.addProperty("uuid", uuid == null ? "" : uuid.toString()); + jsonobject.addProperty("uuid", uuid == null ? "" : FastUUID.toString(uuid)); jsonobject.addProperty("expiresOn", UserCache.a.format(usercache_usercacheentry.b())); return jsonobject; } @@ -316,7 +317,7 @@ public class UserCache { UUID uuid; try { - uuid = UUID.fromString(s); + uuid = FastUUID.parseUUID(s); } catch (Throwable throwable) { return null; } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/Village.java b/eSpigot-Server/src/main/java/net/minecraft/server/Village.java index 87e7096..390f76b 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/Village.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/Village.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.common.collect.Lists; import com.mojang.authlib.GameProfile; import java.util.Iterator; @@ -411,7 +412,7 @@ public class Village { if (nbttagcompound2.hasKey("UUID")) { UserCache usercache = MinecraftServer.getServer().getUserCache(); - GameProfile gameprofile = usercache.a(UUID.fromString(nbttagcompound2.getString("UUID"))); + GameProfile gameprofile = usercache.a(FastUUID.parseUUID(nbttagcompound2.getString("UUID"))); if (gameprofile != null) { this.j.put(gameprofile.getName(), nbttagcompound2.getInt("S")); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/WhiteListEntry.java b/eSpigot-Server/src/main/java/net/minecraft/server/WhiteListEntry.java index 06d29a4..da93bb5 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/WhiteListEntry.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/WhiteListEntry.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.eatthepath.uuid.FastUUID; import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; import java.util.UUID; @@ -29,7 +30,7 @@ public class WhiteListEntry extends JsonListEntry { UUID uuid; try { - uuid = UUID.fromString(s); + uuid = FastUUID.parseUUID(s); } catch (Throwable throwable) { return null; } diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/World.java b/eSpigot-Server/src/main/java/net/minecraft/server/World.java index 81ec6c0..46238c1 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/World.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/World.java @@ -166,7 +166,6 @@ public abstract class World implements IBlockAccess { public final org.github.paperspigot.PaperSpigotWorldConfig paperSpigotConfig; // PaperSpigot 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); @@ -203,9 +202,8 @@ public abstract class World implements IBlockAccess { } protected World(IDataManager idatamanager, WorldData worlddata, WorldProvider worldprovider, MethodProfiler methodprofiler, boolean flag, ChunkGenerator gen, org.bukkit.World.Environment env) { - this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot - this.paperSpigotConfig = new org.github.paperspigot.PaperSpigotWorldConfig( worlddata.getName() ); // PaperSpigot - this.tacoSpigotConfig = new net.techcable.tacospigot.TacoSpigotWorldConfig(worlddata.getName()); // TacoSpigot + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(); // Spigot + this.paperSpigotConfig = new org.github.paperspigot.PaperSpigotWorldConfig(); // PaperSpigot this.generator = gen; this.world = new CraftWorld((WorldServer) this, gen, env); this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit @@ -315,6 +313,10 @@ public abstract class World implements IBlockAccess { return blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000 && blockposition.getY() >= 0 && blockposition.getY() < 256; } + private boolean isValidLocation(int blockposition_x, int blockposition_y, int blockposition_z) { + return blockposition_x >= -30000000 && blockposition_z >= -30000000 && blockposition_x < 30000000 && blockposition_z < 30000000 && blockposition_z >= 0 && blockposition_y < 256; + } + public boolean isEmpty(BlockPosition blockposition) { return this.getType(blockposition).getBlock().getMaterial() == Material.AIR; } @@ -324,6 +326,11 @@ public abstract class World implements IBlockAccess { // return this.a(blockposition, true); } + public boolean isLoaded(int blockposition_x, int blockposition_y, int blockposition_z) { + return getChunkIfLoaded(blockposition_x >> 4, blockposition_z >> 4) != null; // Paper + //return this.a(blockposition, true); + } + public boolean a(BlockPosition blockposition, boolean flag) { return this.isValidLocation(blockposition) && this.isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4, flag); } @@ -381,6 +388,10 @@ public abstract class World implements IBlockAccess { return this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); } + public Chunk getChunkAtWorldCoords(int blockposition_x, int blockposition_y, int blockposition_z) { + return this.getChunkAt(blockposition_x >> 4, blockposition_z >> 4); + } + // Migot start private void cacheLastChunkAccess(Chunk foundChunk) { this.lastChunkAccessed = ((foundChunk == null || foundChunk.isEmpty() || foundChunk.wasUnloaded()) ? this.dummyChunk : foundChunk); @@ -614,13 +625,14 @@ public abstract class World implements IBlockAccess { public void d(BlockPosition blockposition, final Block block) { if (!this.isClientSide) { - IBlockData iblockdata = this.getType(blockposition); + IBlockData iblockdata = this.getTypeIfLoaded(blockposition); // Nacho-0012 :: Don't load chunks for physics + if (iblockdata == null) return; // Nacho-0012 :: Don't load chunks for physics try { // CraftBukkit start CraftWorld world = this.getWorld(); // TacoSpigot start - Add config to disable redstone firing BlockPhysicsEvent - if (world != null && (this.tacoSpigotConfig.isRedstoneFireBPE || !(block instanceof BlockRedstoneWire || block instanceof BlockRedstoneTorch || block instanceof BlockRepeater)) && ((WorldServer) this).hasPhysicsEvent) { + if (world != null && (this.paperSpigotConfig.isRedstoneFireBPE || !(block instanceof BlockRedstoneWire || block instanceof BlockRedstoneTorch || block instanceof BlockRepeater)) && ((WorldServer) this).hasPhysicsEvent) { // TacoSpigot end BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftMagicNumbers.getId(block)); this.getServer().getPluginManager().callEvent(event); @@ -786,8 +798,9 @@ public abstract class World implements IBlockAccess { int i; if (blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000) { - if (this.isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4, true)) { - i = this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4).b(blockposition.getX() & 15, blockposition.getZ() & 15); + Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); + if (chunk != null) { + i = chunk.b(blockposition.getX() & 15, blockposition.getZ() & 15); } else { i = 0; } @@ -798,13 +811,15 @@ public abstract class World implements IBlockAccess { return new BlockPosition(blockposition.getX(), i, blockposition.getZ()); } - public int b(int i, int j) { - if (i >= -30000000 && j >= -30000000 && i < 30000000 && j < 30000000) { - if (!this.isChunkLoaded(i >> 4, j >> 4, true)) { + public int b(int i, int j) + { + if (i >= -30000000 && j >= -30000000 && i < 30000000 && j < 30000000) + { + Chunk chunk = this.getChunkIfLoaded(i >> 4, j >> 4); + if (chunk != null) + { return 0; } else { - Chunk chunk = this.getChunkAt(i >> 4, j >> 4); - return chunk.v(); } } else { @@ -812,6 +827,22 @@ public abstract class World implements IBlockAccess { } } + public int b(EnumSkyBlock enumskyblock, int blockposition_x, int blockposition_y, int blockposition_z) { + if (blockposition_y < 0) { + blockposition_y = 0; + } + + if (!this.isValidLocation(blockposition_x, blockposition_y, blockposition_z)) { + return enumskyblock.c; + } else if (!this.isLoaded(blockposition_x, blockposition_y, blockposition_z)) { + return enumskyblock.c; + } else { + Chunk chunk = this.getChunkAtWorldCoords(blockposition_x, blockposition_y, blockposition_z); + + return chunk.getBrightness(enumskyblock, blockposition_x, blockposition_y, blockposition_z); + } + } + public int b(EnumSkyBlock enumskyblock, BlockPosition blockposition) { if (blockposition.getY() < 0) { blockposition = new BlockPosition(blockposition.getX(), 0, blockposition.getZ()); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/WorldNBTStorage.java b/eSpigot-Server/src/main/java/net/minecraft/server/WorldNBTStorage.java index 1ae0f72..9d37f24 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/WorldNBTStorage.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/WorldNBTStorage.java @@ -199,7 +199,7 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { File file = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat"); // Spigot Start boolean usingWrongFile = false; - boolean normalFile = file.exists() && file.isFile(); // KigPaper + boolean normalFile = 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(StandardCharsets.UTF_8) ) + ".dat"); diff --git a/eSpigot-Server/src/main/java/net/minecraft/server/WorldServer.java b/eSpigot-Server/src/main/java/net/minecraft/server/WorldServer.java index 360aa1c..43efd56 100644 --- a/eSpigot-Server/src/main/java/net/minecraft/server/WorldServer.java +++ b/eSpigot-Server/src/main/java/net/minecraft/server/WorldServer.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.elevatemc.spigot.config.eSpigotConfig; import com.google.common.base.Predicate; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -19,7 +20,6 @@ import org.bukkit.craftbukkit.util.HashTreeSet; import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.weather.LightningStrikeEvent; -import com.elevatemc.spigot.eSpigotFeature; // CraftBukkit end public class WorldServer extends World implements IAsyncTaskHandler { @@ -209,7 +209,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { } this.worldProvider.m().b(); - if (eSpigotFeature.DAY_LIGHT_CYCLE.isEnabled()) { + if (eSpigotConfig.dayLightCycle) { if (this.everyoneDeeplySleeping()) { if (this.getGameRules().getBoolean("doDaylightCycle")) { long i = this.worldData.getDayTime() + 24000L; @@ -221,7 +221,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { } } - if (eSpigotFeature.NATURAL_MOB_SPAWNING.isEnabled()) { + if (eSpigotConfig.naturalMobSpawning) { // CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals long time = this.worldData.getTime(); if (this.getGameRules().getBoolean("doMobSpawning") && this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES && (this.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.players.size() > 0)) { @@ -264,7 +264,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { this.manager.flush(); timings.doChunkMap.stopTiming(); // Spigot - if (eSpigotFeature.VILLAGE_TICKING.isEnabled()) { // eSpigot - Disable village ticking + if (eSpigotConfig.villageTicking) { // eSpigot - Disable village ticking this.methodProfiler.c("village"); timings.doVillages.startTiming(); // Spigot this.villages.tick(); @@ -1151,17 +1151,15 @@ public class WorldServer extends World implements IAsyncTaskHandler { // */ if (flag != this.S()) { // Only send weather packets to those affected - for (EntityHuman player : this.players) { - if (player.world == this) { + for (EntityHuman player : this.players) + { + if (player.world == this) + { ((EntityPlayer) player).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); + ((EntityPlayer) player).updateWeather(this.o, this.p, this.q, this.r); } } } - for (EntityHuman player : this.players) { - if (player.world == this) { - ((EntityPlayer) player).updateWeather(this.o, this.p, this.q, this.r); - } - } // CraftBukkit end } diff --git a/eSpigot-Server/src/main/java/net/techcable/tacospigot/HopperHelper.java b/eSpigot-Server/src/main/java/net/techcable/tacospigot/HopperHelper.java index 630a81b..becada5 100644 --- a/eSpigot-Server/src/main/java/net/techcable/tacospigot/HopperHelper.java +++ b/eSpigot-Server/src/main/java/net/techcable/tacospigot/HopperHelper.java @@ -36,6 +36,6 @@ public class HopperHelper { } public static boolean isFireInventoryMoveItemEvent(IHopper hopper) { - return hopper.getWorld().tacoSpigotConfig.isHopperFireIMIE && InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length > 0; + return hopper.getWorld().paperSpigotConfig.isHopperFireIMIE && InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length > 0; } } diff --git a/eSpigot-Server/src/main/java/net/techcable/tacospigot/HopperPusher.java b/eSpigot-Server/src/main/java/net/techcable/tacospigot/HopperPusher.java index 214ec08..f3a3e5d 100644 --- a/eSpigot-Server/src/main/java/net/techcable/tacospigot/HopperPusher.java +++ b/eSpigot-Server/src/main/java/net/techcable/tacospigot/HopperPusher.java @@ -39,7 +39,7 @@ public interface HopperPusher { boolean acceptItem(TileEntityHopper hopper); default boolean tryPutInHopper() { - if (!getWorld().tacoSpigotConfig.isHopperPushBased) return false; + if (!getWorld().paperSpigotConfig.isHopperPushBased) return false; TileEntityHopper hopper = findHopper(); return hopper != null && hopper.canAcceptItems() && acceptItem(hopper); } diff --git a/eSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotConfig.java b/eSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotConfig.java deleted file mode 100644 index 45ed786..0000000 --- a/eSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotConfig.java +++ /dev/null @@ -1,106 +0,0 @@ -package net.techcable.tacospigot; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.List; -import java.util.logging.Level; - -import org.bukkit.Bukkit; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; - -import com.google.common.base.Throwables; - -public class TacoSpigotConfig { - - private static File CONFIG_FILE; - private static final String HEADER = "This is the main configuration file for TacoSpigot.\n" + "As you can see, there's tons to configure. Some options may impact gameplay, so use\n" + "with caution, and make sure you know what each option does before configuring.\n" + "\n" + "If you need help with the configuration or have any questions related to TacoSpigot,\n" + "join us at the IRC.\n" + "\n" + "IRC: #taco @ irc.spi.gt ( http://irc.spi.gt/iris/?channels=taco )\n"; - /*========================================================================*/ - static YamlConfiguration config; - static int version; - /*========================================================================*/ - - public static void init(File configFile) { - CONFIG_FILE = configFile; - config = new YamlConfiguration(); - try { - System.out.println("Loading TacoSpigot config from " + configFile.getName()); - config.load(CONFIG_FILE); - } catch (IOException ignored) { - } catch (InvalidConfigurationException ex) { - Bukkit.getLogger().log(Level.SEVERE, "Could not load taco.yml, please correct your syntax errors", ex); - throw Throwables.propagate(ex); - } - config.options().header(HEADER); - config.options().copyDefaults(true); - - version = getInt("config-version", 1); - set("config-version", 1); - readConfig(TacoSpigotConfig.class, null); - } - - static void readConfig(Class clazz, Object instance) { - for (Method method : clazz.getDeclaredMethods()) { - if (Modifier.isPrivate(method.getModifiers())) { - if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) { - try { - method.setAccessible(true); - method.invoke(instance); - } catch (InvocationTargetException ex) { - throw Throwables.propagate(ex.getCause()); - } catch (Exception ex) { - Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex); - } - } - } - } - - try { - config.save(CONFIG_FILE); - } catch (IOException ex) { - Bukkit.getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex); - } - } - - private static void set(String path, Object val) { - config.set(path, val); - } - - private static boolean getBoolean(String path, boolean def) { - config.addDefault(path, def); - return config.getBoolean(path, config.getBoolean(path)); - } - - private static double getDouble(String path, double def) { - config.addDefault(path, def); - return config.getDouble(path, config.getDouble(path)); - } - - private static float getFloat(String path, float def) { - config.addDefault(path, def); - return config.getFloat(path, config.getFloat(path)); - } - - private static int getInt(String path, int def) { - config.addDefault(path, def); - return config.getInt(path, config.getInt(path)); - } - - private static List getList(String path, T def) { - config.addDefault(path, def); - return config.getList(path, config.getList(path)); - } - - private static String getString(String path, String def) { - config.addDefault(path, def); - return config.getString(path, config.getString(path)); - } - - public static boolean useArraysForBlockStates; - private static void useArraysForBlockStates() { - useArraysForBlockStates = getBoolean("useArraysForBlockStates", false); - } -} diff --git a/eSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotWorldConfig.java b/eSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotWorldConfig.java index f6975ff..e69de29 100644 --- a/eSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotWorldConfig.java +++ b/eSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotWorldConfig.java @@ -1,113 +0,0 @@ -package net.techcable.tacospigot; - -import java.util.List; - -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.YamlConfiguration; - -public class TacoSpigotWorldConfig { - - private final String worldName; - private final YamlConfiguration config; - private boolean verbose; - - public TacoSpigotWorldConfig(String worldName) { - this.worldName = worldName; - this.config = TacoSpigotConfig.config; - init(); - } - - public void init() { - this.verbose = getBoolean("verbose", true); - - log("-------- World Settings For [" + worldName + "] --------"); - TacoSpigotConfig.readConfig(TacoSpigotWorldConfig.class, this); - } - - private void log(String s) { - if (verbose) { - Bukkit.getLogger().info(s); - } - } - - private void set(String path, Object val) { - config.set("world-settings.default." + path, val); - } - - private boolean getBoolean(String path, boolean def) { - config.addDefault("world-settings.default." + path, def); - return config.getBoolean("world-settings." + worldName + "." + path, config.getBoolean("world-settings.default." + path)); - } - - private double getDouble(String path, double def) { - config.addDefault("world-settings.default." + path, def); - return config.getDouble("world-settings." + worldName + "." + path, config.getDouble("world-settings.default." + path)); - } - - private int getInt(String path, int def) { - config.addDefault("world-settings.default." + path, def); - return config.getInt("world-settings." + worldName + "." + path, config.getInt("world-settings.default." + path)); - } - - private float getFloat(String path, float def) { - config.addDefault("world-settings.default." + path, def); - return config.getFloat("world-settings." + worldName + "." + path, config.getFloat("world-settings.default." + path)); - } - - private List getList(String path, T def) { - config.addDefault("world-settings.default." + path, def); - return config.getList("world-settings." + worldName + "." + path, config.getList("world-settings.default." + path)); - } - - private String getString(String path, String def) { - config.addDefault("world-settings.default." + path, def); - return config.getString("world-settings." + worldName + "." + path, config.getString("world-settings.default." + path)); - } - - public boolean isRedstoneFireBPE; - private void isRedstoneFireBPE() { - isRedstoneFireBPE = getBoolean("redstone-fire-BlockPhysicsEvent", true); - } - - public boolean isHopperPushBased; - private void isHopperPushBased() { - isHopperPushBased = getBoolean("hopper.push-based", true); - } - - public boolean isHopperFireIMIE; - private void isHopperFireIMIE() { - isHopperFireIMIE = getBoolean("hopper.fire-InventoryMoveItemEvent", true); - } - - public boolean optimizeArmorStandMovement; - private void isArmorStandMoveWithoutGravity() { - optimizeArmorStandMovement = getBoolean("armor-stand.optimize-movement", false); // Doesn't fully emulate vanilla behavior, see issue #1 - } - - public boolean nonPlayerEntitiesOnScoreboards = false; - private void nonPlayerEntitiesOnScoreboards() { - nonPlayerEntitiesOnScoreboards = getBoolean("allow-non-player-entities-on-scoreboards", false); - } - - public boolean grassIgnoresLight = false; - private void isGrassIgnoresLight() { - grassIgnoresLight = getBoolean("grass-ignores-light", false); - } - - public boolean optimizeTntMovement = false; - private void isOptimizeTnt() { - optimizeTntMovement = getBoolean("tnt.optimize-movement", false); // May not fully emulate vanilla behavior - } - public boolean optimizeLiquidExplosions = true; - private void isOptimizeLiquidExplosions() { - optimizeLiquidExplosions = getBoolean("tnt.optimize-liquid-explosions", true); // This seems like a pretty sane default - } - - public boolean fixEastWest; - private void fixEastWest() { - fixEastWest = getBoolean("fix-east-west-cannoning", false); - } - - public boolean disableFallingBlockStackingAt256; - private void DisableFallingBlockStackingAt256() { disableFallingBlockStackingAt256 = getBoolean("disable-falling-block-stacking-at-256", false);} -} diff --git a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java index 8998372..e08afce 100644 --- a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java +++ b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java @@ -24,7 +24,6 @@ public class CraftCrashReport implements Callable { value.append(' ').append(description.getFullName()).append(' ').append(description.getMain()).append(' ').append(Arrays.toString(description.getAuthors().toArray())).append(','); } value.append("}\n Warnings: ").append(Bukkit.getWarningState().name()); - value.append("\n Reload Count: ").append(String.valueOf(MinecraftServer.getServer().server.reloadCount)); value.append("\n Threads: {"); for (Map.Entry entry : Thread.getAllStackTraces().entrySet()) { value.append(' ').append(entry.getKey().getState().name()).append(' ').append(entry.getKey().getName()).append(": ").append(Arrays.toString(entry.getValue())).append(','); diff --git a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java index a7ab893..eb360bb 100644 --- a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit; +import com.eatthepath.uuid.FastUUID; import com.mojang.authlib.GameProfile; import java.io.File; import java.util.LinkedHashMap; @@ -134,7 +135,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa return Bukkit.getServer().getOfflinePlayer((String) args.get("name")); } - return Bukkit.getServer().getOfflinePlayer(UUID.fromString((String) args.get("UUID"))); + return Bukkit.getServer().getOfflinePlayer(FastUUID.parseUUID((String) args.get("UUID"))); } @Override diff --git a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index e502320..d9e81ba 100644 --- a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -6,6 +6,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -21,8 +22,12 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; +import javax.annotation.Nullable; import javax.imageio.ImageIO; +import com.eatthepath.uuid.FastUUID; +import com.elevatemc.spigot.config.BukkitConfig; +import com.elevatemc.spigot.config.SharedConfig; import com.elevatemc.spigot.eSpigot; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; @@ -93,6 +98,7 @@ import org.bukkit.plugin.messaging.StandardMessenger; import org.bukkit.scheduler.BukkitWorker; import org.bukkit.util.StringUtil; import org.bukkit.util.permissions.DefaultPermissions; +import org.github.paperspigot.PaperSpigotConfig; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; @@ -131,8 +137,6 @@ public final class CraftServer implements Server { protected final MinecraftServer console; protected final DedicatedPlayerList playerList; private final Map worlds = new LinkedHashMap<>(); - private YamlConfiguration configuration; - private YamlConfiguration commandsConfiguration; // KigPaper start - CVE-2017-18640 private final LoaderOptions loaderOptions = new LoaderOptions(); private final Yaml yaml = new Yaml(new SafeConstructor(), new Representer(), new DumperOptions(), loaderOptions); @@ -158,7 +162,6 @@ public final class CraftServer implements Server { private final Pattern validUserPattern = Pattern.compile("^[a-zA-Z0-9_]{2,16}$"); private final UUID invalidUserUUID = UUID.nameUUIDFromBytes("InvalidUsername".getBytes(Charsets.UTF_8)); private final List playerView; - public int reloadCount; private final com.elevatemc.spigot.eSpigot eSpigot = new eSpigot(this); private final class BooleanWrapper { @@ -193,52 +196,18 @@ public final class CraftServer implements Server { getLogger().info("PandaConsole input is disabled due to --noconsole command argument"); } - configuration = YamlConfiguration.loadConfiguration(getConfigFile()); - configuration.options().copyDefaults(true); - configuration.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("configurations/bukkit.yml"), Charsets.UTF_8))); - ConfigurationSection legacyAlias = null; - if (!configuration.isString("aliases")) { - legacyAlias = configuration.getConfigurationSection("aliases"); - configuration.set("aliases", "now-in-commands.yml"); - } - saveConfig(); - if (getCommandsConfigFile().isFile()) { - legacyAlias = null; - } - commandsConfiguration = YamlConfiguration.loadConfiguration(getCommandsConfigFile()); - commandsConfiguration.options().copyDefaults(true); - commandsConfiguration.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("configurations/commands.yml"), Charsets.UTF_8))); - saveCommandsConfig(); + SharedConfig.init((File) console.options.valueOf("espigot-settings")); // eSpigot - // Migrate aliases from old file and add previously implicit $1- to pass all arguments - if (legacyAlias != null) { - ConfigurationSection aliases = commandsConfiguration.createSection("aliases"); - for (String key : legacyAlias.getKeys(false)) { - ArrayList commands = new ArrayList<>(); - - if (legacyAlias.isList(key)) { - for (String command : legacyAlias.getStringList(key)) { - commands.add(command + " $1-"); - } - } else { - commands.add(legacyAlias.getString(key) + " $1-"); - } - - aliases.set(key, commands); - } - } - - saveCommandsConfig(); - overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*"); - ((SimplePluginManager) pluginManager).useTimings(configuration.getBoolean("settings.plugin-profiling")); - monsterSpawn = configuration.getInt("spawn-limits.monsters"); - animalSpawn = configuration.getInt("spawn-limits.animals"); - waterAnimalSpawn = configuration.getInt("spawn-limits.water-animals"); - ambientSpawn = configuration.getInt("spawn-limits.ambient"); - console.autosavePeriod = configuration.getInt("ticks-per.autosave"); - warningState = WarningState.value(configuration.getString("settings.deprecated-verbose")); - chunkGCPeriod = configuration.getInt("chunk-gc.period-in-ticks"); - chunkGCLoadThresh = configuration.getInt("chunk-gc.load-threshold"); + overrideAllCommandBlockCommands = SharedConfig.config.getStringList("commands.command-block-overrides").contains("*"); + ((SimplePluginManager) pluginManager).useTimings(BukkitConfig.pluginProfiling); + monsterSpawn = BukkitConfig.monsterSpawnLimit; + animalSpawn = BukkitConfig.animalSpawnLimit; + waterAnimalSpawn = BukkitConfig.waterAnimalSpawnLimit; + ambientSpawn = BukkitConfig.ambientSpawnLimit; + console.autosavePeriod = BukkitConfig.ticksPerAutosave; + warningState = WarningState.value(BukkitConfig.deprecatedVerbose); + chunkGCPeriod = BukkitConfig.chunkGCPeriodInTicks; + chunkGCLoadThresh = BukkitConfig.chunkGCLoadThreshold; loadIcon(); // Spigot Start - Moved to old location of new DedicatedPlayerList in DedicatedServer @@ -248,31 +217,7 @@ public final class CraftServer implements Server { } public boolean getCommandBlockOverride(String command) { - return overrideAllCommandBlockCommands || commandsConfiguration.getStringList("command-block-overrides").contains(command); - } - - private File getConfigFile() { - return (File) console.options.valueOf("bukkit-settings"); - } - - private File getCommandsConfigFile() { - return (File) console.options.valueOf("commands-settings"); - } - - private void saveConfig() { - try { - configuration.save(getConfigFile()); - } catch (IOException ex) { - Logger.getLogger(CraftServer.class.getName()).log(Level.SEVERE, "Could not save " + getConfigFile(), ex); - } - } - - private void saveCommandsConfig() { - try { - commandsConfiguration.save(getCommandsConfigFile()); - } catch (IOException ex) { - Logger.getLogger(CraftServer.class.getName()).log(Level.SEVERE, "Could not save " + getCommandsConfigFile(), ex); - } + return overrideAllCommandBlockCommands || SharedConfig.config.getStringList("commands.command-block-overrides").contains(command); } public void loadPlugins() { @@ -514,7 +459,7 @@ public final class CraftServer implements Server { @Override public boolean getAllowEnd() { - return this.configuration.getBoolean("settings.allow-end"); + return BukkitConfig.allowEnd; } @Override @@ -523,11 +468,11 @@ public final class CraftServer implements Server { } public boolean getWarnOnOverload() { - return this.configuration.getBoolean("settings.warn-on-overload"); + return BukkitConfig.warnOnOverlaod; } public boolean getQueryPlugins() { - return this.configuration.getBoolean("settings.query-plugins"); + return BukkitConfig.queryPlugins; } @Override @@ -552,12 +497,12 @@ public final class CraftServer implements Server { @Override public String getUpdateFolder() { - return this.configuration.getString("settings.update-folder", "update"); + return BukkitConfig.updateFolder; } @Override public File getUpdateFolderFile() { - return new File((File) console.options.valueOf("plugins"), this.configuration.getString("settings.update-folder", "update")); + return new File((File) console.options.valueOf("plugins"), getUpdateFolder()); } @Override @@ -566,19 +511,19 @@ public final class CraftServer implements Server { if (org.spigotmc.SpigotConfig.bungee) { return -1; } else { - return this.configuration.getInt("settings.connection-throttle"); + return BukkitConfig.connectionThrottle; } // Spigot End } @Override public int getTicksPerAnimalSpawns() { - return this.configuration.getInt("ticks-per.animal-spawns"); + return BukkitConfig.ticksPerAnimalSpawn; } @Override public int getTicksPerMonsterSpawns() { - return this.configuration.getInt("ticks-per.monster-spawns"); + return BukkitConfig.ticksPerMonsterSpawn; } @Override @@ -598,7 +543,7 @@ public final class CraftServer implements Server { @Override public List getWorlds() { - return new ArrayList<>(worlds.values()); + return new ArrayList(worlds.values()); } public DedicatedPlayerList getHandle() { @@ -663,115 +608,6 @@ public final class CraftServer implements Server { return false; } - @Override - public void reload() { - reloadCount++; - configuration = YamlConfiguration.loadConfiguration(getConfigFile()); - commandsConfiguration = YamlConfiguration.loadConfiguration(getCommandsConfigFile()); - PropertyManager config = new PropertyManager(console.options); - - ((DedicatedServer) console).propertyManager = config; - - boolean animals = config.getBoolean("spawn-animals", console.getSpawnAnimals()); - boolean monsters = config.getBoolean("spawn-monsters", console.worlds.get(0).getDifficulty() != EnumDifficulty.PEACEFUL); - EnumDifficulty difficulty = EnumDifficulty.getById(config.getInt("difficulty", console.worlds.get(0).getDifficulty().ordinal())); - - online.value = config.getBoolean("online-mode", console.getOnlineMode()); - console.setSpawnAnimals(config.getBoolean("spawn-animals", console.getSpawnAnimals())); - console.setPVP(config.getBoolean("pvp", console.getPVP())); - console.setAllowFlight(config.getBoolean("allow-flight", console.getAllowFlight())); - console.setMotd(config.getString("motd", console.getMotd())); - monsterSpawn = configuration.getInt("spawn-limits.monsters"); - animalSpawn = configuration.getInt("spawn-limits.animals"); - waterAnimalSpawn = configuration.getInt("spawn-limits.water-animals"); - ambientSpawn = configuration.getInt("spawn-limits.ambient"); - warningState = WarningState.value(configuration.getString("settings.deprecated-verbose")); - printSaveWarning = false; - console.autosavePeriod = configuration.getInt("ticks-per.autosave"); - chunkGCPeriod = configuration.getInt("chunk-gc.period-in-ticks"); - chunkGCLoadThresh = configuration.getInt("chunk-gc.load-threshold"); - loadIcon(); - - try { - playerList.getIPBans().load(); - } catch (IOException ex) { - logger.log(Level.WARNING, "Failed to load banned-ips.json, " + ex.getMessage()); - } - try { - playerList.getProfileBans().load(); - } catch (IOException ex) { - logger.log(Level.WARNING, "Failed to load banned-players.json, " + ex.getMessage()); - } - - org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot - org.github.paperspigot.PaperSpigotConfig.init((File) console.options.valueOf("paper-settings")); // PaperSpigot - net.techcable.tacospigot.TacoSpigotConfig.init((File) console.options.valueOf("taco-settings")); // TacoSpigot - for (WorldServer world : console.worlds) { - world.worldData.setDifficulty(difficulty); - world.setSpawnFlags(monsters, animals); - if (this.getTicksPerAnimalSpawns() < 0) { - world.ticksPerAnimalSpawns = 400; - } else { - world.ticksPerAnimalSpawns = this.getTicksPerAnimalSpawns(); - } - - if (this.getTicksPerMonsterSpawns() < 0) { - world.ticksPerMonsterSpawns = 1; - } else { - world.ticksPerMonsterSpawns = this.getTicksPerMonsterSpawns(); - } - world.spigotConfig.init(); // Spigot - world.paperSpigotConfig.init(); // PaperSpigot - world.tacoSpigotConfig.init(); // TacoSpigot - } - - Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper - pluginManager.clearPlugins(); - commandMap.clearCommands(); - - // Paper start - for (Plugin plugin : pluginClone) { - entityMetadata.removeAll(plugin); - worldMetadata.removeAll(plugin); - playerMetadata.removeAll(plugin); - } - // Paper end - - resetRecipes(); - org.spigotmc.SpigotConfig.registerCommands(); // Spigot - org.github.paperspigot.PaperSpigotConfig.registerCommands(); // PaperSpigot - - overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*"); - - int pollCount = 0; - - // Wait for at most 2.5 seconds for plugins to close their threads - while (pollCount < 50 && getScheduler().getActiveWorkers().size() > 0) { - try { - Thread.sleep(50); - } catch (InterruptedException ignored) {} - pollCount++; - } - - List overdueWorkers = getScheduler().getActiveWorkers(); - for (BukkitWorker worker : overdueWorkers) { - Plugin plugin = worker.getOwner(); - String author = ""; - if (plugin.getDescription().getAuthors().size() > 0) { - author = plugin.getDescription().getAuthors().get(0); - } - getLogger().log(Level.SEVERE, String.format( - "Nag author: '%s' of '%s' about the following: %s", - author, - plugin.getDescription().getName(), - "This plugin is not properly shutting down its async tasks when it is being reloaded. This may cause conflicts with the newly loaded version of the plugin" - )); - } - loadPlugins(); - enablePlugins(PluginLoadOrder.STARTUP); - enablePlugins(PluginLoadOrder.POSTWORLD); - } - private void loadIcon() { icon = new CraftIconCache(null); try { @@ -786,7 +622,7 @@ public final class CraftServer implements Server { @SuppressWarnings({ "unchecked", "finally" }) private void loadCustomPermissions() { - File file = new File(configuration.getString("settings.permissions-file")); + File file = new File(BukkitConfig.permissionsFile); FileInputStream stream; try { @@ -804,7 +640,7 @@ public final class CraftServer implements Server { try { perms = yaml.load(stream); } catch (MarkedYAMLException ex) { - getLogger().log(Level.WARNING, "Server permissions file " + file + " is not valid YAML: " + ex); + getLogger().log(Level.WARNING, "Server permissions file " + file + " is not valid YAML: " + ex.toString()); return; } catch (Throwable ex) { getLogger().log(Level.WARNING, "Server permissions file " + file + " is not valid YAML.", ex); @@ -812,7 +648,7 @@ public final class CraftServer implements Server { } finally { try { stream.close(); - } catch (IOException ignored) {} + } catch (IOException ex) {} } if (perms == null) { @@ -1118,11 +954,11 @@ public final class CraftServer implements Server { Validate.notNull(config, "Config cannot be null"); DataSourceConfig ds = new DataSourceConfig(); - ds.setDriver(configuration.getString("database.driver")); - ds.setUrl(configuration.getString("database.url")); - ds.setUsername(configuration.getString("database.username")); - ds.setPassword(configuration.getString("database.password")); - ds.setIsolationLevel(TransactionIsolation.getLevel(configuration.getString("database.isolation"))); + ds.setDriver(BukkitConfig.databaseDriver); + ds.setUrl(BukkitConfig.databaseUrl); + ds.setUsername(BukkitConfig.databaseUsername); + ds.setPassword(BukkitConfig.databasePassword); + ds.setIsolationLevel(TransactionIsolation.getLevel(BukkitConfig.databaseIsolation)); if (ds.getDriver().contains("sqlite")) { config.setDatabasePlatform(new SQLitePlatform()); @@ -1193,8 +1029,8 @@ public final class CraftServer implements Server { @Override public Map getCommandAliases() { - ConfigurationSection section = commandsConfiguration.getConfigurationSection("aliases"); - Map result = new LinkedHashMap<>(); + ConfigurationSection section = SharedConfig.config.getConfigurationSection("commands.aliases"); + Map result = new LinkedHashMap(); if (section != null) { for (String key : section.getKeys(false)) { @@ -1206,25 +1042,20 @@ public final class CraftServer implements Server { commands = ImmutableList.of(section.getString(key)); } - result.put(key, commands.toArray(new String[0])); + result.put(key, commands.toArray(new String[commands.size()])); } } return result; } - public void removeBukkitSpawnRadius() { - configuration.set("settings.spawn-radius", null); - saveConfig(); - } - public int getBukkitSpawnRadius() { - return configuration.getInt("settings.spawn-radius", -1); + return -1; } @Override public String getShutdownMessage() { - return configuration.getString("settings.shutdown-message"); + return BukkitConfig.shutdownMessage; } @Override @@ -1234,8 +1065,9 @@ public final class CraftServer implements Server { @Override public void setSpawnRadius(int value) { - configuration.set("settings.spawn-radius", value); - saveConfig(); + PropertyManager propertyManager = ((DedicatedServer) console).propertyManager; + propertyManager.setProperty("spawn-protection", value); + propertyManager.savePropertiesFile(); } @Override @@ -1255,11 +1087,11 @@ public final class CraftServer implements Server { @Override public boolean useExactLoginLocation() { - return configuration.getBoolean("settings.use-exact-login-location"); + return BukkitConfig.useExactLoginLocation; } public ChunkGenerator getGenerator(String world) { - ConfigurationSection section = configuration.getConfigurationSection("worlds"); + ConfigurationSection section = BukkitConfig.getConfigurationSection("worlds"); ChunkGenerator result = null; if (section != null) { @@ -1520,7 +1352,7 @@ public final class CraftServer implements Server { } if (container == null) { - container = new File(configuration.getString("settings.world-container", ".")); + container = new File(BukkitConfig.worldContainer); } return container; @@ -1534,7 +1366,7 @@ public final class CraftServer implements Server { for (String file : files) { try { - players.add(getOfflinePlayer(UUID.fromString(file.substring(0, file.length() - 4)))); + players.add(getOfflinePlayer(FastUUID.parseUUID(file.substring(0, file.length() - 4)))); } catch (IllegalArgumentException ex) { // Who knows what is in this directory, just ignore invalid files } @@ -1855,7 +1687,7 @@ public final class CraftServer implements Server { @Override public YamlConfiguration getBukkitConfig() { - return configuration; + return BukkitConfig.config; } @Override @@ -1898,7 +1730,7 @@ public final class CraftServer implements Server { // 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."); + return BukkitConfig.permissionMessage; } // KigPaper end } diff --git a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 92c0681..5c1b0e2 100644 --- a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit; +import com.elevatemc.spigot.util.Constants; import com.elevatemc.spigot.util.Dictionary; import com.google.common.base.Preconditions; import java.io.File; @@ -1515,7 +1516,7 @@ public class CraftWorld implements World { } if ( extra == null ) { - extra = new int[0]; + extra = Constants.EMPTY_ARRAY; } packet = new PacketPlayOutWorldParticles( particle, true, (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount, extra ); } diff --git a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/Main.java b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/Main.java index 5ab1c08..1d8511b 100644 --- a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/Main.java @@ -126,29 +126,13 @@ public class Main { acceptsAll(asList("demo"), "Demo mode"); - // Spigot Start - acceptsAll(asList("S", "spigot-settings"), "File for spigot settings") + // SportPaper start + acceptsAll(asList("SP", "espigot-settings"), "File for espigot settings") .withRequiredArg() .ofType(File.class) - .defaultsTo(new File("spigot.yml")) + .defaultsTo(new File("espigot.yml")) .describedAs("Yml file"); - // Spigot End - - // PaperSpigot Start - acceptsAll(asList("paper", "paper-settings"), "File for paperspigot settings") - .withRequiredArg() - .ofType(File.class) - .defaultsTo(new File("paper.yml")) - .describedAs("Yml file"); - // PaperSpigot End - - // TacoSpigot start - acceptsAll(asList("taco", "taco-settings"), "File for tacospigot settings") - .withRequiredArg() - .ofType(File.class) - .defaultsTo(new File("taco.yml")) - .describedAs("Yml file"); - // TacoSpigot end + // SportPaper end } }; @@ -229,8 +213,7 @@ public class Main { } // Spigot End System.setProperty("library.jansi.version", "eSpigot"); // PandaSpigot - set meaningless jansi version to prevent git builds from crashing on Windows - net.techcable.tacospigot.TacoSpigotConfig.init((File) options.valueOf("taco-settings")); // TacoSpigot - load config before we load libraries to allow access while loading - System.out.println("Loading libraries, please wait..."); + System.out.println("Starting the spigot, please wait..."); MinecraftServer.main(options); } catch (Throwable t) { t.printStackTrace(); diff --git a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java index 230ae9e..7dfd3f9 100644 --- a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java +++ b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.entity; +import com.eatthepath.uuid.FastUUID; import net.minecraft.server.EntityHorse; import org.apache.commons.lang.Validate; import org.bukkit.craftbukkit.CraftServer; @@ -117,7 +118,7 @@ public class CraftHorse extends CraftAnimals implements Horse { public UUID getOwnerUUID() { try { - return UUID.fromString(getHandle().getOwnerUUID()); + return FastUUID.parseUUID(getHandle().getOwnerUUID()); } catch (IllegalArgumentException ex) { return null; } @@ -127,7 +128,7 @@ public class CraftHorse extends CraftAnimals implements Horse { if (uuid == null) { getHandle().setOwnerUUID(""); } else { - getHandle().setOwnerUUID(uuid.toString()); + getHandle().setOwnerUUID(FastUUID.toString(uuid)); } } diff --git a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 0dff03b..6aa5a2d 100644 --- a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1,6 +1,8 @@ package org.bukkit.craftbukkit.entity; +import com.elevatemc.spigot.config.eSpigotConfig; import com.elevatemc.spigot.event.PlayerHealthChangeEvent; +import com.elevatemc.spigot.util.Constants; import com.elevatemc.spigot.util.Dictionary; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; @@ -24,7 +26,6 @@ import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; -import com.elevatemc.spigot.eSpigotFeature; import net.md_5.bungee.api.chat.BaseComponent; import net.minecraft.server.*; @@ -999,7 +1000,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } //remove the hidden player from this player user list - if (!eSpigotFeature.SHOW_HIDDEN_PLAYERS_IN_TAB.isEnabled()) + if (!eSpigotConfig.showHiddenPlayersInTab) getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, other)); } @@ -1014,7 +1015,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { EntityTracker tracker = ((WorldServer) entity.world).tracker; EntityPlayer other = ((CraftPlayer) player).getHandle(); - if (!eSpigotFeature.SHOW_HIDDEN_PLAYERS_IN_TAB.isEnabled()) + if (!eSpigotConfig.showHiddenPlayersInTab) getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, other)); EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId()); @@ -1536,7 +1537,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } if ( extra == null ) { - extra = new int[0]; + extra = Constants.EMPTY_ARRAY; } packet = new PacketPlayOutWorldParticles( particle, true, (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount, extra ); } diff --git a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java index ea1d10b..e6d3c9a 100644 --- a/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java +++ b/eSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.entity; +import com.eatthepath.uuid.FastUUID; import net.minecraft.server.EntityTameableAnimal; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.AnimalTamer; @@ -20,7 +21,7 @@ public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creat public UUID getOwnerUUID() { try { - return UUID.fromString(getHandle().getOwnerUUID()); + return FastUUID.parseUUID(getHandle().getOwnerUUID()); } catch (IllegalArgumentException ex) { return null; } @@ -30,7 +31,7 @@ public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creat if (uuid == null) { getHandle().setOwnerUUID(""); } else { - getHandle().setOwnerUUID(uuid.toString()); + getHandle().setOwnerUUID(FastUUID.toString(uuid)); } } diff --git a/eSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotConfig.java b/eSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotConfig.java index 847a456..c721f8e 100644 --- a/eSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotConfig.java +++ b/eSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotConfig.java @@ -1,144 +1,61 @@ package org.github.paperspigot; -import com.google.common.base.Throwables; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; +import com.elevatemc.spigot.config.SharedConfig; import java.util.*; import java.util.logging.Level; 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; import org.bukkit.command.Command; -import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; public class PaperSpigotConfig { - private static File CONFIG_FILE; - private static final String HEADER = "This is the main configuration file for PaperSpigot.\n" - + "As you can see, there's tons to configure. Some options may impact gameplay, so use\n" - + "with caution, and make sure you know what each option does before configuring.\n" - + "\n" - + "If you need help with the configuration or have any questions related to PaperSpigot,\n" - + "join us at the IRC.\n" - + "\n" - + "IRC: #paperspigot @ irc.spi.gt ( http://irc.spi.gt/iris/?channels=PaperSpigot )\n"; - /*========================================================================*/ public static YamlConfiguration config; - static int version; static Map commands; - /*========================================================================*/ - public static void init(File configFile) + public static void init() { - CONFIG_FILE = configFile; - config = new YamlConfiguration(); - try - { - config.load ( CONFIG_FILE ); - } catch ( IOException ignored) - { - } catch ( InvalidConfigurationException ex ) - { - Bukkit.getLogger().log( Level.SEVERE, "Could not load paper.yml, please correct your syntax errors", ex ); - throw Throwables.propagate( ex ); - } - config.options().header( HEADER ); - config.options().copyDefaults( true ); - - commands = new HashMap<>(); - - version = getInt( "config-version", 9 ); - set( "config-version", 9 ); - readConfig( PaperSpigotConfig.class, null ); - } - - public static void registerCommands() - { - for ( Map.Entry entry : commands.entrySet() ) - { - MinecraftServer.getServer().server.getCommandMap().register( entry.getKey(), "PaperSpigot", entry.getValue() ); - } - } - - static void readConfig(Class clazz, Object instance) - { - for ( Method method : clazz.getDeclaredMethods() ) - { - if ( Modifier.isPrivate( method.getModifiers() ) ) - { - if ( method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE ) - { - try - { - method.setAccessible( true ); - method.invoke( instance ); - } catch ( InvocationTargetException ex ) - { - throw Throwables.propagate( ex.getCause() ); - } catch ( Exception ex ) - { - Bukkit.getLogger().log( Level.SEVERE, "Error invoking " + method, ex ); - } - } - } - } - - try - { - config.save( CONFIG_FILE ); - } catch ( IOException ex ) - { - Bukkit.getLogger().log( Level.SEVERE, "Could not save " + CONFIG_FILE, ex ); - } - } - - private static void set(String path, Object val) - { - config.set( path, val ); + config = SharedConfig.config; + commands = SharedConfig.commands; + SharedConfig.readConfig( PaperSpigotConfig.class, null ); } private static boolean getBoolean(String path, boolean def) { + path = "paper." + path; config.addDefault( path, def ); return config.getBoolean( path, config.getBoolean( path ) ); } private static double getDouble(String path, double def) { + path = "paper." + path; config.addDefault( path, def ); return config.getDouble( path, config.getDouble( path ) ); } - private static float getFloat(String path, float def) - { - // TODO: Figure out why getFloat() always returns the default value. - return (float) getDouble( path, def); - } - private static int getInt(String path, int def) { + path = "paper." + path; config.addDefault( path, def ); return config.getInt( path, config.getInt( path ) ); } private static List getList(String path, T def) { + path = "paper." + path; config.addDefault( path, def ); - return config.getList( path, config.getList( path ) ); + return (List) config.getList( path, config.getList( path ) ); } private static String getString(String path, String def) { + path = "paper." + path; config.addDefault( path, def ); return config.getString( path, config.getString( path ) ); } @@ -269,4 +186,9 @@ public class PaperSpigotConfig private static void regionCompressionAlgorithm() { regionCompressionAlgorithm = RegionFile.CompressionAlgorithm.valueOf(getString("region-compression-algo", "ZLIB").toUpperCase(Locale.ROOT)); } + + public static boolean useArraysForBlockStates; + public static void useArraysForBlockStates() { + useArraysForBlockStates = getBoolean("useArraysForBlockStates", false); + } } diff --git a/eSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java b/eSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java index 7398a6d..a6be096 100644 --- a/eSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java +++ b/eSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java @@ -1,32 +1,25 @@ package org.github.paperspigot; import java.util.List; + +import com.elevatemc.spigot.config.SharedConfig; +import net.minecraft.server.MinecraftServer; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; public class PaperSpigotWorldConfig { + private static YamlConfiguration config; + private static boolean verbose; - private final String worldName; - private final YamlConfiguration config; - private boolean verbose; - - public PaperSpigotWorldConfig(String worldName) + public static void init() { - this.worldName = worldName; - this.config = PaperSpigotConfig.config; - init(); + config = SharedConfig.config; + verbose = getBoolean( "verbose", true ); + SharedConfig.readConfig( PaperSpigotWorldConfig.class, null ); } - public void init() - { - this.verbose = getBoolean( "verbose", true ); - - log( "-------- World Settings For [" + worldName + "] --------" ); - PaperSpigotConfig.readConfig( PaperSpigotWorldConfig.class, this ); - } - - private void log(String s) + private static void log(String s) { if ( verbose ) { @@ -34,98 +27,93 @@ public class PaperSpigotWorldConfig } } - private void set(String path, Object val) + private static boolean getBoolean(String path, boolean def) { - config.set( "world-settings.default." + path, val ); + config.addDefault( "paper.world-settings." + path, def ); + return config.getBoolean( "paper.world-settings." + path, config.getBoolean( "paper.world-settings." + path ) ); } - private boolean getBoolean(String path, boolean def) + private static double getDouble(String path, double def) { - config.addDefault( "world-settings.default." + path, def ); - return config.getBoolean( "world-settings." + worldName + "." + path, config.getBoolean( "world-settings.default." + path ) ); + config.addDefault( "paper.world-settings." + path, def ); + return config.getDouble( "paper.world-settings." + path, config.getDouble( "paper.world-settings." + path ) ); } - private double getDouble(String path, double def) + private static int getInt(String path, int def) { - config.addDefault( "world-settings.default." + path, def ); - return config.getDouble( "world-settings." + worldName + "." + path, config.getDouble( "world-settings.default." + path ) ); + config.addDefault( "paper.world-settings." + path, def ); + return config.getInt( "paper.world-settings." + path, config.getInt( "paper.world-settings." + path ) ); } - private int getInt(String path, int def) - { - config.addDefault( "world-settings.default." + path, def ); - return config.getInt( "world-settings." + worldName + "." + path, config.getInt( "world-settings.default." + path ) ); - } - - private float getFloat(String path, float def) + private static float getFloat(String path, float def) { // TODO: Figure out why getFloat() always returns the default value. - return (float) getDouble( path, def); + return (float) getDouble( path, (double) def ); } - private List getList(String path, T def) + private static List getList(String path, T def) { - config.addDefault( "world-settings.default." + path, def ); - return config.getList( "world-settings." + worldName + "." + path, config.getList( "world-settings.default." + path ) ); + config.addDefault( "paper.world-settings." + path, def ); + return (List) config.getList( "paper.world-settings." + path, config.getList( "paper.world-settings." + path ) ); } - private String getString(String path, String def) + private static String getString(String path, String def) { - config.addDefault( "world-settings.default." + path, def ); - return config.getString( "world-settings." + worldName + "." + path, config.getString( "world-settings.default." + path ) ); + config.addDefault( "paper.world-settings." + path, def ); + return config.getString( "paper.world-settings." + path, config.getString( "paper.world-settings." + path ) ); } - public boolean allowUndeadHorseLeashing; - private void allowUndeadHorseLeashing() + public static boolean allowUndeadHorseLeashing; + private static void allowUndeadHorseLeashing() { allowUndeadHorseLeashing = getBoolean( "allow-undead-horse-leashing", false ); log( "Allow undead horse types to be leashed: " + allowUndeadHorseLeashing ); } - public double squidMinSpawnHeight; - public double squidMaxSpawnHeight; - private void squidSpawnHeight() + public static double squidMinSpawnHeight; + public static double squidMaxSpawnHeight; + private static void squidSpawnHeight() { squidMinSpawnHeight = getDouble( "squid-spawn-height.minimum", 45.0D ); squidMaxSpawnHeight = getDouble( "squid-spawn-height.maximum", 63.0D ); log( "Squids will spawn between Y: " + squidMinSpawnHeight + " and Y: " + squidMaxSpawnHeight ); } - public float playerBlockingDamageMultiplier; - private void playerBlockingDamageMultiplier() + public static float playerBlockingDamageMultiplier; + private static void playerBlockingDamageMultiplier() { playerBlockingDamageMultiplier = getFloat( "player-blocking-damage-multiplier", 0.5F ); log( "Player blocking damage multiplier set to " + playerBlockingDamageMultiplier ); } - public int cactusMaxHeight; - public int reedMaxHeight; - private void blockGrowthHeight() + public static int cactusMaxHeight; + public static int reedMaxHeight; + private static void blockGrowthHeight() { cactusMaxHeight = getInt( "max-growth-height.cactus", 3 ); reedMaxHeight = getInt( "max-growth-height.reeds", 3 ); log( "Max height for cactus growth " + cactusMaxHeight + ". Max height for reed growth " + reedMaxHeight ); } - public int fishingMinTicks; - public int fishingMaxTicks; - private void fishingTickRange() + public static int fishingMinTicks; + public static int fishingMaxTicks; + private static void fishingTickRange() { fishingMinTicks = getInt( "fishing-time-range.MinimumTicks", 100 ); fishingMaxTicks = getInt( "fishing-time-range.MaximumTicks", 900 ); } - public float blockBreakExhaustion; - public float playerSwimmingExhaustion; - private void exhaustionValues() + public static float blockBreakExhaustion; + public static float playerSwimmingExhaustion; + private static void exhaustionValues() { blockBreakExhaustion = getFloat( "player-exhaustion.block-break", 0.025F ); playerSwimmingExhaustion = getFloat( "player-exhaustion.swimming", 0.015F ); } - public int softDespawnDistance; - public int hardDespawnDistance; - private void despawnDistances() + public static int softDespawnDistance; + public static int hardDespawnDistance; + private static void despawnDistances() { softDespawnDistance = getInt( "despawn-ranges.soft", 32 ); // 32^2 = 1024, Minecraft Default hardDespawnDistance = getInt( "despawn-ranges.hard", 128 ); // 128^2 = 16384, Minecraft Default; @@ -140,15 +128,15 @@ public class PaperSpigotWorldConfig hardDespawnDistance = hardDespawnDistance*hardDespawnDistance; } - public boolean keepSpawnInMemory; - private void keepSpawnInMemory() + public static boolean keepSpawnInMemory; + private static void keepSpawnInMemory() { keepSpawnInMemory = getBoolean( "keep-spawn-loaded", true ); log( "Keep spawn chunk loaded: " + keepSpawnInMemory ); } - public int fallingBlockHeightNerf; - private void fallingBlockheightNerf() + public static int fallingBlockHeightNerf; + private static void fallingBlockheightNerf() { fallingBlockHeightNerf = getInt( "falling-block-height-nerf", 0 ); if ( fallingBlockHeightNerf != 0 ) @@ -157,8 +145,8 @@ public class PaperSpigotWorldConfig } } - public int tntEntityHeightNerf; - private void tntEntityHeightNerf() + public static int tntEntityHeightNerf; + private static void tntEntityHeightNerf() { tntEntityHeightNerf = getInt( "tnt-entity-height-nerf", 0 ); if ( tntEntityHeightNerf != 0 ) @@ -167,49 +155,49 @@ public class PaperSpigotWorldConfig } } - public int waterOverLavaFlowSpeed; - private void waterOverLavaFlowSpeed() + public static int waterOverLavaFlowSpeed; + private static void waterOverLavaFlowSpeed() { waterOverLavaFlowSpeed = getInt( "water-over-lava-flow-speed", 5 ); log( "Water over lava flow speed: " + waterOverLavaFlowSpeed ); } - public boolean removeInvalidMobSpawnerTEs; - private void removeInvalidMobSpawnerTEs() + public static boolean removeInvalidMobSpawnerTEs; + private static void removeInvalidMobSpawnerTEs() { removeInvalidMobSpawnerTEs = getBoolean( "remove-invalid-mob-spawner-tile-entities", true ); log( "Remove invalid mob spawner tile entities: " + removeInvalidMobSpawnerTEs ); } - public boolean removeUnloadedEnderPearls; - public boolean removeUnloadedTNTEntities; - public boolean removeUnloadedFallingBlocks; - private void removeUnloaded() + public static boolean removeUnloadedEnderPearls; + public static boolean removeUnloadedTNTEntities; + public static boolean removeUnloadedFallingBlocks; + private static void removeUnloaded() { removeUnloadedEnderPearls = getBoolean( "remove-unloaded.enderpearls", true ); removeUnloadedTNTEntities = getBoolean( "remove-unloaded.tnt-entities", true ); removeUnloadedFallingBlocks = getBoolean( "remove-unloaded.falling-blocks", true ); } - public boolean boatsDropBoats; - public boolean disablePlayerCrits; - public boolean disableChestCatDetection; - private void mechanicsChanges() + public static boolean boatsDropBoats; + public static boolean disablePlayerCrits; + public static boolean disableChestCatDetection; + private static void mechanicsChanges() { boatsDropBoats = getBoolean( "game-mechanics.boats-drop-boats", false ); disablePlayerCrits = getBoolean( "game-mechanics.disable-player-crits", false ); disableChestCatDetection = getBoolean( "game-mechanics.disable-chest-cat-detection", false ); } - public boolean netherVoidTopDamage; - private void nethervoidTopDamage() + public static boolean netherVoidTopDamage; + private static void nethervoidTopDamage() { netherVoidTopDamage = getBoolean( "nether-ceiling-void-damage", false ); } - public int tickNextTickCap; - public boolean tickNextTickListCapIgnoresRedstone; - private void tickNextTickCap() + public static int tickNextTickCap; + public static boolean tickNextTickListCapIgnoresRedstone; + private static void tickNextTickCap() { tickNextTickCap = getInt( "tick-next-tick-list-cap", 10000 ); // Higher values will be friendlier to vanilla style mechanics (to a point) but may hurt performance tickNextTickListCapIgnoresRedstone = getBoolean( "tick-next-tick-list-cap-ignores-redstone", false ); // Redstone TickNextTicks will always bypass the preceding cap. @@ -217,40 +205,40 @@ public class PaperSpigotWorldConfig log( "WorldServer TickNextTickList cap always processes redstone: " + tickNextTickListCapIgnoresRedstone ); } - public boolean useAsyncLighting; - private void useAsyncLighting() + public static boolean useAsyncLighting; + private static void useAsyncLighting() { useAsyncLighting = getBoolean( "use-async-lighting", false ); log( "World async lighting: " + useAsyncLighting ); } - public boolean disableEndCredits; - private void disableEndCredits() + public static boolean disableEndCredits; + private static void disableEndCredits() { disableEndCredits = getBoolean( "game-mechanics.disable-end-credits", false ); } - public boolean loadUnloadedEnderPearls; - public boolean loadUnloadedTNTEntities; - public boolean loadUnloadedFallingBlocks; - private void loadUnloaded() + public static boolean loadUnloadedEnderPearls; + public static boolean loadUnloadedTNTEntities; + public static boolean loadUnloadedFallingBlocks; + private static void loadUnloaded() { loadUnloadedEnderPearls = getBoolean( "load-chunks.enderpearls", false ); loadUnloadedTNTEntities = getBoolean( "load-chunks.tnt-entities", false ); loadUnloadedFallingBlocks = getBoolean( "load-chunks.falling-blocks", false ); } - public boolean generateCanyon; - public boolean generateCaves; - public boolean generateDungeon; - public boolean generateFortress; - public boolean generateMineshaft; - public boolean generateMonument; - public boolean generateStronghold; - public boolean generateTemple; - public boolean generateVillage; - public boolean generateFlatBedrock; - private void generatorSettings() + public static boolean generateCanyon; + public static boolean generateCaves; + public static boolean generateDungeon; + public static boolean generateFortress; + public static boolean generateMineshaft; + public static boolean generateMonument; + public static boolean generateStronghold; + public static boolean generateTemple; + public static boolean generateVillage; + public static boolean generateFlatBedrock; + private static void generatorSettings() { generateCanyon = getBoolean( "generator-settings.canyon", true ); generateCaves = getBoolean( "generator-settings.caves", true ); @@ -264,152 +252,198 @@ public class PaperSpigotWorldConfig generateFlatBedrock = getBoolean( "generator-settings.flat-bedrock", false ); } - public boolean fixCannons; - private void fixCannons() + public static boolean fixCannons; + private static void fixCannons() { - // TODO: Remove migrations after most users have upgraded. - if ( PaperSpigotConfig.version < 9 ) - { - // Migrate default value - - boolean value = config.getBoolean( "world-settings.default.fix-cannons", false ); - if ( !value ) value = config.getBoolean( "world-settings.default.tnt-gameplay.fix-directional-bias", false ); - if ( !value ) value = !config.getBoolean( "world-settings.default.tnt-gameplay.moves-in-water", true ); - if ( !value ) value = config.getBoolean( "world-settings.default.tnt-gameplay.legacy-explosion-height", false ); - if ( value ) config.set( "world-settings.default.fix-cannons", true ); - - if ( config.contains( "world-settings.default.tnt-gameplay" ) ) - { - config.getDefaults().set( "world-settings.default.tnt-gameplay", null); - config.set( "world-settings.default.tnt-gameplay", null ); - } - - // Migrate world setting - - value = config.getBoolean( "world-settings." + worldName + ".fix-cannons", false ); - if ( !value ) value = config.getBoolean( "world-settings." + worldName + ".tnt-gameplay.fix-directional-bias", false ); - if ( !value ) value = !config.getBoolean( "world-settings." + worldName + ".tnt-gameplay.moves-in-water", true ); - if ( !value ) value = config.getBoolean( "world-settings." + worldName + ".tnt-gameplay.legacy-explosion-height", false ); - if ( value ) config.set( "world-settings." + worldName + ".fix-cannons", true ); - - if ( config.contains( "world-settings." + worldName + ".tnt-gameplay" ) ) - { - config.getDefaults().set( "world-settings." + worldName + ".tnt-gameplay", null); - config.set( "world-settings." + worldName + ".tnt-gameplay", null ); - } - } - fixCannons = getBoolean( "fix-cannons", false ); - log( "Fix TNT cannons: " + fixCannons ); } - public boolean fallingBlocksCollideWithSigns; - private void fallingBlocksCollideWithSigns() + public static boolean fallingBlocksCollideWithSigns; + private static void fallingBlocksCollideWithSigns() { fallingBlocksCollideWithSigns = getBoolean( "falling-blocks-collide-with-signs", false ); } - public boolean optimizeExplosions; - private void optimizeExplosions() + public static boolean optimizeExplosions; + private static void optimizeExplosions() { optimizeExplosions = getBoolean( "optimize-explosions", false ); } - public boolean fastDrainLava; - public boolean fastDrainWater; - private void fastDraining() + public static boolean fastDrainLava; + public static boolean fastDrainWater; + private static void fastDraining() { fastDrainLava = getBoolean( "fast-drain.lava", false ); fastDrainWater = getBoolean( "fast-drain.water", false ); } - public int lavaFlowSpeedNormal; - public int lavaFlowSpeedNether; - private void lavaFlowSpeed() + public static int lavaFlowSpeedNormal; + public static int lavaFlowSpeedNether; + private static void lavaFlowSpeed() { lavaFlowSpeedNormal = getInt( "lava-flow-speed.normal", 30 ); lavaFlowSpeedNether = getInt( "lava-flow-speed.nether", 10 ); } - public boolean disableExplosionKnockback; - private void disableExplosionKnockback() + public static boolean disableExplosionKnockback; + private static void disableExplosionKnockback() { disableExplosionKnockback = getBoolean( "disable-explosion-knockback", false ); } - public boolean disableThunder; - private void disableThunder() + public static boolean disableThunder; + private static void disableThunder() { disableThunder = getBoolean( "disable-thunder", false ); } - public boolean disableIceAndSnow; - private void disableIceAndSnow() + public static boolean disableIceAndSnow; + private static void disableIceAndSnow() { disableIceAndSnow = getBoolean( "disable-ice-and-snow", false ); } - public boolean disableMoodSounds; - private void disableMoodSounds() + public static boolean disableMoodSounds; + private static void disableMoodSounds() { disableMoodSounds = getBoolean( "disable-mood-sounds", false ); } - public int mobSpawnerTickRate; - private void mobSpawnerTickRate() + public static int mobSpawnerTickRate; + private static void mobSpawnerTickRate() { mobSpawnerTickRate = getInt( "mob-spawner-tick-rate", 1 ); } - public boolean cacheChunkMaps; - private void cacheChunkMaps() + public static boolean cacheChunkMaps; + private static void cacheChunkMaps() { cacheChunkMaps = getBoolean( "cache-chunk-maps", false ); } - public int containerUpdateTickRate; - private void containerUpdateTickRate() + public static int containerUpdateTickRate; + private static void containerUpdateTickRate() { containerUpdateTickRate = getInt( "container-update-tick-rate", 1 ); } - public float tntExplosionVolume; - private void tntExplosionVolume() + public static float tntExplosionVolume; + private static void tntExplosionVolume() { tntExplosionVolume = getFloat( "tnt-explosion-volume", 4.0F ); } - public boolean useHopperCheck; - private void useHopperCheck() + public static boolean useHopperCheck; + private static void useHopperCheck() { useHopperCheck = getBoolean( "use-hopper-check", false ); } - public boolean allChunksAreSlimeChunks; - private void allChunksAreSlimeChunks() + public static boolean allChunksAreSlimeChunks; + private static void allChunksAreSlimeChunks() { allChunksAreSlimeChunks = getBoolean( "all-chunks-are-slime-chunks", false ); } - public boolean allowBlockLocationTabCompletion; - private void allowBlockLocationTabCompletion() + public static boolean allowBlockLocationTabCompletion; + private static void allowBlockLocationTabCompletion() { allowBlockLocationTabCompletion = getBoolean( "allow-block-location-tab-completion", true ); } - public int portalSearchRadius; - private void portalSearchRadius() + public static int portalSearchRadius; + private static void portalSearchRadius() { portalSearchRadius = getInt("portal-search-radius", 128); } - public boolean removeCorruptTEs; - private void removeCorruptTEs() { + public static boolean disableTeleportationSuffocationCheck; + private static void disableTeleportationSuffocationCheck() + { + disableTeleportationSuffocationCheck = getBoolean("disable-teleportation-suffocation-check", false); + } + + public static boolean useInhabitedTime = true; + private static void useInhabitedTime() { + useInhabitedTime = getBoolean("use-chunk-inhabited-timer", true); + } + + public static int grassUpdateRate = 1; + private static void grassUpdateRate() { + grassUpdateRate = Math.max(0, getInt("grass-spread-tick-rate", grassUpdateRate)); + log("Grass Spread Tick Rate: " + grassUpdateRate); + } + + public static int autoSavePeriod = -1; + private static void autoSavePeriod() { + autoSavePeriod = getInt("auto-save-interval", -1); + if (autoSavePeriod > 0) { + log("Auto Save Interval: " +autoSavePeriod + " (" + (autoSavePeriod / 20) + "s)"); + } else if (autoSavePeriod < 0) { + autoSavePeriod = MinecraftServer.getServer().autosavePeriod; + } + } + + public static int maxAutoSaveChunksPerTick = 24; + private static void maxAutoSaveChunksPerTick() { + maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24); + } + + public static boolean removeCorruptTEs = false; + private static void removeCorruptTEs() { removeCorruptTEs = getBoolean("remove-corrupt-tile-entities", false); } - public boolean armorStandEntityLookups; - private void armorStandEntityLookups() { + public static boolean armorStandEntityLookups = true; + private static void armorStandEntityLookups() { armorStandEntityLookups = getBoolean("armor-stands-do-collision-entity-lookups", true); } + + public static boolean isRedstoneFireBPE; + private void isRedstoneFireBPE() { + isRedstoneFireBPE = getBoolean("redstone-fire-BlockPhysicsEvent", true); + } + + public static boolean isHopperPushBased; + private static void isHopperPushBased() { + isHopperPushBased = getBoolean("hopper.push-based", true); + } + + public static boolean isHopperFireIMIE; + private static void isHopperFireIMIE() { + isHopperFireIMIE = getBoolean("hopper.fire-InventoryMoveItemEvent", true); + } + + public static boolean optimizeArmorStandMovement; + private static void isArmorStandMoveWithoutGravity() { + optimizeArmorStandMovement = getBoolean("armor-stand.optimize-movement", false); // Doesn't fully emulate vanilla behavior, see issue #1 + } + + public static boolean nonPlayerEntitiesOnScoreboards = false; + private static void nonPlayerEntitiesOnScoreboards() { + nonPlayerEntitiesOnScoreboards = getBoolean("allow-non-player-entities-on-scoreboards", false); + } + + public static boolean grassIgnoresLight = false; + private static void isGrassIgnoresLight() { + grassIgnoresLight = getBoolean("grass-ignores-light", false); + } + + public static boolean optimizeTntMovement = false; + private static void isOptimizeTnt() { + optimizeTntMovement = getBoolean("tnt.optimize-movement", false); // May not fully emulate vanilla behavior + } + public static boolean optimizeLiquidExplosions = true; + private static void isOptimizeLiquidExplosions() { + optimizeLiquidExplosions = getBoolean("tnt.optimize-liquid-explosions", true); // This seems like a pretty sane default + } + + public static boolean fixEastWest; + private void fixEastWest() { + fixEastWest = getBoolean("fix-east-west-cannoning", false); + } + + public static boolean disableFallingBlockStackingAt256; + private void DisableFallingBlockStackingAt256() { disableFallingBlockStackingAt256 = getBoolean("disable-falling-block-stacking-at-256", false);} } diff --git a/eSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java b/eSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java index bcae756..da25c63 100644 --- a/eSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java +++ b/eSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java @@ -1,24 +1,14 @@ package org.spigotmc; -import com.google.common.base.Throwables; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.TimeUnit; import java.util.logging.Level; + +import com.elevatemc.spigot.config.SharedConfig; import gnu.trove.map.hash.TObjectIntHashMap; import com.google.common.collect.Lists; import net.minecraft.server.AttributeRanged; import net.minecraft.server.GenericAttributes; -import net.minecraft.server.MinecraftServer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.Configuration; @@ -26,141 +16,53 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import co.aikar.timings.Timings; import co.aikar.timings.TimingsManager; public class SpigotConfig { - - private static File CONFIG_FILE; - private static final String HEADER = "This is the main configuration file for Spigot.\n" - + "As you can see, there's tons to configure. Some options may impact gameplay, so use\n" - + "with caution, and make sure you know what each option does before configuring.\n" - + "For a reference for any variable inside this file, check out the Spigot wiki at\n" - + "http://www.spigotmc.org/wiki/spigot-configuration/\n" - + "\n" - + "If you need help with the configuration or have any questions related to Spigot,\n" - + "join us at the IRC or drop by our forums and leave a post.\n" - + "\n" - + "IRC: #spigot @ irc.spi.gt ( http://www.spigotmc.org/pages/irc/ )\n" - + "Forums: http://www.spigotmc.org/\n"; - /*========================================================================*/ public static YamlConfiguration config; - static int version; static Map commands; - /*========================================================================*/ - private static Metrics metrics; - public static void init(File configFile) + public static void init() { - CONFIG_FILE = configFile; - config = new YamlConfiguration(); - try - { - config.load( CONFIG_FILE ); - } catch ( IOException ignored) - { - } catch ( InvalidConfigurationException ex ) - { - Bukkit.getLogger().log( Level.SEVERE, "Could not load spigot.yml, please correct your syntax errors", ex ); - throw Throwables.propagate( ex ); - } - - config.options().header( HEADER ); - config.options().copyDefaults( true ); - - commands = new HashMap<>(); - - version = getInt( "config-version", 8 ); - set( "config-version", 8 ); - readConfig( SpigotConfig.class, null ); - } - - public static void registerCommands() - { - for ( Map.Entry entry : commands.entrySet() ) - { - MinecraftServer.getServer().server.getCommandMap().register( entry.getKey(), "Spigot", entry.getValue() ); - } - - if ( metrics == null ) - { - try - { - metrics = new Metrics(); - metrics.start(); - } catch ( IOException ex ) - { - Bukkit.getServer().getLogger().log( Level.SEVERE, "Could not start metrics service", ex ); - } - } - } - - static void readConfig(Class clazz, Object instance) - { - for ( Method method : clazz.getDeclaredMethods() ) - { - if ( Modifier.isPrivate( method.getModifiers() ) ) - { - if ( method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE ) - { - try - { - method.setAccessible( true ); - method.invoke( instance ); - } catch ( InvocationTargetException ex ) - { - throw Throwables.propagate( ex.getCause() ); - } catch ( Exception ex ) - { - Bukkit.getLogger().log( Level.SEVERE, "Error invoking " + method, ex ); - } - } - } - } - - try - { - config.save( CONFIG_FILE ); - } catch ( IOException ex ) - { - Bukkit.getLogger().log( Level.SEVERE, "Could not save " + CONFIG_FILE, ex ); - } - } - - private static void set(String path, Object val) - { - config.set( path, val ); + config = SharedConfig.config; + commands = SharedConfig.commands; + SharedConfig.readConfig( SpigotConfig.class, null ); } private static boolean getBoolean(String path, boolean def) { + path = "spigot." + path; config.addDefault( path, def ); return config.getBoolean( path, config.getBoolean( path ) ); } private static int getInt(String path, int def) { + path = "spigot." + path; config.addDefault( path, def ); return config.getInt( path, config.getInt( path ) ); } private static List getList(String path, T def) { + path = "spigot." + path; config.addDefault( path, def ); - return config.getList( path, config.getList( path ) ); + return (List) config.getList( path, config.getList( path ) ); } private static String getString(String path, String def) { + path = "spigot." + path; config.addDefault( path, def ); return config.getString( path, config.getString( path ) ); } private static double getDouble(String path, double def) { + path = "spigot." + path; config.addDefault( path, def ); return config.getDouble( path, config.getDouble( path ) ); } @@ -174,22 +76,12 @@ public class SpigotConfig public static int tabComplete; private static void tabComplete() { - if ( version < 6 ) - { - boolean oldValue = getBoolean( "commands.tab-complete", true ); - if ( oldValue ) - { - set( "commands.tab-complete", 0 ); - } else - { - set( "commands.tab-complete", -1 ); - } - } tabComplete = getInt( "commands.tab-complete", 0 ); } public static String whitelistMessage; public static String unknownCommandMessage; + public static String internalErrorMessage; public static String serverFullMessage; public static String outdatedClientMessage = "Outdated client! Please use {0}"; public static String outdatedServerMessage = "Outdated server! I\'m still on {0}"; @@ -199,14 +91,9 @@ public class SpigotConfig } private static void messages() { - if (version < 8) - { - set( "messages.outdated-client", outdatedClientMessage ); - set( "messages.outdated-server", outdatedServerMessage ); - } - whitelistMessage = transform( getString( "messages.whitelist", "You are not whitelisted on this server!" ) ); unknownCommandMessage = transform( getString( "messages.unknown-command", "Unknown command. Type \"/help\" for help." ) ); + internalErrorMessage = transform( getString( "messages.internal-error", "&cAn internal error occurred while attempting to perform this command" ) ); serverFullMessage = transform( getString( "messages.server-full", "The server is full!" ) ); outdatedClientMessage = transform( getString( "messages.outdated-client", outdatedClientMessage ) ); outdatedServerMessage = transform( getString( "messages.outdated-server", outdatedServerMessage ) ); @@ -226,13 +113,14 @@ public class SpigotConfig WatchdogThread.doStart( timeoutTime, restartOnCrash ); } + public static boolean fetchSkulls = true; + private static void fetchSkulls() + { + fetchSkulls = getBoolean("settings.fetch-skulls", fetchSkulls); + } + public static boolean bungee; private static void bungee() { - if ( version < 4 ) - { - set( "settings.bungeecord", false ); - System.out.println( "Oudated config, disabling BungeeCord support!" ); - } bungee = getBoolean( "settings.bungeecord", false ); } @@ -282,16 +170,16 @@ public class SpigotConfig } public static boolean disableStatSaving; - public static TObjectIntHashMap forcedStats = new TObjectIntHashMap<>(); + public static TObjectIntHashMap forcedStats = new TObjectIntHashMap(); private static void stats() { disableStatSaving = getBoolean( "stats.disable-saving", false ); - if ( !config.contains( "stats.forced-stats" ) ) { - config.createSection( "stats.forced-stats" ); + if ( !config.contains( "spigot.stats.forced-stats" ) ) { + config.createSection( "spigot.stats.forced-stats" ); } - ConfigurationSection section = config.getConfigurationSection( "stats.forced-stats" ); + ConfigurationSection section = config.getConfigurationSection( "spigot.stats.forced-stats" ); for ( String name : section.getKeys( true ) ) { if ( section.isInt( name ) ) @@ -324,10 +212,7 @@ public class SpigotConfig public static List spamExclusions; private static void spamExclusions() { - spamExclusions = getList( "commands.spam-exclusions", Arrays.asList( new String[] - { - "/skill" - } ) ); + spamExclusions = getList( "commands.spam-exclusions", Collections.singletonList("/skill")); } public static boolean silentCommandBlocks; @@ -345,21 +230,16 @@ public class SpigotConfig public static Set replaceCommands; private static void replaceCommands() { - if ( config.contains( "replace-commands" ) ) - { - set( "commands.replace-commands", config.getStringList( "replace-commands" ) ); - config.set( "replace-commands", null ); - } - replaceCommands = new HashSet<>((List) getList("commands.replace-commands", - Arrays.asList("setblock", "summon", "testforblock", "tellraw"))); + replaceCommands = new HashSet( (List) getList( "commands.replace-commands", + Arrays.asList( "setblock", "summon", "testforblock", "tellraw" ) ) ); } - + public static int userCacheCap; private static void userCacheCap() { userCacheCap = getInt( "settings.user-cache-size", 1000 ); } - + public static boolean saveUserCacheOnStopOnly; private static void saveUserCacheOnStopOnly() { diff --git a/eSpigot-Server/src/main/java/org/spigotmc/SpigotWorldConfig.java b/eSpigot-Server/src/main/java/org/spigotmc/SpigotWorldConfig.java index 76db455..880780b 100644 --- a/eSpigot-Server/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/eSpigot-Server/src/main/java/org/spigotmc/SpigotWorldConfig.java @@ -2,32 +2,25 @@ package org.spigotmc; import java.util.Arrays; import java.util.List; + +import com.elevatemc.spigot.config.SharedConfig; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; public class SpigotWorldConfig { + private static YamlConfiguration config; + private static boolean verbose; - private final String worldName; - private final YamlConfiguration config; - private boolean verbose; - - public SpigotWorldConfig(String worldName) + public static void init() { - this.worldName = worldName; - this.config = SpigotConfig.config; - init(); + config = SharedConfig.config; + verbose = getBoolean( "verbose", true ); + + SharedConfig.readConfig( SpigotWorldConfig.class, null ); } - public void init() - { - this.verbose = getBoolean( "verbose", true ); - - log( "-------- World Settings For [" + worldName + "] --------" ); - SpigotConfig.readConfig( SpigotWorldConfig.class, this ); - } - - private void log(String s) + private static void log(String s) { if ( verbose ) { @@ -35,44 +28,39 @@ public class SpigotWorldConfig } } - private void set(String path, Object val) + private static boolean getBoolean(String path, boolean def) { - config.set( "world-settings.default." + path, val ); + config.addDefault( "spigot.world-settings." + path, def ); + return config.getBoolean( "spigot.world-settings." + path, config.getBoolean( "spigot.world-settings." + path ) ); } - private boolean getBoolean(String path, boolean def) + private static double getDouble(String path, double def) { - config.addDefault( "world-settings.default." + path, def ); - return config.getBoolean( "world-settings." + worldName + "." + path, config.getBoolean( "world-settings.default." + path ) ); + config.addDefault( "spigot.world-settings." + path, def ); + return config.getDouble( "spigot.world-settings." + path, config.getDouble( "spigot.world-settings." + path ) ); } - private double getDouble(String path, double def) + private static int getInt(String path, int def) { - config.addDefault( "world-settings.default." + path, def ); - return config.getDouble( "world-settings." + worldName + "." + path, config.getDouble( "world-settings.default." + path ) ); + config.addDefault( "spigot.world-settings." + path, def ); + return config.getInt( "spigot.world-settings." + path, config.getInt( "spigot.world-settings." + path ) ); } - private int getInt(String path, int def) + private static List getList(String path, T def) { - config.addDefault( "world-settings.default." + path, def ); - return config.getInt( "world-settings." + worldName + "." + path, config.getInt( "world-settings.default." + path ) ); + config.addDefault( "spigot.world-settings." + path, def ); + return (List) config.getList( "spigot.world-settings." + path, config.getList( "spigot.world-settings." + path ) ); } - private List getList(String path, T def) + private static String getString(String path, String def) { - config.addDefault( "world-settings.default." + path, def ); - return config.getList( "world-settings." + worldName + "." + path, config.getList( "world-settings.default." + path ) ); + config.addDefault( "spigot.world-settings." + path, def ); + return config.getString( "spigot.world-settings." + path, config.getString( "spigot.world-settings." + path ) ); } - private String getString(String path, String def) - { - config.addDefault( "world-settings.default." + path, def ); - return config.getString( "world-settings." + worldName + "." + path, config.getString( "world-settings.default." + path ) ); - } - - public int chunksPerTick; - public boolean clearChunksOnTick; - private void chunksPerTick() + public static int chunksPerTick; + public static boolean clearChunksOnTick; + private static void chunksPerTick() { chunksPerTick = getInt( "chunks-per-tick", 650 ); log( "Chunks to Grow per Tick: " + chunksPerTick ); @@ -82,15 +70,15 @@ public class SpigotWorldConfig } // Crop growth rates - public int cactusModifier; - public int caneModifier; - public int melonModifier; - public int mushroomModifier; - public int pumpkinModifier; - public int saplingModifier; - public int wheatModifier; - public int wartModifier; - private int getAndValidateGrowth(String crop) + public static int cactusModifier; + public static int caneModifier; + public static int melonModifier; + public static int mushroomModifier; + public static int pumpkinModifier; + public static int saplingModifier; + public static int wheatModifier; + public static int wartModifier; + private static int getAndValidateGrowth(String crop) { int modifier = getInt( "growth." + crop.toLowerCase() + "-modifier", 100 ); if ( modifier == 0 ) @@ -102,7 +90,7 @@ public class SpigotWorldConfig return modifier; } - private void growthModifiers() + private static void growthModifiers() { cactusModifier = getAndValidateGrowth( "Cactus" ); caneModifier = getAndValidateGrowth( "Cane" ); @@ -114,38 +102,38 @@ public class SpigotWorldConfig wartModifier = getAndValidateGrowth( "NetherWart" ); } - public double itemMerge; - private void itemMerge() + public static double itemMerge; + private static void itemMerge() { itemMerge = getDouble("merge-radius.item", 2.5 ); log( "Item Merge Radius: " + itemMerge ); } - public double expMerge; - private void expMerge() + public static double expMerge; + private static void expMerge() { expMerge = getDouble("merge-radius.exp", 3.0 ); log( "Experience Merge Radius: " + expMerge ); } - public int viewDistance; - private void viewDistance() + public static int viewDistance; + private static void viewDistance() { viewDistance = getInt( "view-distance", Bukkit.getViewDistance() ); log( "View Distance: " + viewDistance ); } - public byte mobSpawnRange; - private void mobSpawnRange() + public static byte mobSpawnRange; + private static void mobSpawnRange() { mobSpawnRange = (byte) getInt( "mob-spawn-range", 4 ); log( "Mob Spawn Range: " + mobSpawnRange ); } - public int animalActivationRange = 32; - public int monsterActivationRange = 32; - public int miscActivationRange = 16; - private void activationRange() + public static int animalActivationRange = 32; + public static int monsterActivationRange = 32; + public static int miscActivationRange = 16; + private static void activationRange() { animalActivationRange = getInt( "entity-activation-range.animals", animalActivationRange ); monsterActivationRange = getInt( "entity-activation-range.monsters", monsterActivationRange ); @@ -153,12 +141,12 @@ public class SpigotWorldConfig log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Mi " + miscActivationRange ); } - public int playerTrackingRange = 48; - public int animalTrackingRange = 48; - public int monsterTrackingRange = 48; - public int miscTrackingRange = 32; - public int otherTrackingRange = 64; - private void trackingRange() + public static int playerTrackingRange = 48; + public static int animalTrackingRange = 48; + public static int monsterTrackingRange = 48; + public static int miscTrackingRange = 32; + public static int otherTrackingRange = 64; + private static void trackingRange() { playerTrackingRange = getInt( "entity-tracking-range.players", playerTrackingRange ); animalTrackingRange = getInt( "entity-tracking-range.animals", animalTrackingRange ); @@ -168,10 +156,10 @@ public class SpigotWorldConfig log( "Entity Tracking Range: Pl " + playerTrackingRange + " / An " + animalTrackingRange + " / Mo " + monsterTrackingRange + " / Mi " + miscTrackingRange + " / Other " + otherTrackingRange ); } - public int hopperTransfer; - public int hopperCheck; - public int hopperAmount; - private void hoppers() + public static int hopperTransfer; + public static int hopperCheck; + public static int hopperAmount; + private static void hoppers() { // Set the tick delay between hopper item movements hopperTransfer = getInt( "ticks-per.hopper-transfer", 8 ); @@ -183,16 +171,16 @@ public class SpigotWorldConfig log( "Hopper Transfer: " + hopperTransfer + " Hopper Check: " + hopperCheck + " Hopper Amount: " + hopperAmount ); } - public boolean randomLightUpdates; - private void lightUpdates() + public static boolean randomLightUpdates; + private static void lightUpdates() { randomLightUpdates = getBoolean( "random-light-updates", false ); log( "Random Lighting Updates: " + randomLightUpdates ); } - public boolean saveStructureInfo; - public boolean saveMineshaftStructureInfo; // Migot - private void structureInfo() + public static boolean saveStructureInfo; + public static boolean saveMineshaftStructureInfo; // Migot + private static void structureInfo() { saveStructureInfo = getBoolean( "save-structure-info", true ); log( "Structure Info Saving: " + saveStructureInfo ); @@ -207,113 +195,103 @@ public class SpigotWorldConfig } } - public int itemDespawnRate; - private void itemDespawnRate() + public static int itemDespawnRate; + private static void itemDespawnRate() { itemDespawnRate = getInt( "item-despawn-rate", 6000 ); log( "Item Despawn Rate: " + itemDespawnRate ); } - public int arrowDespawnRate; - private void arrowDespawnRate() + public static int arrowDespawnRate; + private static void arrowDespawnRate() { arrowDespawnRate = getInt( "arrow-despawn-rate", 1200 ); log( "Arrow Despawn Rate: " + arrowDespawnRate ); } - - public boolean antiXray; - public int engineMode; - public List hiddenBlocks; - public List replaceBlocks; - public AntiXray antiXrayInstance; - private void antiXray() + + public static boolean antiXray; + public static int engineMode; + public static List hiddenBlocks; + public static List replaceBlocks; + public static AntiXray antiXrayInstance; + private static void antiXray() { - antiXray = getBoolean( "anti-xray.enabled", true ); + antiXray = getBoolean( "anti-xray.enabled", false ); log( "Anti X-Ray: " + antiXray ); engineMode = getInt( "anti-xray.engine-mode", 1 ); log( "\tEngine Mode: " + engineMode ); - if ( SpigotConfig.version < 5 ) - { - set( "anti-xray.blocks", null ); - } - hiddenBlocks = getList( "anti-xray.hide-blocks", Arrays.asList( new Integer[] - { - 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130 - } ) ); + hiddenBlocks = getList( "anti-xray.hide-blocks", Arrays.asList(14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130) ); log( "\tHidden Blocks: " + hiddenBlocks ); - replaceBlocks = getList( "anti-xray.replace-blocks", Arrays.asList( new Integer[] - { - 1, 5 - } ) ); + replaceBlocks = getList( "anti-xray.replace-blocks", Arrays.asList(1, 5) ); log( "\tReplace Blocks: " + replaceBlocks ); - antiXrayInstance = new AntiXray( this ); + antiXrayInstance = new AntiXray( new SpigotWorldConfig() ); } - public boolean zombieAggressiveTowardsVillager; - private void zombieAggressiveTowardsVillager() + public static boolean zombieAggressiveTowardsVillager; + private static void zombieAggressiveTowardsVillager() { zombieAggressiveTowardsVillager = getBoolean( "zombie-aggressive-towards-villager", true ); log( "Zombie Aggressive Towards Villager: " + zombieAggressiveTowardsVillager ); } - public boolean nerfSpawnerMobs; - private void nerfSpawnerMobs() + public static boolean nerfSpawnerMobs; + private static void nerfSpawnerMobs() { nerfSpawnerMobs = getBoolean( "nerf-spawner-mobs", false ); log( "Nerfing mobs spawned from spawners: " + nerfSpawnerMobs ); } - public boolean enableZombiePigmenPortalSpawns; - private void enableZombiePigmenPortalSpawns() + public static boolean enableZombiePigmenPortalSpawns; + private static void enableZombiePigmenPortalSpawns() { enableZombiePigmenPortalSpawns = getBoolean( "enable-zombie-pigmen-portal-spawns", true ); log( "Allow Zombie Pigmen to spawn from portal blocks: " + enableZombiePigmenPortalSpawns ); } - public int maxBulkChunk; - private void bulkChunkCount() + public static int maxBulkChunk; + private static void bulkChunkCount() { maxBulkChunk = getInt( "max-bulk-chunks", 10 ); log( "Sending up to " + maxBulkChunk + " chunks per packet" ); } - public int maxCollisionsPerEntity; - private void maxEntityCollision() + public static int maxCollisionsPerEntity; + private static void maxEntityCollision() { maxCollisionsPerEntity = getInt( "max-entity-collisions", 8 ); log( "Max Entity Collisions: " + maxCollisionsPerEntity ); } - public int dragonDeathSoundRadius; - private void keepDragonDeathPerWorld() + public static int dragonDeathSoundRadius; + private static void keepDragonDeathPerWorld() { dragonDeathSoundRadius = getInt( "dragon-death-sound-radius", 0 ); } - public int witherSpawnSoundRadius; - private void witherSpawnSoundRadius() + public static int witherSpawnSoundRadius; + private static void witherSpawnSoundRadius() { witherSpawnSoundRadius = getInt( "wither-spawn-sound-radius", 0 ); } - public int villageSeed; - public int largeFeatureSeed; - private void initWorldGenSeeds() + public static int villageSeed; + public static int largeFeatureSeed; + private static void initWorldGenSeeds() { villageSeed = getInt( "seed-village", 10387312 ); largeFeatureSeed = getInt( "seed-feature", 14357617 ); log( "Custom Map Seeds: Village: " + villageSeed + " Feature: " + largeFeatureSeed ); } - public float walkExhaustion; - public float sprintExhaustion; - public float combatExhaustion; - public float regenExhaustion; - private void initHunger() + public static float walkExhaustion; + public static float sprintExhaustion; + public static float combatExhaustion; + public static float regenExhaustion; + private static void initHunger() { walkExhaustion = (float) getDouble( "hunger.walk-exhaustion", 0.2 ); sprintExhaustion = (float) getDouble( "hunger.sprint-exhaustion", 0.8 ); @@ -321,26 +299,22 @@ public class SpigotWorldConfig regenExhaustion = (float) getDouble( "hunger.regen-exhaustion", 3 ); } - public int currentPrimedTnt = 0; - public int maxTntTicksPerTick; - private void maxTntPerTick() { - if ( SpigotConfig.version < 7 ) - { - set( "max-tnt-per-tick", 100 ); - } + public static int currentPrimedTnt = 0; + public static int maxTntTicksPerTick; + private static void maxTntPerTick() { maxTntTicksPerTick = getInt( "max-tnt-per-tick", 100 ); log( "Max TNT Explosions: " + maxTntTicksPerTick ); } - public int hangingTickFrequency; - private void hangingTickFrequency() + public static int hangingTickFrequency; + private static void hangingTickFrequency() { hangingTickFrequency = getInt( "hanging-tick-frequency", 100 ); } - public int tileMaxTickTime; - public int entityMaxTickTime; - private void maxTickTimes() + public static int tileMaxTickTime; + public static int entityMaxTickTime; + private static void maxTickTimes() { tileMaxTickTime = getInt("max-tick-time.tile", 50); entityMaxTickTime = getInt("max-tick-time.entity", 50);